talos 1.4__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- talos/__init__.py +38 -0
- talos/autom8/__init__.py +6 -0
- talos/autom8/automodel.py +126 -0
- talos/autom8/autoparams.py +272 -0
- talos/autom8/autopredict.py +108 -0
- talos/autom8/autoscan.py +56 -0
- talos/callbacks/__init__.py +5 -0
- talos/callbacks/experiment_log.py +86 -0
- talos/callbacks/power_draw.py +46 -0
- talos/commands/__init__.py +0 -0
- talos/commands/analyze.py +230 -0
- talos/commands/deploy.py +118 -0
- talos/commands/evaluate.py +99 -0
- talos/commands/predict.py +91 -0
- talos/commands/restore.py +56 -0
- talos/logging/__init__.py +0 -0
- talos/logging/logging_finish.py +8 -0
- talos/logging/logging_run.py +45 -0
- talos/logging/results.py +57 -0
- talos/metrics/__init__.py +0 -0
- talos/metrics/entropy.py +46 -0
- talos/metrics/keras_metrics.py +101 -0
- talos/model/__init__.py +3 -0
- talos/model/early_stopper.py +44 -0
- talos/model/hidden_layers.py +42 -0
- talos/model/ingest_model.py +10 -0
- talos/model/network_shape.py +65 -0
- talos/model/normalizers.py +27 -0
- talos/model/output_layer.py +22 -0
- talos/parameters/DistributeParamSpace.py +69 -0
- talos/parameters/ParamSpace.py +244 -0
- talos/parameters/__init__.py +0 -0
- talos/reducers/GamifyMap.py +91 -0
- talos/reducers/__init__.py +0 -0
- talos/reducers/correlation.py +54 -0
- talos/reducers/forrest.py +44 -0
- talos/reducers/gamify.py +25 -0
- talos/reducers/limit_by_metric.py +17 -0
- talos/reducers/local_strategy.py +14 -0
- talos/reducers/reduce_run.py +84 -0
- talos/reducers/reduce_utils.py +31 -0
- talos/reducers/sample_reducer.py +64 -0
- talos/reducers/trees.py +48 -0
- talos/scan/Scan.py +205 -0
- talos/scan/__init__.py +0 -0
- talos/scan/scan_addon.py +126 -0
- talos/scan/scan_finish.py +76 -0
- talos/scan/scan_prepare.py +63 -0
- talos/scan/scan_round.py +69 -0
- talos/scan/scan_run.py +37 -0
- talos/scan/scan_utils.py +29 -0
- talos/templates/__init__.py +4 -0
- talos/templates/datasets.py +187 -0
- talos/templates/models.py +154 -0
- talos/templates/params.py +80 -0
- talos/templates/pipelines.py +56 -0
- talos/utils/__init__.py +16 -0
- talos/utils/best_model.py +40 -0
- talos/utils/exceptions.py +18 -0
- talos/utils/generator.py +20 -0
- talos/utils/gpu_utils.py +54 -0
- talos/utils/load_model.py +23 -0
- talos/utils/power_draw_append.py +26 -0
- talos/utils/recover_best_model.py +94 -0
- talos/utils/rescale_meanzero.py +11 -0
- talos/utils/sequence_generator.py +21 -0
- talos/utils/test_utils.py +20 -0
- talos/utils/torch_history.py +29 -0
- talos/utils/validation_split.py +93 -0
- talos-1.4.dist-info/METADATA +172 -0
- talos-1.4.dist-info/RECORD +73 -0
- talos-1.4.dist-info/WHEEL +5 -0
- talos-1.4.dist-info/licenses/LICENSE +21 -0
talos/__init__.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
warnings.simplefilter('ignore')
|
|
3
|
+
|
|
4
|
+
# import commands
|
|
5
|
+
from .scan.Scan import Scan
|
|
6
|
+
from .commands.analyze import Analyze
|
|
7
|
+
from .commands.analyze import Analyze as Reporting
|
|
8
|
+
from .commands.predict import Predict
|
|
9
|
+
from .commands.deploy import Deploy
|
|
10
|
+
from .commands.evaluate import Evaluate
|
|
11
|
+
from .commands.restore import Restore
|
|
12
|
+
|
|
13
|
+
# import extras
|
|
14
|
+
from . import utils
|
|
15
|
+
from . import templates
|
|
16
|
+
from . import autom8
|
|
17
|
+
from . import callbacks
|
|
18
|
+
|
|
19
|
+
# the purpose of everything below is to keep the namespace completely clean
|
|
20
|
+
|
|
21
|
+
template_sub = [templates.datasets,
|
|
22
|
+
templates.models,
|
|
23
|
+
templates.params,
|
|
24
|
+
templates.pipelines]
|
|
25
|
+
|
|
26
|
+
keep_from_templates = ['iris', 'cervical_cancer', 'titanic', 'breast_cancer',
|
|
27
|
+
'icu_mortality', 'telco_churn', 'mnist']
|
|
28
|
+
|
|
29
|
+
for sub in template_sub:
|
|
30
|
+
for key in list(sub.__dict__):
|
|
31
|
+
if key.startswith('__') is False:
|
|
32
|
+
if key not in keep_from_templates:
|
|
33
|
+
delattr(sub, key)
|
|
34
|
+
|
|
35
|
+
del commands, scan, model, metrics, key
|
|
36
|
+
del sub, keep_from_templates, template_sub, warnings
|
|
37
|
+
|
|
38
|
+
__version__ = "1.4"
|
talos/autom8/__init__.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
class AutoModel:
|
|
2
|
+
|
|
3
|
+
def __init__(self, task, experiment_name, metric=None):
|
|
4
|
+
|
|
5
|
+
'''
|
|
6
|
+
|
|
7
|
+
Creates an input model for Scan(). Optimized for being used together
|
|
8
|
+
with Params(). For example:
|
|
9
|
+
|
|
10
|
+
p = talos.AutoParams().params
|
|
11
|
+
model = talos.AutoModel(task='binary').model
|
|
12
|
+
|
|
13
|
+
talos.Scan(x, y, p, model)
|
|
14
|
+
|
|
15
|
+
NOTE: the parameter space from Params() is very large, so use limits
|
|
16
|
+
in or reducers in Scan() accordingly.
|
|
17
|
+
|
|
18
|
+
task : string or None
|
|
19
|
+
If 'continuous' then mae is used for metric, if 'binary',
|
|
20
|
+
'multiclass', or 'multilabel', f1score is used. Accuracy is always
|
|
21
|
+
used.
|
|
22
|
+
experiment_name | str | Must be same as in `Scan()`
|
|
23
|
+
metric : None or list
|
|
24
|
+
You can also input a list with one or more custom metrics or names
|
|
25
|
+
of Keras or Talos metrics.
|
|
26
|
+
'''
|
|
27
|
+
|
|
28
|
+
from talos.callbacks.experiment_log import ExperimentLog
|
|
29
|
+
|
|
30
|
+
self.task = task
|
|
31
|
+
self.experiment_name = experiment_name
|
|
32
|
+
self.metric = metric
|
|
33
|
+
|
|
34
|
+
if self.task is not None:
|
|
35
|
+
self.metrics = self._set_metric()
|
|
36
|
+
elif self.metric is not None and isinstance(self.metric, list):
|
|
37
|
+
self.metrics = self.metric + ['acc']
|
|
38
|
+
else:
|
|
39
|
+
print("Either pick task or provide list as input for metric.")
|
|
40
|
+
|
|
41
|
+
# create the model
|
|
42
|
+
self.model = self._create_input_model
|
|
43
|
+
self.callback = ExperimentLog
|
|
44
|
+
|
|
45
|
+
def _set_metric(self):
|
|
46
|
+
|
|
47
|
+
"""Sets the metric for the model based on the experiment type
|
|
48
|
+
or a list of metrics from user."""
|
|
49
|
+
|
|
50
|
+
import talos as ta
|
|
51
|
+
|
|
52
|
+
if self.task in ['binary', 'multiclass', 'multilabel']:
|
|
53
|
+
return [ta.utils.metrics.f1score, 'acc']
|
|
54
|
+
elif self.task == 'continuous':
|
|
55
|
+
return [ta.utils.metrics.mae, 'acc']
|
|
56
|
+
|
|
57
|
+
def _create_input_model(self, x_train, y_train, x_val, y_val, params):
|
|
58
|
+
|
|
59
|
+
import wrangle as wr
|
|
60
|
+
|
|
61
|
+
from tensorflow.keras.models import Sequential
|
|
62
|
+
from tensorflow.keras.layers import Dropout, Flatten
|
|
63
|
+
from tensorflow.keras.layers import LSTM, Conv1D, SimpleRNN, Dense, Bidirectional
|
|
64
|
+
|
|
65
|
+
model = Sequential()
|
|
66
|
+
|
|
67
|
+
if params['network'] != 'dense':
|
|
68
|
+
x_train = wr.array_reshape_conv1d(x_train)
|
|
69
|
+
x_val = wr.array_reshape_conv1d(x_val)
|
|
70
|
+
|
|
71
|
+
if params['network'] == 'conv1d':
|
|
72
|
+
model.add(Conv1D(params['first_neuron'], x_train.shape[1]))
|
|
73
|
+
model.add(Flatten())
|
|
74
|
+
|
|
75
|
+
elif params['network'] == 'lstm':
|
|
76
|
+
model.add(LSTM(params['first_neuron']))
|
|
77
|
+
|
|
78
|
+
if params['network'] == 'bidirectional_lstm':
|
|
79
|
+
model.add(Bidirectional(LSTM(params['first_neuron'])))
|
|
80
|
+
|
|
81
|
+
elif params['network'] == 'simplernn':
|
|
82
|
+
model.add(SimpleRNN(params['first_neuron']))
|
|
83
|
+
|
|
84
|
+
elif params['network'] == 'dense':
|
|
85
|
+
model.add(Dense(params['first_neuron'],
|
|
86
|
+
input_dim=x_train.shape[1],
|
|
87
|
+
activation='relu',
|
|
88
|
+
kernel_initializer=params['kernel_initializer']))
|
|
89
|
+
|
|
90
|
+
model.add(Dropout(params['dropout']))
|
|
91
|
+
|
|
92
|
+
# add hidden layers to the model
|
|
93
|
+
from talos.model.hidden_layers import hidden_layers
|
|
94
|
+
hidden_layers(model, params, 1)
|
|
95
|
+
|
|
96
|
+
# get the right activation and last_neuron based on task
|
|
97
|
+
from talos.model.output_layer import output_layer
|
|
98
|
+
activation, last_neuron = output_layer(self.task,
|
|
99
|
+
params['last_activation'],
|
|
100
|
+
y_train,
|
|
101
|
+
y_val)
|
|
102
|
+
|
|
103
|
+
model.add(Dense(last_neuron,
|
|
104
|
+
activation=activation,
|
|
105
|
+
kernel_initializer=params['kernel_initializer']))
|
|
106
|
+
|
|
107
|
+
# bundle the optimizer with learning rate changes
|
|
108
|
+
from talos.model.normalizers import lr_normalizer
|
|
109
|
+
optimizer = params['optimizer'](lr=lr_normalizer(params['lr'],
|
|
110
|
+
params['optimizer']))
|
|
111
|
+
|
|
112
|
+
# compile the model
|
|
113
|
+
model.compile(optimizer=optimizer,
|
|
114
|
+
loss=params['losses'],
|
|
115
|
+
metrics=self.metrics)
|
|
116
|
+
|
|
117
|
+
# fit the model
|
|
118
|
+
out = model.fit(x_train, y_train,
|
|
119
|
+
batch_size=params['batch_size'],
|
|
120
|
+
epochs=params['epochs'],
|
|
121
|
+
verbose=0,
|
|
122
|
+
callbacks=[self.callback(self.experiment_name, params)],
|
|
123
|
+
validation_data=(x_val, y_val))
|
|
124
|
+
|
|
125
|
+
# pass the output to Talos
|
|
126
|
+
return out, model
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from tensorflow.keras.optimizers.legacy import Adam, Adagrad, SGD
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
loss = {'binary': ['binary_crossentropy', 'LogCosh'],
|
|
6
|
+
'multi_class': ['sparse_categorical_crossentropy'],
|
|
7
|
+
'multi_label': ['categorical_crossentropy'],
|
|
8
|
+
'continuous': ['mae']}
|
|
9
|
+
|
|
10
|
+
last_activation = {'binary': ['sigmoid'],
|
|
11
|
+
'multi_class': ['softmax'],
|
|
12
|
+
'multi_label': ['softmax'],
|
|
13
|
+
'continuous': [None]}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AutoParams:
|
|
17
|
+
|
|
18
|
+
def __init__(self,
|
|
19
|
+
params=None,
|
|
20
|
+
task='binary',
|
|
21
|
+
replace=True,
|
|
22
|
+
auto=True,
|
|
23
|
+
network=True,
|
|
24
|
+
resample_params=4):
|
|
25
|
+
|
|
26
|
+
'''A facility for generating or appending params dictionary.
|
|
27
|
+
|
|
28
|
+
params : dict or None
|
|
29
|
+
task : str
|
|
30
|
+
'binary', 'multi_class', 'multi_label', or 'continuous'
|
|
31
|
+
replace : bool
|
|
32
|
+
Replace current dictionary entries with new ones.
|
|
33
|
+
auto : bool
|
|
34
|
+
Automatically generate or append params dictionary with
|
|
35
|
+
all available parameters.
|
|
36
|
+
network : bool
|
|
37
|
+
Adds several network architectures as parameters. This is to be
|
|
38
|
+
used as an input together with KerasModel(). If False then only
|
|
39
|
+
'dense' will be added.
|
|
40
|
+
resample_params | int or False | The number of values per parameter
|
|
41
|
+
'''
|
|
42
|
+
|
|
43
|
+
self._task = task
|
|
44
|
+
self._replace = replace
|
|
45
|
+
self._network = network
|
|
46
|
+
|
|
47
|
+
if params is None:
|
|
48
|
+
self.params = {}
|
|
49
|
+
else:
|
|
50
|
+
self.params = params
|
|
51
|
+
if auto:
|
|
52
|
+
self._automated()
|
|
53
|
+
|
|
54
|
+
if resample_params is not False:
|
|
55
|
+
self.resample_params(resample_params)
|
|
56
|
+
|
|
57
|
+
def _automated(self, shapes='fixed'):
|
|
58
|
+
|
|
59
|
+
'''Automatically generate a comprehensive
|
|
60
|
+
parameter dict to be used in Scan()
|
|
61
|
+
|
|
62
|
+
shapes : string
|
|
63
|
+
Either 'fixed' or 'sloped'
|
|
64
|
+
|
|
65
|
+
'''
|
|
66
|
+
|
|
67
|
+
if shapes == 'fixed':
|
|
68
|
+
self.shapes()
|
|
69
|
+
else:
|
|
70
|
+
self.shapes_slope()
|
|
71
|
+
self.layers()
|
|
72
|
+
self.dropout()
|
|
73
|
+
self.optimizers()
|
|
74
|
+
self.activations()
|
|
75
|
+
self.neurons()
|
|
76
|
+
self.losses()
|
|
77
|
+
self.batch_size()
|
|
78
|
+
self.epochs()
|
|
79
|
+
self.kernel_initializers()
|
|
80
|
+
self.lr()
|
|
81
|
+
if self._network:
|
|
82
|
+
self.networks()
|
|
83
|
+
else:
|
|
84
|
+
self.params['network'] = ['dense']
|
|
85
|
+
self.last_activations()
|
|
86
|
+
|
|
87
|
+
def shapes(self, shapes='auto'):
|
|
88
|
+
|
|
89
|
+
'''Uses triangle, funnel, and brick shapes.'''
|
|
90
|
+
|
|
91
|
+
if shapes == 'auto':
|
|
92
|
+
self._append_params('shapes', ['triangle', 'funnel', 'brick'])
|
|
93
|
+
else:
|
|
94
|
+
self._append_params('shapes', shapes)
|
|
95
|
+
|
|
96
|
+
def shapes_slope(self, min_slope=0, max_slope=.6, steps=.1):
|
|
97
|
+
|
|
98
|
+
'''Uses a single decimal float for values below 0.5 to
|
|
99
|
+
reduce the width of the following layer.'''
|
|
100
|
+
|
|
101
|
+
self._append_params('shapes', np.arange(min_slope,
|
|
102
|
+
max_slope,
|
|
103
|
+
steps).tolist())
|
|
104
|
+
|
|
105
|
+
def layers(self, min_layers=0, max_layers=6, steps=1):
|
|
106
|
+
|
|
107
|
+
self._append_params('hidden_layers',
|
|
108
|
+
list(range(min_layers, max_layers, steps)))
|
|
109
|
+
|
|
110
|
+
def dropout(self, min_dropout=0, max_dropout=.85, steps=0.1):
|
|
111
|
+
|
|
112
|
+
self._append_params('dropout',
|
|
113
|
+
np.round(np.arange(min_dropout,
|
|
114
|
+
max_dropout,
|
|
115
|
+
steps), 2).tolist())
|
|
116
|
+
|
|
117
|
+
def optimizers(self, optimizers='auto'):
|
|
118
|
+
|
|
119
|
+
'''If `optimizers='auto'` then optimizers will be picked based on
|
|
120
|
+
automatically. Otherwise input a list with one or
|
|
121
|
+
more optimizers will be used.
|
|
122
|
+
'''
|
|
123
|
+
|
|
124
|
+
if optimizers == 'auto':
|
|
125
|
+
self._append_params('optimizer', [Adam, Adagrad, SGD])
|
|
126
|
+
else:
|
|
127
|
+
self._append_params('optimizer', optimizers)
|
|
128
|
+
|
|
129
|
+
def activations(self, activations='auto'):
|
|
130
|
+
|
|
131
|
+
'''If `activations='auto'` then activations will be picked based on
|
|
132
|
+
automatically. Otherwise input a list with one or
|
|
133
|
+
more activations will be used.
|
|
134
|
+
'''
|
|
135
|
+
|
|
136
|
+
if activations == 'auto':
|
|
137
|
+
activations = ['relu', 'elu']
|
|
138
|
+
|
|
139
|
+
self._append_params('activation', activations)
|
|
140
|
+
|
|
141
|
+
def losses(self, losses='auto'):
|
|
142
|
+
|
|
143
|
+
'''If `losses='auto'` then losses will be picked based on
|
|
144
|
+
`AutoParam()` argument `task`. Otherwise input a list with one or
|
|
145
|
+
more losses will be used.
|
|
146
|
+
'''
|
|
147
|
+
|
|
148
|
+
if losses == 'auto':
|
|
149
|
+
self._append_params('losses', loss[self._task])
|
|
150
|
+
else:
|
|
151
|
+
self._append_params('losses', losses)
|
|
152
|
+
|
|
153
|
+
def neurons(self, min_neuron=8, max_neuron=None, steps=None):
|
|
154
|
+
|
|
155
|
+
'''`max` and `steps` has to be either `None` or
|
|
156
|
+
integer value at the same time.'''
|
|
157
|
+
|
|
158
|
+
if max_neuron is None and steps is None:
|
|
159
|
+
values = [int(np.exp2(i)) for i in range(3, 11)]
|
|
160
|
+
else:
|
|
161
|
+
values = list(range(min_neuron, max_neuron, steps))
|
|
162
|
+
|
|
163
|
+
self._append_params('first_neuron', values)
|
|
164
|
+
|
|
165
|
+
def batch_size(self, min_size=8, max_size=None, steps=None):
|
|
166
|
+
|
|
167
|
+
'''`max_size` and `steps` has to be either `None` or
|
|
168
|
+
integer value at the same time.'''
|
|
169
|
+
|
|
170
|
+
if max_size is None and steps is None:
|
|
171
|
+
values = [int(np.exp2(i / 2)) for i in range(3, 15)]
|
|
172
|
+
else:
|
|
173
|
+
values = list(range(min_size, max_size, steps))
|
|
174
|
+
|
|
175
|
+
self._append_params('batch_size', values)
|
|
176
|
+
|
|
177
|
+
def epochs(self, min_epochs=50, max_epochs=None, steps=None):
|
|
178
|
+
|
|
179
|
+
'''`max_epochs` and `steps` has to be either `None` or
|
|
180
|
+
integer value at the same time.'''
|
|
181
|
+
|
|
182
|
+
if max_epochs is None and steps is None:
|
|
183
|
+
values = [int(np.exp2(i / 2)) + 50 for i in range(3, 15)]
|
|
184
|
+
else:
|
|
185
|
+
values = list(range(min_epochs, max_epochs, steps))
|
|
186
|
+
|
|
187
|
+
self._append_params('epochs', values)
|
|
188
|
+
|
|
189
|
+
def kernel_initializers(self, kernel_inits='auto'):
|
|
190
|
+
|
|
191
|
+
'''
|
|
192
|
+
kernel_inits | list | one or more kernel initializers
|
|
193
|
+
'''
|
|
194
|
+
|
|
195
|
+
if kernel_inits == 'auto':
|
|
196
|
+
self._append_params('kernel_initializer',
|
|
197
|
+
['uniform', 'normal', 'he_normal',
|
|
198
|
+
'he_uniform', 'lecun_normal',
|
|
199
|
+
'glorot_uniform', 'glorot_normal',
|
|
200
|
+
'random_uniform', 'random_normal'])
|
|
201
|
+
else:
|
|
202
|
+
self._append_params('kernel_initializer', kernel_inits)
|
|
203
|
+
|
|
204
|
+
def lr(self, learning_rates='auto'):
|
|
205
|
+
|
|
206
|
+
'''If `learning_rates='auto'` then a very wide range of learning rates
|
|
207
|
+
will be added. Otherwise a list with one or more learning rates
|
|
208
|
+
is used.
|
|
209
|
+
|
|
210
|
+
NOTE: talos.utils.lr_normalizer should be used if more than one optimizer
|
|
211
|
+
is used in the experiment
|
|
212
|
+
'''
|
|
213
|
+
|
|
214
|
+
if learning_rates == 'auto':
|
|
215
|
+
|
|
216
|
+
a = np.round(np.arange(0.01, 0.2, 0.02), 3).tolist()
|
|
217
|
+
b = np.round(np.arange(0, 1, 0.2), 2).tolist()
|
|
218
|
+
c = list(range(0, 11))
|
|
219
|
+
|
|
220
|
+
self._append_params('lr', a + b + c)
|
|
221
|
+
|
|
222
|
+
else:
|
|
223
|
+
|
|
224
|
+
self._append_params('lr', learning_rates)
|
|
225
|
+
|
|
226
|
+
def networks(self, networks='auto'):
|
|
227
|
+
|
|
228
|
+
'''If `network='auto'` then dense, simplernn, lstm, conv1d, and
|
|
229
|
+
bidirectional_lstm are added. Otherwise a list with one or more
|
|
230
|
+
network architectures is used.
|
|
231
|
+
'''
|
|
232
|
+
|
|
233
|
+
if networks == 'auto':
|
|
234
|
+
self._append_params('network', ['dense',
|
|
235
|
+
'simplernn',
|
|
236
|
+
'lstm',
|
|
237
|
+
'bidirectional_lstm',
|
|
238
|
+
'conv1d'])
|
|
239
|
+
else:
|
|
240
|
+
self._append_params('network', networks)
|
|
241
|
+
|
|
242
|
+
def last_activations(self, last_activations='auto'):
|
|
243
|
+
|
|
244
|
+
'''If `last_activations='auto'` then activations will be picked
|
|
245
|
+
automatically based on `AutoParams` property `task`.
|
|
246
|
+
Otherwise input a list with one or more activations will be used.
|
|
247
|
+
'''
|
|
248
|
+
|
|
249
|
+
if last_activations == 'auto':
|
|
250
|
+
self._append_params('last_activation', last_activation[self._task])
|
|
251
|
+
else:
|
|
252
|
+
self._append_params('last_activation', last_activations)
|
|
253
|
+
|
|
254
|
+
def resample_params(self, n):
|
|
255
|
+
|
|
256
|
+
'''Resamples params dictionary so that `n` values are present for each
|
|
257
|
+
parameter.'''
|
|
258
|
+
|
|
259
|
+
from wrangle import dic_resample_values
|
|
260
|
+
|
|
261
|
+
self.params = dic_resample_values(self.params, n)
|
|
262
|
+
|
|
263
|
+
def _append_params(self, label, values):
|
|
264
|
+
|
|
265
|
+
if self._replace is False:
|
|
266
|
+
try:
|
|
267
|
+
self.params[label]
|
|
268
|
+
except KeyError:
|
|
269
|
+
self.params[label] = values
|
|
270
|
+
|
|
271
|
+
else:
|
|
272
|
+
self.params[label] = values
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
def AutoPredict(scan_object,
|
|
2
|
+
x_val,
|
|
3
|
+
y_val,
|
|
4
|
+
x_pred,
|
|
5
|
+
task,
|
|
6
|
+
metric='val_acc',
|
|
7
|
+
n_models=10,
|
|
8
|
+
folds=5,
|
|
9
|
+
shuffle=True,
|
|
10
|
+
asc=False):
|
|
11
|
+
|
|
12
|
+
'''Automatically handles the process of finding the best models from a
|
|
13
|
+
completed `Scan()` experiment, evaluates those models, and uses the winner
|
|
14
|
+
to make predictions on input data.
|
|
15
|
+
|
|
16
|
+
NOTE: the input data must be in same format as 'x' that was
|
|
17
|
+
used in `Scan()`.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
scan_object : Scan() object
|
|
22
|
+
A Scan() process needs to be completed first, and then the resulting
|
|
23
|
+
object can be used as input here.
|
|
24
|
+
x_val : ndarray or list of ndarray
|
|
25
|
+
Data to be used for 'x' in evaluation. Note that should be in the same
|
|
26
|
+
format as the data which was used in the Scan() but not the same data.
|
|
27
|
+
y_val : ndarray or list of ndarray
|
|
28
|
+
Data to be used for 'y' in evaluation. Note that should be in the same
|
|
29
|
+
format as the data which was used in the Scan() but not the same data.
|
|
30
|
+
y_pred : ndarray or list of ndarray
|
|
31
|
+
Input data to be used for the actual predictions in evaluation. Note
|
|
32
|
+
it should be in the same format as the data which was used in the
|
|
33
|
+
Scan() but not the same data.
|
|
34
|
+
task : string
|
|
35
|
+
'binary', 'multi_class', 'multi_label', or 'continuous'.
|
|
36
|
+
metric : str
|
|
37
|
+
The metric to be used for deciding which models are promising.
|
|
38
|
+
Basically the 'n' argument and 'metric' argument are combined to pick
|
|
39
|
+
'n' best performing models based on 'metric'.
|
|
40
|
+
n_models : str
|
|
41
|
+
Number of promising models to be included in the evaluation process.
|
|
42
|
+
Time increase linearly with number of models.
|
|
43
|
+
folds : int
|
|
44
|
+
Number of folds to be used in cross-validation.
|
|
45
|
+
shuffle : bool
|
|
46
|
+
If the data should be shuffled before cross-validation.
|
|
47
|
+
average : str
|
|
48
|
+
This parameter is required for multiclass/multilabel targets. If None,
|
|
49
|
+
the scores for each class are returned. Otherwise, this determines
|
|
50
|
+
the type of averaging performed on the data:
|
|
51
|
+
|
|
52
|
+
'binary':
|
|
53
|
+
Only report results for the class specified by pos_label.
|
|
54
|
+
This is applicable only if targets (y_{true,pred}) are binary.
|
|
55
|
+
|
|
56
|
+
'micro':
|
|
57
|
+
Calculate metrics globally by counting the total true positives,
|
|
58
|
+
false negatives and false positives.
|
|
59
|
+
|
|
60
|
+
'macro':
|
|
61
|
+
Calculate metrics for each label, and find their unweighted mean.
|
|
62
|
+
This does not take label imbalance into account.
|
|
63
|
+
|
|
64
|
+
'weighted':
|
|
65
|
+
Calculate metrics for each label, and find their average weighted
|
|
66
|
+
by support (the number of true instances for each label). This alters
|
|
67
|
+
'macro' to account for label imbalance; it can result in an F-score
|
|
68
|
+
that is not between precision and recall.
|
|
69
|
+
|
|
70
|
+
'samples':
|
|
71
|
+
Calculate metrics for each instance, and find their average
|
|
72
|
+
(only meaningful for multilabel classification where this differs
|
|
73
|
+
from accuracy_score).
|
|
74
|
+
asc : bool
|
|
75
|
+
This needs to be True for evaluation metrics that need to be minimized,
|
|
76
|
+
and False when a metric needs to be maximized.
|
|
77
|
+
|
|
78
|
+
'''
|
|
79
|
+
|
|
80
|
+
import numpy as np
|
|
81
|
+
|
|
82
|
+
# evaluate and add the evaluation scores
|
|
83
|
+
scan_object.evaluate_models(x_val,
|
|
84
|
+
y_val,
|
|
85
|
+
n_models=n_models,
|
|
86
|
+
task=task,
|
|
87
|
+
metric=metric,
|
|
88
|
+
folds=folds,
|
|
89
|
+
shuffle=shuffle,
|
|
90
|
+
asc=False)
|
|
91
|
+
|
|
92
|
+
# get the best model based on evaluated score
|
|
93
|
+
scan_object.preds_model = scan_object.best_model('eval_f1score_mean')
|
|
94
|
+
|
|
95
|
+
# make predictions with the model
|
|
96
|
+
scan_object.preds_probabilities = scan_object.preds_model.predict(x_pred)
|
|
97
|
+
|
|
98
|
+
# make (class) predictiosn with the model
|
|
99
|
+
preds = scan_object.preds_model.predict(x_pred)
|
|
100
|
+
scan_object.preds_classes = np.argmax(preds, axis=1)
|
|
101
|
+
|
|
102
|
+
# get the hyperparameter for the model
|
|
103
|
+
scan_object.preds_parameters = scan_object.data.sort_values('eval_f1score_mean',
|
|
104
|
+
ascending=False).iloc[0]
|
|
105
|
+
|
|
106
|
+
print(">> Added model, probabilities, classes, and parameters to scan_object")
|
|
107
|
+
|
|
108
|
+
return scan_object
|
talos/autom8/autoscan.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
class AutoScan:
|
|
2
|
+
|
|
3
|
+
def __init__(self,
|
|
4
|
+
task,
|
|
5
|
+
experiment_name,
|
|
6
|
+
max_param_values=None):
|
|
7
|
+
|
|
8
|
+
'''Configure the `AutoScan()` experiment and then use
|
|
9
|
+
the property `start` in the returned class object to start
|
|
10
|
+
the actual experiment.
|
|
11
|
+
|
|
12
|
+
`task` | str | 'binary', 'multi_class', 'multi_label', or 'continuous'
|
|
13
|
+
`max_param_values` | int | Number of parameter values to be included.
|
|
14
|
+
Note, this will only work when `params` is
|
|
15
|
+
not passed as kwargs in `AutoScan.start`.
|
|
16
|
+
'''
|
|
17
|
+
|
|
18
|
+
self.task = task
|
|
19
|
+
self.max_param_values = max_param_values
|
|
20
|
+
self.experiment_name = experiment_name
|
|
21
|
+
|
|
22
|
+
def start(self, x, y, **kwargs):
|
|
23
|
+
|
|
24
|
+
'''Start the scan. Note that you can use `Scan()` arguments as you
|
|
25
|
+
would otherwise directly interacting with `Scan()`.
|
|
26
|
+
|
|
27
|
+
`x` | array or list of arrays | prediction features
|
|
28
|
+
`y` | array or list of arrays | prediction outcome variable
|
|
29
|
+
`kwargs` | arguments | any `Scan()` argument can be passed here
|
|
30
|
+
|
|
31
|
+
'''
|
|
32
|
+
|
|
33
|
+
import talos
|
|
34
|
+
|
|
35
|
+
m = talos.autom8.AutoModel(self.task, self.experiment_name).model
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
kwargs['params']
|
|
39
|
+
scan_object = talos.Scan(x, y,
|
|
40
|
+
model=m,
|
|
41
|
+
experiment_name=self.experiment_name,
|
|
42
|
+
**kwargs)
|
|
43
|
+
except KeyError:
|
|
44
|
+
p = talos.autom8.AutoParams(task=self.task)
|
|
45
|
+
|
|
46
|
+
if self.max_param_values is not None:
|
|
47
|
+
p.resample_params(self.max_param_values)
|
|
48
|
+
params = p.params
|
|
49
|
+
scan_object = talos.Scan(x=x,
|
|
50
|
+
y=y,
|
|
51
|
+
params=params,
|
|
52
|
+
model=m,
|
|
53
|
+
experiment_name=self.experiment_name,
|
|
54
|
+
**kwargs)
|
|
55
|
+
|
|
56
|
+
return scan_object
|