Passed
Push — master ( e37ecf...2614a9 )
by Simon
04:19
created

gradient_free_optimizers.stop_run.StopRun.update()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
import time
6
import numpy as np
7
8
9
def time_exceeded(start_time, max_time):
10
    run_time = time.time() - start_time
11
    return max_time and run_time > max_time
12
13
14
def score_exceeded(score_best, max_score):
15
    return max_score and score_best >= max_score
16
17
18
def no_change(score_new_list, early_stopping):
19
    if "n_iter_no_change" not in early_stopping:
20
        print(
21
            "Warning n_iter_no_change-parameter must be set in order for early stopping to work"
22
        )
23
        return False
24
25
    n_iter_no_change = early_stopping["n_iter_no_change"]
26
    if len(score_new_list) <= n_iter_no_change:
27
        return False
28
29
    scores_np = np.array(score_new_list)
30
31
    max_score = max(score_new_list)
32
    max_index = np.argmax(scores_np)
33
    length_pos = len(score_new_list)
34
35
    diff = length_pos - max_index
36
37
    if diff > n_iter_no_change:
38
        return True
39
40
    first_n = length_pos - n_iter_no_change
41
    scores_first_n = score_new_list[:first_n]
42
43
    max_first_n = max(scores_first_n)
44
45
    if "tol_abs" in early_stopping and early_stopping["tol_abs"] is not None:
46
        tol_abs = early_stopping["tol_abs"]
47
48
        if abs(max_first_n - max_score) < tol_abs:
49
            return True
50
51
    if "tol_rel" in early_stopping and early_stopping["tol_rel"] is not None:
52
        tol_rel = early_stopping["tol_rel"]
53
54
        percent_imp = ((max_score - max_first_n) / abs(max_first_n)) * 100
55
        if percent_imp < tol_rel:
56
            return True
57
58
59
class StopRun:
60
    def __init__(self, start_time, max_time, max_score, early_stopping):
61
        self.start_time = start_time
62
        self.max_time = max_time
63
        self.max_score = max_score
64
        self.early_stopping = early_stopping
65
66
    def update(self, score_best, score_new_list):
67
        self.score_best = score_best
68
        self.score_new_list = score_new_list
69
70
    def check(self):
71
        if self.max_time and time_exceeded(self.start_time, self.max_time):
72
            return True
73
        elif self.max_score and score_exceeded(self.score_best, self.max_score):
74
            return True
75
        elif self.early_stopping and no_change(
76
            self.score_new_list, self.early_stopping
77
        ):
78
            return True
79