pyerualjetwork 5.1__py3-none-any.whl → 5.5__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.
- pyerualjetwork/__init__.py +15 -14
- pyerualjetwork/cpu/__init__.py +24 -0
- pyerualjetwork/{activation_functions_cpu.py → cpu/activation_functions.py} +40 -4
- pyerualjetwork/{data_operations_cpu.py → cpu/data_ops.py} +17 -19
- pyerualjetwork/{metrics_cpu.py → cpu/metrics.py} +3 -1
- pyerualjetwork/{visualizations_cpu.py → cpu/visualizations.py} +96 -139
- pyerualjetwork/cuda/__init__.py +24 -0
- pyerualjetwork/{activation_functions_cuda.py → cuda/activation_functions.py} +54 -5
- pyerualjetwork/{data_operations_cuda.py → cuda/data_ops.py} +16 -16
- pyerualjetwork/{metrics_cuda.py → cuda/metrics.py} +1 -1
- pyerualjetwork/{visualizations_cuda.py → cuda/visualizations.py} +8 -244
- pyerualjetwork/{ene_cpu.py → ene.py} +29 -95
- pyerualjetwork/fitness_functions.py +0 -1
- pyerualjetwork/help.py +5 -5
- pyerualjetwork/issue_solver.py +39 -11
- pyerualjetwork/{memory_operations.py → memory_ops.py} +1 -1
- pyerualjetwork/model_ops.py +734 -0
- pyerualjetwork/{neu_cpu.py → nn.py} +199 -91
- pyerualjetwork/{model_operations_cpu.py → old_cpu_model_ops.py} +62 -59
- pyerualjetwork/{model_operations_cuda.py → old_cuda_model_ops.py} +99 -86
- {pyerualjetwork-5.1.dist-info → pyerualjetwork-5.5.dist-info}/METADATA +16 -18
- pyerualjetwork-5.5.dist-info/RECORD +27 -0
- pyerualjetwork/ene_cuda.py +0 -962
- pyerualjetwork/neu_cuda.py +0 -588
- pyerualjetwork-5.1.dist-info/RECORD +0 -26
- /pyerualjetwork/{loss_functions_cpu.py → cpu/loss_functions.py} +0 -0
- /pyerualjetwork/{loss_functions_cuda.py → cuda/loss_functions.py} +0 -0
- {pyerualjetwork-5.1.dist-info → pyerualjetwork-5.5.dist-info}/WHEEL +0 -0
- {pyerualjetwork-5.1.dist-info → pyerualjetwork-5.5.dist-info}/top_level.txt +0 -0
@@ -2,9 +2,9 @@
|
|
2
2
|
"""
|
3
3
|
|
4
4
|
|
5
|
-
|
5
|
+
NN (Neural Networks)
|
6
6
|
============================
|
7
|
-
This module hosts functions for training and evaluating artificial neural networks
|
7
|
+
This module hosts functions for training and evaluating artificial neural networks for labeled classification tasks.
|
8
8
|
|
9
9
|
Currently, 3 types of models can be trained:
|
10
10
|
|
@@ -40,7 +40,7 @@ Examples: https://github.com/HCB06/PyerualJetwork/tree/main/Welcome_to_PyerualJe
|
|
40
40
|
|
41
41
|
PyerualJetwork document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PyerualJetwork/PYERUALJETWORK_USER_MANUEL_AND_LEGAL_INFORMATION(EN).pdf
|
42
42
|
|
43
|
-
-
|
43
|
+
- Creator: Hasan Can Beydili
|
44
44
|
- YouTube: https://www.youtube.com/@HasanCanBeydili
|
45
45
|
- Linkedin: https://www.linkedin.com/in/hasan-can-beydili-77a1b9270/
|
46
46
|
- Instagram: https://www.instagram.com/canbeydilj
|
@@ -48,24 +48,16 @@ PyerualJetwork document: https://github.com/HCB06/PyerualJetwork/blob/main/Welco
|
|
48
48
|
"""
|
49
49
|
|
50
50
|
import numpy as np
|
51
|
+
import cupy as cp
|
51
52
|
import copy
|
52
53
|
import random
|
53
54
|
|
54
55
|
### LIBRARY IMPORTS ###
|
55
56
|
from .ui import loading_bars, initialize_loading_bar
|
56
|
-
from .
|
57
|
-
from .
|
58
|
-
from .
|
59
|
-
from .memory_operations import optimize_labels
|
60
|
-
from .loss_functions_cpu import categorical_crossentropy, binary_crossentropy
|
57
|
+
from .cpu.activation_functions import all_activations
|
58
|
+
from .model_ops import get_acc, get_preds_softmax, get_preds
|
59
|
+
from .memory_ops import optimize_labels, transfer_to_gpu
|
61
60
|
from .fitness_functions import wals
|
62
|
-
from .visualizations_cpu import (
|
63
|
-
draw_neural_web,
|
64
|
-
display_visualizations_for_learner,
|
65
|
-
update_history_plots_for_learner,
|
66
|
-
initialize_visualization_for_learner,
|
67
|
-
update_neuron_history_for_learner
|
68
|
-
)
|
69
61
|
|
70
62
|
### GLOBAL VARIABLES ###
|
71
63
|
bar_format_normal = loading_bars()[0]
|
@@ -79,48 +71,61 @@ def plan_fit(
|
|
79
71
|
activations=['linear'],
|
80
72
|
W=None,
|
81
73
|
auto_normalization=False,
|
74
|
+
cuda=False,
|
82
75
|
dtype=np.float32
|
83
76
|
):
|
84
77
|
"""
|
85
78
|
Creates a PLAN model to fitting data.
|
86
79
|
|
87
80
|
Args:
|
88
|
-
x_train (aray-like[num]): List or numarray of input data.
|
81
|
+
x_train (aray-like[num or cup]): List or numarray of input data.
|
89
82
|
|
90
|
-
y_train (aray-like[num]): List or numarray of target labels. (one hot encoded)
|
83
|
+
y_train (aray-like[num or cup]): List or numarray of target labels. (one hot encoded)
|
91
84
|
|
92
85
|
activations (list): For deeper PLAN networks, activation function parameters. For more information please run this code: neu.activations_list() default: [None] (optional)
|
93
86
|
|
94
|
-
W (numpy.ndarray): If you want to re-continue or update model
|
87
|
+
W (numpy.ndarray or cupy.ndarray): If you want to re-continue or update model
|
95
88
|
|
96
89
|
auto_normalization (bool, optional): Normalization may solves overflow problem. Default: False
|
97
90
|
|
91
|
+
cuda (bool, optional): CUDA GPU acceleration ? Default = False.
|
92
|
+
|
98
93
|
dtype (numpy.dtype): Data type for the arrays. np.float32 by default. Example: np.float64 or np.float16.
|
99
94
|
|
100
95
|
Returns:
|
101
96
|
numpyarray: (Weight matrix).
|
102
97
|
"""
|
98
|
+
|
99
|
+
from .cpu.data_ops import normalization
|
100
|
+
if not cuda:
|
101
|
+
from cpu.activation_functions import apply_activation
|
102
|
+
array_type = np
|
103
103
|
|
104
|
+
else:
|
105
|
+
from .cuda.activation_functions import apply_activation
|
106
|
+
array_type = cp
|
107
|
+
|
108
|
+
|
104
109
|
# Pre-check
|
105
110
|
|
106
111
|
if len(x_train) != len(y_train): raise ValueError("x_train and y_train must have the same length.")
|
107
112
|
|
108
|
-
weight =
|
113
|
+
weight = array_type.zeros((len(y_train[0]), len(x_train[0].ravel()))).astype(dtype, copy=False) if W is None else W
|
109
114
|
|
110
115
|
if auto_normalization is True: x_train = normalization(apply_activation(x_train, activations))
|
111
116
|
elif auto_normalization is False: x_train = apply_activation(x_train, activations)
|
112
117
|
else: raise ValueError('normalization parameter only be True or False')
|
113
|
-
|
114
|
-
weight += y_train.T @ x_train
|
115
118
|
|
116
|
-
|
119
|
+
weight += y_train.T @ x_train if not cuda else cp.array(y_train).T @ cp.array(x_train)
|
117
120
|
|
121
|
+
return normalization(weight.get() if cuda else weight,dtype=dtype)
|
118
122
|
|
119
|
-
|
123
|
+
|
124
|
+
def learn(x_train, y_train, optimizer, template_model, gen, pop_size, fit_start=True, batch_size=1,
|
120
125
|
weight_evolve=True, neural_web_history=False, show_current_activations=False, auto_normalization=False,
|
121
126
|
neurons_history=False, early_stop=False, show_history=False, target_loss=None,
|
122
127
|
interval=33.33, target_acc=None, loss='categorical_crossentropy', acc_impact=0.9, loss_impact=0.1,
|
123
|
-
start_this_act=None, start_this_W=None, neurons=[], activation_functions=[], dtype=np.float32):
|
128
|
+
start_this_act=None, start_this_W=None, neurons=[], activation_functions=[], decision_boundary_history=False, cuda=False, dtype=np.float32):
|
124
129
|
"""
|
125
130
|
Optimizes the activation functions for a neural network by leveraging train data to find
|
126
131
|
the most accurate combination of activation potentiation(or activation function) & weight values for the labeled classificaiton dataset.
|
@@ -132,18 +137,29 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
132
137
|
* This function also able to train classic MLP model architectures.
|
133
138
|
* And my newest innovative architecture: PTNN (Potentiation Transfer Neural Network).
|
134
139
|
|
140
|
+
Examples:
|
141
|
+
|
142
|
+
This creates a PLAN model:
|
143
|
+
- ```model = learn(x_train, y_train, optimizer, template_model, pop_size=100, gen=100, fit_start=True) ```
|
144
|
+
|
145
|
+
This creates a MLP model(with 2 hidden layer):
|
146
|
+
- ```model = learn(x_train, y_train, optimizer, template_model, pop_size=100, gen=100, fit_start=False, neurons=[64, 64], activation_functions=['tanh', 'tanh']) ```
|
147
|
+
|
148
|
+
This creates a PTNN model(with 2 hidden layer & 1 aggregation layer(comes with PLAN)):
|
149
|
+
- ```model = learn(x_train, y_train, optimizer, template_model, pop_size=100, gen=[10, 100], fit_start=True, neurons=[64, 64], activation_functions=['tanh', 'tanh']) ```
|
150
|
+
|
135
151
|
:Args:
|
136
152
|
:param x_train: (array-like): Training input data.
|
137
153
|
:param y_train: (array-like): Labels for training data. one-hot encoded.
|
138
|
-
:param optimizer: (function): Optimization technique with hyperparameters. (PLAN, MLP & PTNN (all) using ENE for optimization. Gradient based technique's will added in the future.) Please use this: from pyerualjetwork.
|
154
|
+
:param optimizer: (function): Optimization technique with hyperparameters. (PLAN, MLP & PTNN (all) using ENE for optimization. Gradient based technique's will added in the future.) Please use this: from pyerualjetwork.ene import evolver (and) optimizer = lambda *args, **kwargs: evolver(*args, 'here give your hyperparameters for example: activation_add_prob=0.85', **kwargs) Example:
|
139
155
|
```python
|
140
|
-
optimizer = lambda *args, **kwargs:
|
156
|
+
optimizer = lambda *args, **kwargs: ene.evolver(*args,
|
141
157
|
activation_add_prob=0.05,
|
142
158
|
strategy='aggressive',
|
143
159
|
policy='more_selective',
|
144
160
|
**kwargs)
|
145
161
|
|
146
|
-
model =
|
162
|
+
model = nn.learn(x_train,
|
147
163
|
y_train,
|
148
164
|
optimizer,
|
149
165
|
fit_start=True,
|
@@ -152,6 +168,7 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
152
168
|
batch_size=0.05,
|
153
169
|
interval=16.67)
|
154
170
|
```
|
171
|
+
:param template_model: (tuple): Use --> get_model_template() function in the model_ops module.
|
155
172
|
:param fit_start: (bool, optional): If the fit_start parameter is set to True, the initial generation population undergoes a simple short training process using the PLAN algorithm. This allows for a very robust starting point, especially for large and complex datasets. However, for small or relatively simple datasets, it may result in unnecessary computational overhead. When fit_start is True, completing the first generation may take slightly longer (this increase in computational cost applies only to the first generation and does not affect subsequent generations). If fit_start is set to False, the initial population will be entirely random. Additonaly if you want to train PTNN model you must be give True. Options: True or False. Default: True
|
156
173
|
:param gen: (int or list): The generation count for genetic optimization. If you want to train PTNN model you must give a list of two number. First number for PLAN model training second number for MLP.
|
157
174
|
:param batch_size: (float, optional): Batch size is used in the prediction process to receive train feedback by dividing the train data into chunks and selecting activations based on randomly chosen partitions. This process reduces computational cost and time while still covering the entire train set due to random selection, so it doesn't significantly impact accuracy. For example, a batch size of 0.08 means each train batch represents %8 of the train set. Default is 1. (%100 of train)
|
@@ -172,29 +189,56 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
172
189
|
:param start_this_act: (list, optional): To resume a previously canceled or interrupted training from where it left off, or to continue from that point with a different strategy, provide the list of activation functions selected up to the learned portion to this parameter. Default is None
|
173
190
|
:param start_this_W: (numpy.array, optional): To resume a previously canceled or interrupted training from where it left off, or to continue from that point with a different strategy, provide the weight matrix of this genome. Default is None
|
174
191
|
:param neurons: (list[int], optional): If you dont want train PLAN model this parameter represents neuron count of each hidden layer for MLP or PTNN. Number of elements --> Layer count. Default: [] (No hidden layer) --> architecture setted to PLAN, if not --> architecture setted to MLP.
|
192
|
+
:param decision_boundary_history: (bool, optional): At the end of the training, the decision boundary history is shown in animation form. Note: If you are sure of your memory, set it to True. Default: False
|
175
193
|
:param activation_functions: (list[str], optional): If you dont want train PLAN model this parameter represents activation function of each hidden layer for MLP or PTNN. if neurons is not [] --> uses default: ['linear'] * len(neurons). if neurons is [] --> uses [].
|
176
194
|
:param dtype: (numpy.dtype): Data type for the Weight matrices. np.float32 by default. Example: np.float64 or np.float16.
|
195
|
+
:param cuda: (bool, optional): CUDA GPU acceleration ? Default = False.
|
177
196
|
|
178
197
|
Returns:
|
179
198
|
tuple: A list for model parameters: [Weight matrix, Train Preds, Train Accuracy, [Activations functions]].
|
180
199
|
"""
|
181
200
|
|
182
|
-
from .
|
183
|
-
|
201
|
+
from .ene import define_genomes
|
202
|
+
from .cpu.visualizations import display_decision_boundary_history, create_decision_boundary_hist, plot_decision_boundary
|
203
|
+
|
204
|
+
if cuda is False:
|
205
|
+
from .cpu.data_ops import batcher
|
206
|
+
from .cpu.loss_functions import categorical_crossentropy, binary_crossentropy
|
207
|
+
from .cpu.visualizations import (
|
208
|
+
draw_neural_web,
|
209
|
+
display_visualizations_for_learner,
|
210
|
+
update_history_plots_for_learner,
|
211
|
+
initialize_visualization_for_learner,
|
212
|
+
update_neuron_history_for_learner)
|
213
|
+
|
214
|
+
else:
|
215
|
+
from .cuda.data_ops import batcher
|
216
|
+
from .cuda.loss_functions import categorical_crossentropy, binary_crossentropy
|
217
|
+
from .cuda.visualizations import (
|
218
|
+
draw_neural_web,
|
219
|
+
display_visualizations_for_learner,
|
220
|
+
update_history_plots_for_learner,
|
221
|
+
initialize_visualization_for_learner,
|
222
|
+
update_neuron_history_for_learner)
|
223
|
+
|
184
224
|
data = 'Train'
|
185
225
|
|
186
226
|
except_this = ['spiral', 'circular']
|
187
227
|
activations = [item for item in all_activations() if item not in except_this]
|
188
228
|
activations_len = len(activations)
|
189
|
-
|
229
|
+
|
190
230
|
# Pre-checks
|
191
231
|
|
232
|
+
if cuda:
|
233
|
+
x_train = transfer_to_gpu(x_train, dtype=dtype)
|
234
|
+
y_train = transfer_to_gpu(y_train, dtype=dtype)
|
235
|
+
|
192
236
|
if pop_size > activations_len and fit_start is True:
|
193
237
|
for _ in range(pop_size - len(activations)):
|
194
238
|
random_index_all_act = random.randint(0, len(activations)-1)
|
195
239
|
activations.append(activations[random_index_all_act])
|
196
240
|
|
197
|
-
y_train = optimize_labels(y_train, cuda=
|
241
|
+
y_train = optimize_labels(y_train, cuda=cuda)
|
198
242
|
|
199
243
|
if pop_size < activations_len: raise ValueError(f"pop_size must be higher or equal to {activations_len}")
|
200
244
|
|
@@ -250,7 +294,7 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
250
294
|
loss_list = []
|
251
295
|
target_pop = []
|
252
296
|
|
253
|
-
progress = initialize_loading_bar(total=
|
297
|
+
progress = initialize_loading_bar(total=pop_size, desc="", ncols=77, bar_format=bar_format_learner)
|
254
298
|
|
255
299
|
if fit_start is False:
|
256
300
|
weight_pop, act_pop = define_genomes(input_shape=len(x_train[0]), output_shape=len(y_train[0]), neurons=neurons, activation_functions=activations, population_size=pop_size, dtype=dtype)
|
@@ -266,10 +310,10 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
266
310
|
# LEARNING STARTED
|
267
311
|
for i in range(gen):
|
268
312
|
|
269
|
-
|
313
|
+
# TRANSFORMATION PLAN TO MLP FOR PTNN (in later generations)
|
270
314
|
if model_type == 'PLAN' and transfer_learning:
|
271
315
|
if i == gen_copy[0]:
|
272
|
-
|
316
|
+
|
273
317
|
model_type = 'PTNN'
|
274
318
|
neurons = neurons_copy
|
275
319
|
|
@@ -308,24 +352,24 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
308
352
|
progress.update(0)
|
309
353
|
|
310
354
|
for j in range(pop_size):
|
311
|
-
|
312
|
-
x_train_batch, y_train_batch = batcher(x_train, y_train, batch_size=batch_size)
|
313
355
|
|
356
|
+
x_train_batch, y_train_batch = batcher(x_train, y_train, batch_size=batch_size)
|
357
|
+
|
314
358
|
if fit_start is True and i == 0:
|
315
359
|
if start_this_act is not None and j == 0:
|
316
360
|
pass
|
317
361
|
else:
|
318
362
|
|
319
363
|
act_pop[j] = activations[j]
|
320
|
-
W = plan_fit(x_train_batch, y_train_batch, activations=act_pop[j], auto_normalization=auto_normalization, dtype=dtype)
|
364
|
+
W = plan_fit(x_train_batch, y_train_batch, activations=act_pop[j], cuda=cuda, auto_normalization=auto_normalization, dtype=dtype)
|
321
365
|
weight_pop[j] = W
|
322
366
|
|
323
367
|
|
324
368
|
if weight_evolve is False:
|
325
|
-
weight_pop[j] = plan_fit(x_train_batch, y_train_batch, activations=act_pop[j], auto_normalization=auto_normalization, dtype=dtype)
|
369
|
+
weight_pop[j] = plan_fit(x_train_batch, y_train_batch, activations=act_pop[j], cuda=cuda, auto_normalization=auto_normalization, dtype=dtype)
|
326
370
|
|
327
371
|
|
328
|
-
model = evaluate(x_train_batch, y_train_batch, W=weight_pop[j], activations=act_pop[j], activation_potentiations=activation_potentiations[j], auto_normalization=auto_normalization, model_type=model_type)
|
372
|
+
model = evaluate(x_train_batch, y_train_batch, W=weight_pop[j], activations=act_pop[j], activation_potentiations=activation_potentiations[j], auto_normalization=auto_normalization, cuda=cuda, model_type=model_type)
|
329
373
|
acc = model[get_acc()]
|
330
374
|
|
331
375
|
if loss == 'categorical_crossentropy':
|
@@ -336,8 +380,8 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
336
380
|
y_pred_batch=model[get_preds_softmax()])
|
337
381
|
|
338
382
|
fitness = wals(acc, train_loss, acc_impact, loss_impact)
|
339
|
-
target_pop.append(fitness)
|
340
|
-
|
383
|
+
target_pop.append(fitness if not cuda else fitness.get())
|
384
|
+
|
341
385
|
if fitness >= best_fitness:
|
342
386
|
|
343
387
|
best_fitness = fitness
|
@@ -346,7 +390,13 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
346
390
|
best_weight = np.copy(weight_pop[j]) if model_type == 'PLAN' else copy.deepcopy(weight_pop[j])
|
347
391
|
best_model = model
|
348
392
|
|
349
|
-
|
393
|
+
if isinstance(act_pop[j], list) and model_type == 'PLAN':
|
394
|
+
final_activations = act_pop[j].copy()
|
395
|
+
elif isinstance(act_pop[j], str):
|
396
|
+
final_activations = act_pop[j]
|
397
|
+
else:
|
398
|
+
final_activations = copy.deepcopy(act_pop[j])
|
399
|
+
|
350
400
|
if model_type == 'PLAN': final_activations = [final_activations[0]] if len(set(final_activations)) == 1 else final_activations # removing if all same
|
351
401
|
|
352
402
|
if batch_size == 1:
|
@@ -382,7 +432,7 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
382
432
|
if target_acc is not None and best_acc >= target_acc:
|
383
433
|
progress.close()
|
384
434
|
train_model = evaluate(x_train, y_train, W=best_weight,
|
385
|
-
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, model_type=model_type)
|
435
|
+
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, cuda=cuda, model_type=model_type)
|
386
436
|
if loss == 'categorical_crossentropy':
|
387
437
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
388
438
|
y_pred_batch=train_model[get_preds_softmax()])
|
@@ -396,15 +446,26 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
396
446
|
print('Train Loss: ', train_loss, '\n')
|
397
447
|
print('Model Type:', model_type)
|
398
448
|
|
449
|
+
if decision_boundary_history: display_decision_boundary_history(fig, artist, interval=interval)
|
450
|
+
|
399
451
|
display_visualizations_for_learner(viz_objects, best_weight, data, best_acc,
|
400
452
|
best_loss, y_train, interval)
|
401
|
-
|
453
|
+
|
454
|
+
model = template_model._replace(weights=best_weight,
|
455
|
+
predictions=best_model[get_preds()],
|
456
|
+
accuracy=best_acc,
|
457
|
+
activations=final_activations,
|
458
|
+
softmax_predictions=best_model[get_preds_softmax()],
|
459
|
+
model_type=model_type,
|
460
|
+
activation_potentiation=activation_potentiation)
|
461
|
+
|
462
|
+
return model
|
402
463
|
|
403
464
|
# Check target loss
|
404
465
|
if target_loss is not None and best_loss <= target_loss:
|
405
466
|
progress.close()
|
406
467
|
train_model = evaluate(x_train, y_train, W=best_weight,
|
407
|
-
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, model_type=model_type)
|
468
|
+
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, cuda=cuda, model_type=model_type)
|
408
469
|
|
409
470
|
if loss == 'categorical_crossentropy':
|
410
471
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -419,16 +480,33 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
419
480
|
print('Train Loss: ', train_loss, '\n')
|
420
481
|
print('Model Type:', model_type)
|
421
482
|
|
483
|
+
if decision_boundary_history: display_decision_boundary_history(fig, artist, interval=interval)
|
484
|
+
|
422
485
|
# Display final visualizations
|
423
486
|
display_visualizations_for_learner(viz_objects, best_weight, data, best_acc,
|
424
487
|
train_loss, y_train, interval)
|
425
|
-
|
488
|
+
|
489
|
+
model = template_model._replace(weights=best_weight,
|
490
|
+
predictions=best_model[get_preds()],
|
491
|
+
accuracy=best_acc,
|
492
|
+
activations=final_activations,
|
493
|
+
softmax_predictions=best_model[get_preds_softmax()],
|
494
|
+
model_type=model_type,
|
495
|
+
activation_potentiation=activation_potentiation)
|
496
|
+
|
497
|
+
return model
|
426
498
|
|
427
499
|
|
428
500
|
progress.update(1)
|
429
501
|
|
502
|
+
if decision_boundary_history:
|
503
|
+
if i == 0:
|
504
|
+
fig, ax = create_decision_boundary_hist()
|
505
|
+
artist = []
|
506
|
+
artist = plot_decision_boundary(x_train_batch, y_train_batch, activations=act_pop[np.argmax(target_pop)], W=weight_pop[np.argmax(target_pop)], cuda=cuda, model_type=model_type, ax=ax, artist=artist)
|
507
|
+
|
430
508
|
if batch_size != 1:
|
431
|
-
train_model = evaluate(x_train, y_train, W=best_weight, activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, model_type=model_type)
|
509
|
+
train_model = evaluate(x_train, y_train, W=best_weight, activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, cuda=cuda, model_type=model_type)
|
432
510
|
|
433
511
|
if loss == 'categorical_crossentropy':
|
434
512
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -459,7 +537,7 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
459
537
|
if best_acc_per_gen_list[i] == best_acc_per_gen_list[i-1]:
|
460
538
|
progress.close()
|
461
539
|
train_model = evaluate(x_train, y_train, W=best_weight,
|
462
|
-
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, model_type=model_type)
|
540
|
+
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, cuda=cuda, model_type=model_type)
|
463
541
|
|
464
542
|
if loss == 'categorical_crossentropy':
|
465
543
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -474,16 +552,27 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
474
552
|
print('Train Loss: ', train_loss, '\n')
|
475
553
|
print('Model Type:', model_type)
|
476
554
|
|
555
|
+
if decision_boundary_history: display_decision_boundary_history(fig, artist, interval=interval)
|
556
|
+
|
477
557
|
# Display final visualizations
|
478
558
|
display_visualizations_for_learner(viz_objects, best_weight, data, best_acc,
|
479
559
|
train_loss, y_train, interval)
|
480
|
-
|
560
|
+
|
561
|
+
model = template_model._replace(weights=best_weight,
|
562
|
+
predictions=best_model[get_preds()],
|
563
|
+
accuracy=best_acc,
|
564
|
+
activations=final_activations,
|
565
|
+
softmax_predictions=best_model[get_preds_softmax()],
|
566
|
+
model_type=model_type,
|
567
|
+
activation_potentiation=activation_potentiation)
|
568
|
+
|
569
|
+
return model
|
481
570
|
|
482
571
|
# Final evaluation
|
483
572
|
progress.close()
|
484
573
|
|
485
574
|
train_model = evaluate(x_train, y_train, W=best_weight,
|
486
|
-
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, model_type=model_type)
|
575
|
+
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, cuda=cuda, model_type=model_type)
|
487
576
|
|
488
577
|
if loss == 'categorical_crossentropy':
|
489
578
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -492,25 +581,40 @@ def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size
|
|
492
581
|
train_loss = binary_crossentropy(y_true_batch=y_train,
|
493
582
|
y_pred_batch=train_model[get_preds_softmax()])
|
494
583
|
|
584
|
+
|
495
585
|
print('\nActivations: ', final_activations)
|
496
586
|
print('Activation Potentiation: ', activation_potentiation)
|
497
587
|
print('Train Accuracy:', train_model[get_acc()])
|
498
588
|
print('Train Loss: ', train_loss, '\n')
|
499
589
|
print('Model Type:', model_type)
|
500
590
|
|
591
|
+
if decision_boundary_history: display_decision_boundary_history(fig, artist, interval=interval)
|
592
|
+
|
501
593
|
# Display final visualizations
|
502
594
|
display_visualizations_for_learner(viz_objects, best_weight, data, best_acc, train_loss, y_train, interval)
|
503
|
-
|
595
|
+
|
596
|
+
model = template_model._replace(weights=best_weight,
|
597
|
+
predictions=best_model[get_preds()],
|
598
|
+
accuracy=best_acc,
|
599
|
+
activations=final_activations,
|
600
|
+
softmax_predictions=best_model[get_preds_softmax()],
|
601
|
+
model_type=model_type,
|
602
|
+
activation_potentiation=activation_potentiation)
|
603
|
+
|
604
|
+
return model
|
504
605
|
|
505
606
|
|
506
607
|
def evaluate(
|
507
608
|
x_test,
|
508
609
|
y_test,
|
509
|
-
|
510
|
-
|
610
|
+
model=None,
|
611
|
+
model_type=None,
|
612
|
+
W=None,
|
511
613
|
activations=['linear'],
|
512
614
|
activation_potentiations=[],
|
513
|
-
auto_normalization=False
|
615
|
+
auto_normalization=False,
|
616
|
+
show_report=False,
|
617
|
+
cuda=False
|
514
618
|
) -> tuple:
|
515
619
|
"""
|
516
620
|
Evaluates the neural network model using the given test data.
|
@@ -520,61 +624,65 @@ def evaluate(
|
|
520
624
|
|
521
625
|
y_test (np.ndarray): Test labels (one-hot encoded).
|
522
626
|
|
523
|
-
|
627
|
+
model (tuple, optional): Trained model.
|
628
|
+
|
629
|
+
model_type: (str, optional): Type of the model. Options: 'PLAN', 'MLP', 'PTNN'.
|
630
|
+
|
631
|
+
W (array-like, optional): Neural net weight matrix.
|
524
632
|
|
525
|
-
W (np.ndarray): Neural net weight matrix.
|
526
|
-
|
527
633
|
activations (list, optional): Activation list for PLAN or MLP models (MLP layers activations if it PTNN model). Default = ['linear'].
|
528
634
|
|
529
635
|
activation_potentiations (list, optional): Extra activation potentiation list (PLAN layers activations) for PTNN models. Default = [].
|
530
636
|
|
531
637
|
auto_normalization (bool, optional): Normalization for x_test ? Default = False.
|
532
638
|
|
533
|
-
|
534
|
-
tuple: Model (list).
|
535
|
-
"""
|
639
|
+
show_report (bool, optional): show test report. Default = False
|
536
640
|
|
537
|
-
|
641
|
+
cuda (bool, optional): CUDA GPU acceleration ? Default = False.
|
538
642
|
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
activations = [item if isinstance(item, list) or isinstance(item, str) else [item] for item in activations]
|
643
|
+
Returns:
|
644
|
+
tuple: W, preds, accuracy, None, None, softmax_preds
|
645
|
+
"""
|
543
646
|
|
544
|
-
|
545
|
-
|
546
|
-
for i in range(len(W)):
|
547
|
-
if i != len(W) - 1 and i != 0: layer = apply_activation(layer, activations[i])
|
647
|
+
from .cpu.visualizations import plot_evaluate
|
648
|
+
from .model_ops import predict_from_memory
|
548
649
|
|
549
|
-
|
650
|
+
if not cuda:
|
651
|
+
from .cpu.data_ops import normalization
|
652
|
+
|
653
|
+
if model:
|
654
|
+
sample_acc = model.accuracy
|
655
|
+
if hasattr(sample_acc, "get"): model = model._replace(accuracy=sample_acc.get())
|
550
656
|
|
551
|
-
|
657
|
+
else:
|
658
|
+
from .cuda.data_ops import normalization
|
659
|
+
x_test = cp.array(x_test)
|
660
|
+
y_test = cp.array(y_test)
|
552
661
|
|
553
|
-
|
662
|
+
if model:
|
663
|
+
sample_acc = model.accuracy
|
664
|
+
if isinstance(sample_acc, np.number): model = model._replace(accuracy=cp.array(sample_acc))
|
554
665
|
|
555
|
-
|
556
|
-
|
666
|
+
if model is None:
|
667
|
+
from .model_ops import get_model_template
|
668
|
+
template_model = get_model_template()
|
669
|
+
|
670
|
+
model = template_model._replace(weights=W,
|
671
|
+
activations=activations,
|
672
|
+
model_type=model_type,
|
673
|
+
activation_potentiation=activation_potentiations)
|
557
674
|
|
558
|
-
|
675
|
+
result = predict_from_memory(x_test, model, cuda=cuda)
|
559
676
|
|
560
|
-
|
561
|
-
activation_potentiations = [activation_potentiations]
|
562
|
-
elif isinstance(activation_potentiations, list):
|
563
|
-
activation_potentiations = [item if isinstance(item, list) or isinstance(item, str) else [item] for item in activation_potentiations]
|
564
|
-
|
565
|
-
x_test = apply_activation(x_test, activation_potentiations)
|
566
|
-
layer = x_test @ W[0].T
|
677
|
+
if auto_normalization: x_test = normalization(x_test, dtype=x_test.dtype)
|
567
678
|
|
568
|
-
|
569
|
-
if i != len(W) - 1: layer = apply_activation(layer, activations[i])
|
679
|
+
array_type = cp if cuda else np
|
570
680
|
|
571
|
-
|
681
|
+
max_vals = array_type.max(result, axis=1, keepdims=True)
|
682
|
+
|
683
|
+
softmax_preds = array_type.exp(result - max_vals) / array_type.sum(array_type.exp(result - max_vals), axis=1, keepdims=True)
|
684
|
+
accuracy = (array_type.argmax(softmax_preds, axis=1) == array_type.argmax(y_test, axis=1)).mean()
|
572
685
|
|
573
|
-
|
686
|
+
if show_report: plot_evaluate(x_test, y_test, result, acc=accuracy, model=model, cuda=cuda)
|
574
687
|
|
575
|
-
max_vals = np.max(result, axis=1, keepdims=True)
|
576
|
-
|
577
|
-
softmax_preds = np.exp(result - max_vals) / np.sum(np.exp(result - max_vals), axis=1, keepdims=True)
|
578
|
-
accuracy = (np.argmax(softmax_preds, axis=1) == np.argmax(y_test, axis=1)).mean()
|
579
|
-
|
580
688
|
return W, result, accuracy, None, None, softmax_preds
|