pyerualjetwork 3.3.4__py3-none-any.whl → 4.1.9__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 +7 -16
- pyerualjetwork/activation_functions.py +120 -146
- pyerualjetwork/activation_functions_cuda.py +341 -0
- pyerualjetwork/data_operations.py +79 -77
- pyerualjetwork/data_operations_cuda.py +461 -0
- pyerualjetwork/help.py +4 -4
- pyerualjetwork/loss_functions_cuda.py +21 -0
- pyerualjetwork/memory_operations.py +298 -0
- pyerualjetwork/metrics_cuda.py +163 -0
- pyerualjetwork/model_operations.py +81 -23
- pyerualjetwork/model_operations_cuda.py +421 -0
- pyerualjetwork/plan.py +229 -210
- pyerualjetwork/plan_cuda.py +696 -0
- pyerualjetwork/planeat.py +60 -43
- pyerualjetwork/planeat_cuda.py +744 -0
- pyerualjetwork/visualizations.py +153 -129
- pyerualjetwork/visualizations_cuda.py +826 -0
- {pyerualjetwork-3.3.4.dist-info → pyerualjetwork-4.1.9.dist-info}/METADATA +45 -21
- pyerualjetwork-4.1.9.dist-info/RECORD +24 -0
- pyerualjetwork-3.3.4.dist-info/RECORD +0 -15
- {pyerualjetwork-3.3.4.dist-info → pyerualjetwork-4.1.9.dist-info}/WHEEL +0 -0
- {pyerualjetwork-3.3.4.dist-info → pyerualjetwork-4.1.9.dist-info}/top_level.txt +0 -0
pyerualjetwork/plan.py
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
|
4
4
|
MAIN MODULE FOR PLAN
|
5
5
|
|
6
|
-
PLAN document: https://github.com/HCB06/
|
7
|
-
|
6
|
+
PLAN document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PLAN/PLAN.pdf
|
7
|
+
PYERUALJETWORK document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PyerualJetwork/PYERUALJETWORK_USER_MANUEL_AND_LEGAL_INFORMATION(EN).pdf
|
8
8
|
|
9
9
|
@author: Hasan Can Beydili
|
10
10
|
@YouTube: https://www.youtube.com/@HasanCanBeydili
|
@@ -14,8 +14,9 @@ ANAPLAN document: https://github.com/HCB06/Anaplan/blob/main/Welcome_to_Anaplan/
|
|
14
14
|
"""
|
15
15
|
|
16
16
|
import numpy as np
|
17
|
-
from colorama import Fore
|
18
|
-
import
|
17
|
+
from colorama import Fore
|
18
|
+
import math
|
19
|
+
import random
|
19
20
|
|
20
21
|
### LIBRARY IMPORTS ###
|
21
22
|
from .ui import loading_bars, initialize_loading_bar
|
@@ -23,11 +24,13 @@ from .data_operations import normalization, decode_one_hot, batcher
|
|
23
24
|
from .loss_functions import binary_crossentropy, categorical_crossentropy
|
24
25
|
from .activation_functions import apply_activation, Softmax, all_activations
|
25
26
|
from .metrics import metrics
|
26
|
-
from.model_operations import get_acc, get_preds, get_preds_softmax
|
27
|
+
from .model_operations import get_acc, get_preds, get_preds_softmax
|
28
|
+
from .memory_operations import optimize_labels
|
27
29
|
from .visualizations import (
|
28
30
|
draw_neural_web,
|
31
|
+
update_neural_web_for_fit,
|
29
32
|
plot_evaluate,
|
30
|
-
|
33
|
+
update_neuron_history,
|
31
34
|
initialize_visualization_for_fit,
|
32
35
|
update_weight_visualization_for_fit,
|
33
36
|
update_decision_boundary_for_fit,
|
@@ -35,7 +38,9 @@ from .visualizations import (
|
|
35
38
|
display_visualization_for_fit,
|
36
39
|
display_visualizations_for_learner,
|
37
40
|
update_history_plots_for_learner,
|
38
|
-
initialize_visualization_for_learner
|
41
|
+
initialize_visualization_for_learner,
|
42
|
+
update_neuron_history_for_learner,
|
43
|
+
show
|
39
44
|
)
|
40
45
|
|
41
46
|
### GLOBAL VARIABLES ###
|
@@ -47,7 +52,7 @@ bar_format_learner = loading_bars()[1]
|
|
47
52
|
def fit(
|
48
53
|
x_train,
|
49
54
|
y_train,
|
50
|
-
val=
|
55
|
+
val=False,
|
51
56
|
val_count=None,
|
52
57
|
activation_potentiation=['linear'],
|
53
58
|
x_val=None,
|
@@ -58,7 +63,8 @@ def fit(
|
|
58
63
|
decision_boundary_status=True,
|
59
64
|
train_bar=True,
|
60
65
|
auto_normalization=True,
|
61
|
-
neurons_history=False
|
66
|
+
neurons_history=False,
|
67
|
+
dtype=np.float32
|
62
68
|
):
|
63
69
|
"""
|
64
70
|
Creates a model to fitting data.
|
@@ -93,11 +99,16 @@ def fit(
|
|
93
99
|
|
94
100
|
neurons_history (bool, optional): Shows the history of changes that neurons undergo during the CL (Cumulative Learning) stages. True or False. Default is False. (optional)
|
95
101
|
|
102
|
+
dtype (numpy.dtype): Data type for the arrays. np.float32 by default. Example: np.float64 or np.float16. [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not reccomended!] (optional)
|
103
|
+
|
96
104
|
Returns:
|
97
105
|
numpyarray([num]): (Weight matrix).
|
98
106
|
"""
|
107
|
+
|
99
108
|
# Pre-checks
|
100
109
|
|
110
|
+
x_train = x_train.astype(dtype, copy=False)
|
111
|
+
|
101
112
|
if train_bar and val:
|
102
113
|
train_progress = initialize_loading_bar(total=len(x_train), ncols=71, desc='Fitting', bar_format=bar_format_normal)
|
103
114
|
elif train_bar and val == False:
|
@@ -106,82 +117,117 @@ def fit(
|
|
106
117
|
if len(x_train) != len(y_train):
|
107
118
|
raise ValueError("x_train and y_train must have the same length.")
|
108
119
|
|
109
|
-
if val and (x_val is None
|
120
|
+
if val and (x_val is None and y_val is None):
|
110
121
|
x_val, y_val = x_train, y_train
|
111
122
|
|
123
|
+
elif val and (x_val is not None and y_val is not None):
|
124
|
+
x_val = x_val.astype(dtype, copy=False)
|
125
|
+
y_val = y_val.astype(dtype, copy=False)
|
126
|
+
|
112
127
|
val_list = [] if val else None
|
113
128
|
val_count = val_count or 10
|
114
129
|
# Defining weights
|
115
|
-
STPW = np.ones((len(y_train[0]), len(x_train[0].ravel()))) # STPW = SHORT TIME POTENTIATION WEIGHT
|
116
|
-
LTPW = np.zeros((len(y_train[0]), len(x_train[0].ravel()))) # LTPW = LONG TIME POTENTIATION WEIGHT
|
130
|
+
STPW = np.ones((len(y_train[0]), len(x_train[0].ravel()))).astype(dtype, copy=False) # STPW = SHORT TIME POTENTIATION WEIGHT
|
131
|
+
LTPW = np.zeros((len(y_train[0]), len(x_train[0].ravel()))).astype(dtype, copy=False) # LTPW = LONG TIME POTENTIATION WEIGHT
|
117
132
|
# Initialize visualization
|
118
133
|
vis_objects = initialize_visualization_for_fit(val, show_training, neurons_history, x_train, y_train)
|
119
134
|
|
120
135
|
# Training process
|
121
136
|
for index, inp in enumerate(x_train):
|
122
|
-
inp = np.array(inp).ravel()
|
137
|
+
inp = np.array(inp, copy=False).ravel()
|
123
138
|
y_decoded = decode_one_hot(y_train)
|
124
139
|
# Weight updates
|
125
140
|
STPW = feed_forward(inp, STPW, is_training=True, Class=y_decoded[index], activation_potentiation=activation_potentiation, LTD=LTD)
|
126
|
-
LTPW += normalization(STPW) if auto_normalization else STPW
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
141
|
+
LTPW += normalization(STPW, dtype=dtype) if auto_normalization else STPW
|
142
|
+
if val and index != 0:
|
143
|
+
if index % math.ceil((val_count / len(x_train)) * 100) == 0:
|
144
|
+
val_acc = evaluate(x_val, y_val, loading_bar_status=False, activation_potentiation=activation_potentiation, W=LTPW)[get_acc()]
|
145
|
+
val_list.append(val_acc)
|
146
|
+
|
147
|
+
# Visualization updates
|
148
|
+
if show_training:
|
149
|
+
update_weight_visualization_for_fit(vis_objects['ax'][0, 0], LTPW, vis_objects['artist2'])
|
150
|
+
if decision_boundary_status:
|
151
|
+
update_decision_boundary_for_fit(vis_objects['ax'][0, 1], x_val, y_val, activation_potentiation, LTPW, vis_objects['artist1'])
|
152
|
+
update_validation_history_for_fit(vis_objects['ax'][1, 1], val_list, vis_objects['artist3'])
|
153
|
+
update_neural_web_for_fit(W=LTPW, G=vis_objects['G'], ax=vis_objects['ax'][1, 0], artist=vis_objects['artist4'])
|
154
|
+
if neurons_history:
|
155
|
+
update_neuron_history(LTPW, row=vis_objects['row'], col=vis_objects['col'], class_count=len(y_train[0]), fig1=vis_objects['fig1'], ax1=vis_objects['ax1'], artist5=vis_objects['artist5'], acc=val_acc)
|
134
156
|
if train_bar:
|
135
157
|
train_progress.update(1)
|
136
158
|
|
137
|
-
STPW = np.ones((len(y_train[0]), len(x_train[0].ravel())))
|
159
|
+
STPW = np.ones((len(y_train[0]), len(x_train[0].ravel()))).astype(dtype, copy=False)
|
138
160
|
|
139
161
|
# Finalize visualization
|
140
162
|
if show_training:
|
141
|
-
display_visualization_for_fit(vis_objects['fig'], vis_objects['artist1'], interval)
|
163
|
+
ani1 = display_visualization_for_fit(vis_objects['fig'], vis_objects['artist1'], interval)
|
164
|
+
ani2 = display_visualization_for_fit(vis_objects['fig'], vis_objects['artist2'], interval)
|
165
|
+
ani3 = display_visualization_for_fit(vis_objects['fig'], vis_objects['artist3'], interval)
|
166
|
+
ani4 = display_visualization_for_fit(vis_objects['fig'], vis_objects['artist4'], interval)
|
167
|
+
show()
|
168
|
+
|
169
|
+
if neurons_history:
|
170
|
+
ani5 = display_visualization_for_fit(vis_objects['fig1'], vis_objects['artist5'], interval)
|
171
|
+
show()
|
142
172
|
|
143
|
-
return normalization(LTPW)
|
173
|
+
return normalization(LTPW, dtype=dtype)
|
144
174
|
|
145
175
|
|
146
|
-
def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', batch_size=1,
|
176
|
+
def learner(x_train, y_train, optimizer, x_test=None, y_test=None, strategy='accuracy', gen=None, batch_size=1,
|
147
177
|
neural_web_history=False, show_current_activations=False, auto_normalization=True,
|
148
|
-
neurons_history=False,
|
149
|
-
early_stop=False, loss='categorical_crossentropy', show_history=False,
|
178
|
+
neurons_history=False, early_stop=False, loss='categorical_crossentropy', show_history=False,
|
150
179
|
interval=33.33, target_acc=None, target_loss=None, except_this=None,
|
151
|
-
only_this=None,
|
180
|
+
only_this=None, start_this_act=None, start_this_W=None, target_fitness='max', dtype=np.float32):
|
152
181
|
"""
|
153
182
|
Optimizes the activation functions for a neural network by leveraging train data to find
|
154
|
-
the most accurate combination of activation potentiation for the given dataset.
|
183
|
+
the most accurate combination of activation potentiation for the given dataset using genetic algorithm NEAT (Neuroevolution of Augmenting Topologies). But modifided for PLAN version. Created by me: PLANEAT.
|
155
184
|
|
185
|
+
Why genetic optimization and not backpropagation?
|
186
|
+
Because PLAN is different from other neural network architectures. In PLAN, the learnable parameters are not the weights; instead, the learnable parameters are the activation functions.
|
187
|
+
Since activation functions are not differentiable, we cannot use gradient descent or backpropagation. However, I developed a more powerful genetic optimization algorithm: PLANEAT.
|
188
|
+
|
156
189
|
Args:
|
157
190
|
|
158
191
|
x_train (array-like): Training input data.
|
159
192
|
|
160
|
-
y_train (array-like): Labels for training data.
|
193
|
+
y_train (array-like): Labels for training data. one-hot encoded.
|
194
|
+
|
195
|
+
optimizer (function): PLAN optimization technique with hyperparameters. (PLAN using NEAT(PLANEAT) for optimization.) Please use this: from pyerualjetwork import planeat (and) optimizer = lambda *args, **kwargs: planeat.evolve(*args, 'here give your neat hyperparameters for example: activation_add_prob=0.85', **kwargs) Example:
|
196
|
+
```python
|
197
|
+
genetic_optimizer = lambda *args, **kwargs: planeat.evolve(*args,
|
198
|
+
activation_add_prob=0.85,
|
199
|
+
mutations=False,
|
200
|
+
strategy='cross_over',
|
201
|
+
**kwargs)
|
202
|
+
|
203
|
+
model = plan.learner(x_train,
|
204
|
+
y_train,
|
205
|
+
optimizer=genetic_optimizer,
|
206
|
+
strategy='accuracy',
|
207
|
+
show_history=True,
|
208
|
+
target_acc=0.94,
|
209
|
+
interval=16.67)
|
210
|
+
```
|
161
211
|
|
162
212
|
x_test (array-like, optional): Test input data (for improve next gen generilization). If test data is not given then train feedback learning active
|
163
213
|
|
164
214
|
y_test (array-like, optional): Test Labels (for improve next gen generilization). If test data is not given then train feedback learning active
|
165
215
|
|
166
|
-
strategy (str, optional): Learning strategy. (options: 'accuracy', '
|
167
|
-
|
168
|
-
patience ((int, float), optional): patience value for adaptive strategies. For 'adaptive_accuracy' Default value: 5. For 'adaptive_loss' Default value: 0.150.
|
216
|
+
strategy (str, optional): Learning strategy. (options: 'accuracy', 'f1', 'precision', 'recall'): 'accuracy', Maximizes train (or test if given) accuracy during learning. 'f1', Maximizes train (or test if given) f1 score during learning. 'precision', Maximizes train (or test if given) precision score during learning. 'recall', Maximizes train (or test if given) recall during learning. Default is 'accuracy'.
|
169
217
|
|
170
|
-
|
218
|
+
gen (int, optional): The generation count for genetic optimization.
|
171
219
|
|
172
220
|
batch_size (float, optional): Batch size is used in the prediction process to receive test feedback by dividing the test data into chunks and selecting activations based on randomly chosen partitions. This process reduces computational cost and time while still covering the entire test set due to random selection, so it doesn't significantly impact accuracy. For example, a batch size of 0.08 means each test batch represents 8% of the test set. Default is 1. (%100 of test)
|
173
221
|
|
174
222
|
auto_normalization (bool, optional): If auto normalization=False this makes more faster training times and much better accuracy performance for some datasets. Default is True.
|
175
223
|
|
176
|
-
|
177
|
-
|
178
|
-
early_stop (bool, optional): If True, implements early stopping during training.(If test accuracy not improves in two depth stops learning.) Default is False.
|
224
|
+
early_stop (bool, optional): If True, implements early stopping during training.(If test accuracy not improves in two gen stops learning.) Default is False.
|
179
225
|
|
180
226
|
show_current_activations (bool, optional): Should it display the activations selected according to the current strategies during learning, or not? (True or False) This can be very useful if you want to cancel the learning process and resume from where you left off later. After canceling, you will need to view the live training activations in order to choose the activations to be given to the 'start_this' parameter. Default is False
|
181
227
|
|
182
228
|
show_history (bool, optional): If True, displays the training history after optimization. Default is False.
|
183
229
|
|
184
|
-
loss (str, optional): For visualizing and monitoring. PLAN neural networks doesn't need any loss function in training
|
230
|
+
loss (str, optional): For visualizing and monitoring. PLAN neural networks doesn't need any loss function in training. options: ('categorical_crossentropy' or 'binary_crossentropy') Default is 'categorical_crossentropy'.
|
185
231
|
|
186
232
|
interval (int, optional): The interval at which evaluations are conducted during training. (33.33 = 30 FPS, 16.67 = 60 FPS) Default is 100.
|
187
233
|
|
@@ -193,52 +239,54 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
|
|
193
239
|
|
194
240
|
only_this (list, optional): A list of activations to focus on during optimization. Default is None. (For avaliable activation functions, run this code: plan.activations_list())
|
195
241
|
|
196
|
-
|
242
|
+
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
|
243
|
+
|
244
|
+
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
|
197
245
|
|
198
246
|
neurons_history (bool, optional): Shows the history of changes that neurons undergo during the TFL (Test or Train Feedback Learning) stages. True or False. Default is False.
|
199
247
|
|
200
248
|
neural_web_history (bool, optional): Draws history of neural web. Default is False.
|
201
249
|
|
250
|
+
target_fitness (str, optional): Target fitness strategy for PLANEAT optimization. ('max' for machine learning, 'min' for machine unlearning.) Default: 'max'
|
251
|
+
|
252
|
+
dtype (numpy.dtype): Data type for the arrays. np.float32 by default. Example: np.float64 or np.float16. [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not reccomended!] (optional)
|
253
|
+
|
202
254
|
Returns:
|
203
255
|
tuple: A list for model parameters: [Weight matrix, Test loss, Test Accuracy, [Activations functions]].
|
204
256
|
|
205
257
|
"""
|
206
|
-
|
258
|
+
|
259
|
+
print(Fore.WHITE + "\nRemember, optimization on large datasets can be very time-consuming and computationally expensive. Therefore, if you are working with such a dataset, our recommendation is to include activation function: ['circular', 'spiral'] in the 'except_this' parameter unless absolutely necessary, as they can significantly prolong the process. from: learner\n" + Fore.RESET)
|
207
260
|
|
208
261
|
activation_potentiation = all_activations()
|
209
262
|
|
263
|
+
# Pre-checks
|
264
|
+
|
265
|
+
x_train = x_train.astype(dtype, copy=False)
|
266
|
+
y_train = optimize_labels(y_train, cuda=False)
|
267
|
+
|
210
268
|
if x_test is None and y_test is None:
|
211
269
|
x_test = x_train
|
212
270
|
y_test = y_train
|
213
271
|
data = 'Train'
|
214
272
|
else:
|
273
|
+
x_test = x_test.astype(dtype, copy=False)
|
274
|
+
y_test = optimize_labels(y_test, cuda=False)
|
215
275
|
data = 'Test'
|
216
276
|
|
217
|
-
if early_shifting != False:
|
218
|
-
shift_patience = early_shifting
|
219
|
-
|
220
|
-
# Strategy initialization
|
221
|
-
if strategy == 'adaptive_accuracy':
|
222
|
-
strategy = 'accuracy'
|
223
|
-
adaptive = True
|
224
|
-
if patience == None:
|
225
|
-
patience = 5
|
226
|
-
elif strategy == 'adaptive_loss':
|
227
|
-
strategy = 'loss'
|
228
|
-
adaptive = True
|
229
|
-
if patience == None:
|
230
|
-
patience = 0.150
|
231
|
-
else:
|
232
|
-
adaptive = False
|
233
|
-
|
234
277
|
# Filter activation functions
|
235
|
-
if only_this
|
278
|
+
if only_this is not None:
|
236
279
|
activation_potentiation = only_this
|
237
|
-
if except_this
|
280
|
+
if except_this is not None:
|
238
281
|
activation_potentiation = [item for item in activation_potentiation if item not in except_this]
|
239
|
-
if
|
240
|
-
|
282
|
+
if gen is None:
|
283
|
+
gen = len(activation_potentiation)
|
284
|
+
|
285
|
+
if strategy != 'accuracy' and strategy != 'f1' and strategy != 'recall' and strategy != 'precision': raise ValueError("Strategy parameter only be 'accuracy' or 'f1' or 'recall' or 'precision'.")
|
241
286
|
|
287
|
+
if start_this_act is None and len(activation_potentiation) % 2 != 0: raise ValueError("Activation length must be even number. Please use 'except_this' parameter and except some activation. For example: except_this=['linear']")
|
288
|
+
if start_this_act is not None and len(activation_potentiation) + 1 % 2 != 0: raise ValueError("You are using start_this parameter, activation length still must be even number. Please use 'except_this' parameter and except some activation. For example: except_this=['linear']")
|
289
|
+
|
242
290
|
# Initialize visualization components
|
243
291
|
viz_objects = initialize_visualization_for_learner(show_history, neurons_history, neural_web_history, x_train, y_train)
|
244
292
|
|
@@ -247,18 +295,20 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
|
|
247
295
|
ncols = 76
|
248
296
|
else:
|
249
297
|
ncols = 89
|
250
|
-
progress = initialize_loading_bar(total=len(activation_potentiation), desc="", ncols=ncols, bar_format=bar_format_learner)
|
251
298
|
|
252
299
|
# Initialize variables
|
253
|
-
|
254
|
-
|
255
|
-
|
300
|
+
act_pop = []
|
301
|
+
weight_pop = []
|
302
|
+
|
303
|
+
if start_this_act is None and start_this_W is None:
|
256
304
|
best_acc = 0
|
257
305
|
else:
|
258
|
-
|
306
|
+
act_pop.append(start_this_act)
|
307
|
+
weight_pop.append(start_this_W)
|
308
|
+
|
259
309
|
x_test_batch, y_test_batch = batcher(x_test, y_test, batch_size=batch_size)
|
260
|
-
|
261
|
-
model = evaluate(x_test_batch, y_test_batch, W=
|
310
|
+
|
311
|
+
model = evaluate(x_test_batch, y_test_batch, W=start_this_W, loading_bar_status=False, activation_potentiation=act_pop, dtype=dtype)
|
262
312
|
|
263
313
|
if loss == 'categorical_crossentropy':
|
264
314
|
test_loss = categorical_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
|
@@ -268,12 +318,15 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
|
|
268
318
|
best_acc = model[get_acc()]
|
269
319
|
best_loss = test_loss
|
270
320
|
|
271
|
-
|
321
|
+
best_acc_per_gen_list = []
|
272
322
|
postfix_dict = {}
|
273
323
|
loss_list = []
|
274
|
-
|
275
|
-
|
276
|
-
|
324
|
+
target_pop = []
|
325
|
+
|
326
|
+
progress = initialize_loading_bar(total=len(activation_potentiation), desc="", ncols=ncols, bar_format=bar_format_learner)
|
327
|
+
|
328
|
+
for i in range(gen):
|
329
|
+
postfix_dict["Gen"] = str(i+1) + '/' + str(gen)
|
277
330
|
progress.set_postfix(postfix_dict)
|
278
331
|
|
279
332
|
progress.n = 0
|
@@ -281,79 +334,65 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
|
|
281
334
|
progress.update(0)
|
282
335
|
|
283
336
|
for j in range(len(activation_potentiation)):
|
284
|
-
for k in range(len(best_activations)):
|
285
|
-
activations.append(best_activations[k])
|
286
|
-
|
287
|
-
activations.append(activation_potentiation[j])
|
288
337
|
|
289
338
|
x_test_batch, y_test_batch = batcher(x_test, y_test, batch_size=batch_size)
|
290
|
-
|
291
|
-
|
339
|
+
|
340
|
+
if i == 0:
|
341
|
+
act_pop.append(activation_potentiation[j])
|
342
|
+
W = fit(x_train, y_train, activation_potentiation=act_pop[-1], train_bar=False, auto_normalization=auto_normalization, dtype=dtype)
|
343
|
+
weight_pop.append(W)
|
292
344
|
|
345
|
+
model = evaluate(x_test_batch, y_test_batch, W=weight_pop[j], loading_bar_status=False, activation_potentiation=act_pop[j], dtype=dtype)
|
293
346
|
acc = model[get_acc()]
|
347
|
+
|
348
|
+
if strategy == 'accuracy': target_pop.append(acc)
|
294
349
|
|
295
|
-
|
296
|
-
if loss == 'categorical_crossentropy':
|
297
|
-
test_loss = categorical_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
|
298
|
-
else:
|
299
|
-
test_loss = binary_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
|
300
|
-
|
301
|
-
if i == 0 and j == 0 and start_this is None:
|
302
|
-
best_loss = test_loss
|
303
|
-
|
304
|
-
if strategy == 'f1' or strategy == 'precision' or strategy == 'recall' or strategy == 'all':
|
350
|
+
elif strategy == 'f1' or strategy == 'precision' or strategy == 'recall':
|
305
351
|
precision_score, recall_score, f1_score = metrics(y_test_batch, model[get_preds()])
|
306
352
|
|
307
|
-
if strategy == 'precision'
|
353
|
+
if strategy == 'precision':
|
354
|
+
target_pop.append(precision_score)
|
355
|
+
|
308
356
|
if i == 0 and j == 0:
|
309
357
|
best_precision = precision_score
|
310
358
|
|
311
|
-
if strategy == 'recall'
|
359
|
+
if strategy == 'recall':
|
360
|
+
target_pop.append(recall_score)
|
361
|
+
|
312
362
|
if i == 0 and j == 0:
|
313
363
|
best_recall = recall_score
|
314
364
|
|
315
|
-
if strategy == 'f1'
|
365
|
+
if strategy == 'f1':
|
366
|
+
target_pop.append(f1_score)
|
367
|
+
|
316
368
|
if i == 0 and j == 0:
|
317
369
|
best_f1 = f1_score
|
318
370
|
|
319
|
-
if early_shifting != False:
|
320
|
-
if acc <= best_acc:
|
321
|
-
early_shifting -= 1
|
322
|
-
if early_shifting == 0:
|
323
|
-
early_shifting = shift_patience
|
324
|
-
break
|
325
|
-
|
326
371
|
if ((strategy == 'accuracy' and acc >= best_acc) or
|
327
|
-
(strategy == 'loss' and test_loss <= best_loss) or
|
328
372
|
(strategy == 'f1' and f1_score >= best_f1) or
|
329
|
-
(strategy == 'precision' and precision_score >= best_precision) or
|
330
|
-
(strategy == 'recall' and recall_score >= best_recall)
|
331
|
-
(strategy == 'all' and f1_score >= best_f1 and acc >= best_acc and
|
332
|
-
test_loss <= best_loss and precision_score >= best_precision and
|
333
|
-
recall_score >= best_recall)):
|
373
|
+
(strategy == 'precision' and precision_score >= best_precision) or
|
374
|
+
(strategy == 'recall' and recall_score >= best_recall)):
|
334
375
|
|
335
|
-
current_best_activation = activation_potentiation[j]
|
336
376
|
best_acc = acc
|
337
|
-
|
377
|
+
best_weights = weight_pop[j]
|
378
|
+
final_activations = act_pop[j]
|
379
|
+
best_model = model
|
380
|
+
|
381
|
+
final_activations = [final_activations[0]] if len(set(final_activations)) == 1 else final_activations # removing if all same
|
382
|
+
|
338
383
|
if batch_size == 1:
|
339
384
|
postfix_dict[f"{data} Accuracy"] = best_acc
|
340
385
|
else:
|
341
386
|
postfix_dict[f"{data} Batch Accuracy"] = acc
|
342
387
|
progress.set_postfix(postfix_dict)
|
343
|
-
|
344
|
-
final_activations = activations
|
345
388
|
|
346
389
|
if show_current_activations:
|
347
390
|
print(f", Current Activations={final_activations}", end='')
|
348
391
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
if loss == 'categorical_crossentropy':
|
354
|
-
test_loss = categorical_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
|
355
|
-
else:
|
356
|
-
test_loss = binary_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
|
392
|
+
if loss == 'categorical_crossentropy':
|
393
|
+
test_loss = categorical_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
|
394
|
+
else:
|
395
|
+
test_loss = binary_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
|
357
396
|
|
358
397
|
if batch_size == 1:
|
359
398
|
postfix_dict[f"{data} Loss"] = test_loss
|
@@ -365,13 +404,13 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
|
|
365
404
|
|
366
405
|
# Update visualizations during training
|
367
406
|
if show_history:
|
368
|
-
|
369
|
-
update_history_plots_for_learner(viz_objects,
|
370
|
-
|
407
|
+
gen_list = range(1, len(best_acc_per_gen_list) + 2)
|
408
|
+
update_history_plots_for_learner(viz_objects, gen_list, loss_list + [test_loss],
|
409
|
+
best_acc_per_gen_list + [best_acc], x_train, final_activations)
|
371
410
|
|
372
411
|
if neurons_history:
|
373
412
|
viz_objects['neurons']['artists'] = (
|
374
|
-
|
413
|
+
update_neuron_history_for_learner(np.copy(best_weights), viz_objects['neurons']['ax'],
|
375
414
|
viz_objects['neurons']['row'], viz_objects['neurons']['col'],
|
376
415
|
y_train[0], viz_objects['neurons']['artists'],
|
377
416
|
data=data, fig1=viz_objects['neurons']['fig'],
|
@@ -388,7 +427,7 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
|
|
388
427
|
if target_acc is not None and best_acc >= target_acc:
|
389
428
|
progress.close()
|
390
429
|
train_model = evaluate(x_train, y_train, W=best_weights, loading_bar_status=False,
|
391
|
-
activation_potentiation=final_activations)
|
430
|
+
activation_potentiation=final_activations, dtype=dtype)
|
392
431
|
|
393
432
|
if loss == 'categorical_crossentropy':
|
394
433
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -413,7 +452,7 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
|
|
413
452
|
if target_loss is not None and best_loss <= target_loss:
|
414
453
|
progress.close()
|
415
454
|
train_model = evaluate(x_train, y_train, W=best_weights, loading_bar_status=False,
|
416
|
-
activation_potentiation=final_activations)
|
455
|
+
activation_potentiation=final_activations, dtype=dtype)
|
417
456
|
|
418
457
|
if loss == 'categorical_crossentropy':
|
419
458
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -435,28 +474,19 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
|
|
435
474
|
return best_weights, best_model[get_preds()], best_acc, final_activations
|
436
475
|
|
437
476
|
progress.update(1)
|
438
|
-
activations = []
|
439
477
|
|
440
|
-
|
441
|
-
best_acc_per_depth_list.append(best_acc)
|
478
|
+
best_acc_per_gen_list.append(best_acc)
|
442
479
|
loss_list.append(best_loss)
|
443
480
|
|
444
|
-
|
445
|
-
|
446
|
-
check = best_acc_per_depth_list[-patience:]
|
447
|
-
if all(x == check[0] for x in check):
|
448
|
-
strategy = 'loss'
|
449
|
-
adaptive = False
|
450
|
-
elif adaptive == True and strategy == 'loss' and best_loss <= patience:
|
451
|
-
strategy = 'accuracy'
|
452
|
-
adaptive = False
|
481
|
+
weight_pop, act_pop = optimizer(np.array(weight_pop, dtype=dtype), act_pop, i, np.array(target_pop, dtype=dtype, copy=False), target_fitness=target_fitness, bar_status=False)
|
482
|
+
target_pop = []
|
453
483
|
|
454
484
|
# Early stopping check
|
455
485
|
if early_stop == True and i > 0:
|
456
|
-
if
|
486
|
+
if best_acc_per_gen_list[i] == best_acc_per_gen_list[i-1]:
|
457
487
|
progress.close()
|
458
488
|
train_model = evaluate(x_train, y_train, W=best_weights, loading_bar_status=False,
|
459
|
-
activation_potentiation=final_activations)
|
489
|
+
activation_potentiation=final_activations, dtype=dtype)
|
460
490
|
|
461
491
|
if loss == 'categorical_crossentropy':
|
462
492
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -480,14 +510,14 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
|
|
480
510
|
# Final evaluation
|
481
511
|
progress.close()
|
482
512
|
train_model = evaluate(x_train, y_train, W=best_weights, loading_bar_status=False,
|
483
|
-
activation_potentiation=final_activations)
|
513
|
+
activation_potentiation=final_activations, dtype=dtype)
|
484
514
|
|
485
515
|
if loss == 'categorical_crossentropy':
|
486
516
|
train_loss = categorical_crossentropy(y_true_batch=y_train, y_pred_batch=train_model[get_preds_softmax()])
|
487
517
|
else:
|
488
518
|
train_loss = binary_crossentropy(y_true_batch=y_train, y_pred_batch=train_model[get_preds_softmax()])
|
489
519
|
|
490
|
-
print('\nActivations: ',
|
520
|
+
print('\nActivations: ', act_pop[-1])
|
491
521
|
print(f'Train Accuracy (%{batch_size * 100} of train samples):', train_model[get_acc()])
|
492
522
|
print(f'Train Loss (%{batch_size * 100} of train samples): ', train_loss, '\n')
|
493
523
|
if data == 'Test':
|
@@ -547,99 +577,88 @@ def feed_forward(
|
|
547
577
|
|
548
578
|
|
549
579
|
def evaluate(
|
550
|
-
x_test, #
|
551
|
-
y_test, #
|
552
|
-
W,
|
553
|
-
activation_potentiation=['linear'], #
|
554
|
-
loading_bar_status=True, #
|
555
|
-
show_metrics=None,
|
580
|
+
x_test, # NumPy array: Test input data.
|
581
|
+
y_test, # NumPy array: Test labels.
|
582
|
+
W, # List of NumPy arrays: Neural network weight matrices.
|
583
|
+
activation_potentiation=['linear'], # List of activation functions.
|
584
|
+
loading_bar_status=True, # Optionally show loading bar.
|
585
|
+
show_metrics=None, # Optionally show metrics.
|
586
|
+
dtype=np.float32
|
556
587
|
) -> tuple:
|
557
588
|
"""
|
558
|
-
|
589
|
+
Evaluates the neural network model using the given test data.
|
559
590
|
|
560
591
|
Args:
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
592
|
+
x_test (np.ndarray): Test input data.
|
593
|
+
|
594
|
+
y_test (np.ndarray): Test labels. one-hot encoded.
|
595
|
+
|
596
|
+
W (list[np.ndarray]): List of neural network weight matrices.
|
597
|
+
|
598
|
+
activation_potentiation (list): List of activation functions.
|
599
|
+
|
600
|
+
loading_bar_status (bool): Option to show a loading bar (optional).
|
601
|
+
|
602
|
+
show_metrics (bool): Option to show metrics (optional).
|
571
603
|
|
572
|
-
|
604
|
+
dtype (numpy.dtype): Data type for the arrays. np.float32 by default. Example: np.float64 or np.float16. [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not reccomended!]
|
573
605
|
|
574
606
|
Returns:
|
575
|
-
tuple:
|
607
|
+
tuple: Predicted labels, model accuracy, and other evaluation metrics.
|
576
608
|
"""
|
577
|
-
|
578
|
-
real_classes = []
|
579
|
-
predict_classes = []
|
580
|
-
|
581
|
-
try:
|
609
|
+
# Pre-checks
|
582
610
|
|
583
|
-
|
584
|
-
true_predict = 0
|
585
|
-
y_preds = []
|
586
|
-
y_preds_raw = []
|
587
|
-
acc_list = []
|
611
|
+
x_test = x_test.astype(dtype, copy=False)
|
588
612
|
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
613
|
+
if len(y_test[0]) < 256:
|
614
|
+
if y_test.dtype != np.uint8:
|
615
|
+
y_test = np.array(y_test, copy=False).astype(np.uint8, copy=False)
|
616
|
+
elif len(y_test[0]) <= 32767:
|
617
|
+
if y_test.dtype != np.uint16:
|
618
|
+
y_test = np.array(y_test, copy=False).astype(np.uint16, copy=False)
|
619
|
+
else:
|
620
|
+
if y_test.dtype != np.uint32:
|
621
|
+
y_test = np.array(y_test, copy=False).astype(np.uint32, copy=False)
|
593
622
|
|
594
|
-
|
623
|
+
predict_probabilitys = np.empty((len(x_test), W.shape[0]), dtype=np.float32)
|
624
|
+
real_classes = np.empty(len(x_test), dtype=np.int32)
|
625
|
+
predict_classes = np.empty(len(x_test), dtype=np.int32)
|
595
626
|
|
596
|
-
|
597
|
-
|
598
|
-
Input = Input.ravel()
|
599
|
-
neural_layer = Input
|
627
|
+
true_predict = 0
|
628
|
+
acc_list = np.empty(len(x_test), dtype=np.float32)
|
600
629
|
|
601
|
-
|
602
|
-
|
630
|
+
if loading_bar_status:
|
631
|
+
loading_bar = initialize_loading_bar(total=len(x_test), ncols=64, desc='Testing', bar_format=bar_format_normal)
|
603
632
|
|
633
|
+
for inpIndex in range(len(x_test)):
|
634
|
+
Input = x_test[inpIndex].ravel()
|
604
635
|
|
605
|
-
|
606
|
-
|
607
|
-
neural_layer = Softmax(neural_layer)
|
636
|
+
neural_layer = Input
|
608
637
|
|
609
|
-
|
638
|
+
neural_layer = feed_forward(neural_layer, np.copy(W), is_training=False, Class='?', activation_potentiation=activation_potentiation)
|
610
639
|
|
611
|
-
|
612
|
-
|
613
|
-
RealOutput = np.argmax(y_test[inpIndex])
|
614
|
-
real_classes.append(RealOutput)
|
615
|
-
PredictedOutput = np.argmax(neural_layer)
|
616
|
-
predict_classes.append(PredictedOutput)
|
617
|
-
|
618
|
-
if RealOutput == PredictedOutput:
|
619
|
-
true_predict += 1
|
620
|
-
acc = true_predict / len(y_test)
|
640
|
+
predict_probabilitys[inpIndex] = Softmax(neural_layer)
|
621
641
|
|
642
|
+
RealOutput = np.argmax(y_test[inpIndex])
|
643
|
+
real_classes[inpIndex] = RealOutput
|
644
|
+
PredictedOutput = np.argmax(neural_layer)
|
645
|
+
predict_classes[inpIndex] = PredictedOutput
|
622
646
|
|
623
|
-
|
624
|
-
|
625
|
-
y_preds_raw.append(Softmax(neural_layer))
|
647
|
+
if RealOutput == PredictedOutput:
|
648
|
+
true_predict += 1
|
626
649
|
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
if inpIndex > 0 and loading_bar_status == True:
|
631
|
-
loading_bar.set_postfix({"Test Accuracy": acc})
|
650
|
+
acc = true_predict / (inpIndex + 1)
|
651
|
+
acc_list[inpIndex] = acc
|
632
652
|
|
633
|
-
if
|
634
|
-
|
635
|
-
loading_bar.
|
636
|
-
plot_evaluate(x_test, y_test, y_preds, acc_list, W=W, activation_potentiation=activation_potentiation)
|
637
|
-
|
638
|
-
W = np.copy(Wc)
|
653
|
+
if loading_bar_status:
|
654
|
+
loading_bar.update(1)
|
655
|
+
loading_bar.set_postfix({"Test Accuracy": acc})
|
639
656
|
|
640
|
-
|
657
|
+
if loading_bar_status:
|
658
|
+
loading_bar.close()
|
641
659
|
|
642
|
-
|
643
|
-
|
660
|
+
if show_metrics:
|
661
|
+
# Plot the evaluation metrics
|
662
|
+
plot_evaluate(x_test, y_test, predict_classes, acc_list, W=np.copy(W), activation_potentiation=activation_potentiation)
|
644
663
|
|
645
|
-
return W,
|
664
|
+
return W, predict_classes, acc_list[-1], None, None, predict_probabilitys
|