pyerualjetwork 5.0.3__py3-none-any.whl → 5.2__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 +3 -3
- pyerualjetwork/activation_functions_cpu.py +3 -71
- pyerualjetwork/activation_functions_cuda.py +2 -74
- pyerualjetwork/data_operations_cpu.py +3 -5
- pyerualjetwork/ene_cuda.py +5 -5
- pyerualjetwork/fitness_functions.py +0 -1
- pyerualjetwork/issue_solver.py +1 -1
- pyerualjetwork/model_operations_cpu.py +123 -55
- pyerualjetwork/model_operations_cuda.py +120 -51
- pyerualjetwork/neu_cpu.py +169 -52
- pyerualjetwork/neu_cuda.py +170 -55
- {pyerualjetwork-5.0.3.dist-info → pyerualjetwork-5.2.dist-info}/METADATA +3 -3
- pyerualjetwork-5.2.dist-info/RECORD +26 -0
- pyerualjetwork-5.0.3.dist-info/RECORD +0 -26
- {pyerualjetwork-5.0.3.dist-info → pyerualjetwork-5.2.dist-info}/WHEEL +0 -0
- {pyerualjetwork-5.0.3.dist-info → pyerualjetwork-5.2.dist-info}/top_level.txt +0 -0
pyerualjetwork/neu_cpu.py
CHANGED
@@ -6,10 +6,27 @@ NEU (Neural Networks) on CPU
|
|
6
6
|
============================
|
7
7
|
This module hosts functions for training and evaluating artificial neural networks on CPU for labeled classification tasks (for now).
|
8
8
|
|
9
|
-
Currently,
|
9
|
+
Currently, 3 types of models can be trained:
|
10
10
|
|
11
11
|
PLAN (Potentiation Learning Artificial Neural Network)
|
12
|
+
* Training Time for Small Projects: fast
|
13
|
+
* Training Time for Big Projects: fast
|
14
|
+
* Explainability: high
|
15
|
+
* Learning Capacity: medium (compared to single perceptrons)
|
16
|
+
|
12
17
|
MLP (Multi-Layer Perceptron → Deep Learning) -- With non-bias
|
18
|
+
* Training Time for Small Projects: fast
|
19
|
+
* Training Time for Big Projects: slow
|
20
|
+
* Explainability: low
|
21
|
+
* Learning Capacity: high
|
22
|
+
|
23
|
+
PTNN (Potentiation Transfer Neural Network) -- With non-bias
|
24
|
+
* Training Time for Small Projects: fast
|
25
|
+
* Training Time for Big Projects: fast
|
26
|
+
* Explainability: low
|
27
|
+
* Learning Capacity: high
|
28
|
+
|
29
|
+
Read learn function docstring for know how to use of these model architectures.
|
13
30
|
|
14
31
|
For more information about PLAN: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PLAN/PLAN.pdf
|
15
32
|
|
@@ -32,6 +49,7 @@ PyerualJetwork document: https://github.com/HCB06/PyerualJetwork/blob/main/Welco
|
|
32
49
|
|
33
50
|
import numpy as np
|
34
51
|
import copy
|
52
|
+
import random
|
35
53
|
|
36
54
|
### LIBRARY IMPORTS ###
|
37
55
|
from .ui import loading_bars, initialize_loading_bar
|
@@ -98,23 +116,26 @@ def plan_fit(
|
|
98
116
|
return normalization(weight, dtype=dtype)
|
99
117
|
|
100
118
|
|
101
|
-
def learn(x_train, y_train, optimizer, fit_start=True,
|
119
|
+
def learn(x_train, y_train, optimizer, gen, pop_size, fit_start=True, batch_size=1,
|
102
120
|
weight_evolve=True, neural_web_history=False, show_current_activations=False, auto_normalization=False,
|
103
121
|
neurons_history=False, early_stop=False, show_history=False, target_loss=None,
|
104
122
|
interval=33.33, target_acc=None, loss='categorical_crossentropy', acc_impact=0.9, loss_impact=0.1,
|
105
123
|
start_this_act=None, start_this_W=None, neurons=[], activation_functions=[], dtype=np.float32):
|
106
124
|
"""
|
107
125
|
Optimizes the activation functions for a neural network by leveraging train data to find
|
108
|
-
the most accurate combination of activation potentiation(or activation function) & weight values for the
|
126
|
+
the most accurate combination of activation potentiation(or activation function) & weight values for the labeled classificaiton dataset.
|
109
127
|
|
110
128
|
Why genetic optimization ENE(Eugenic NeuroEvolution) and not backpropagation?
|
111
129
|
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.
|
112
130
|
Since activation functions are not differentiable, we cannot use gradient descent or backpropagation. However, I developed a more powerful genetic optimization algorithm: ENE.
|
113
131
|
|
132
|
+
* This function also able to train classic MLP model architectures.
|
133
|
+
* And my newest innovative architecture: PTNN (Potentiation Transfer Neural Network).
|
134
|
+
|
114
135
|
:Args:
|
115
136
|
:param x_train: (array-like): Training input data.
|
116
137
|
:param y_train: (array-like): Labels for training data. one-hot encoded.
|
117
|
-
:param optimizer: (function): Optimization technique with hyperparameters. (PLAN
|
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.ene_cpu import evolver (and) optimizer = lambda *args, **kwargs: evolver(*args, 'here give your hyperparameters for example: activation_add_prob=0.85', **kwargs) Example:
|
118
139
|
```python
|
119
140
|
optimizer = lambda *args, **kwargs: ene_cpu.evolver(*args,
|
120
141
|
activation_add_prob=0.05,
|
@@ -131,11 +152,11 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
131
152
|
batch_size=0.05,
|
132
153
|
interval=16.67)
|
133
154
|
```
|
134
|
-
: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. Options: True or False. Default: True
|
135
|
-
:param gen: (int
|
155
|
+
: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
|
+
: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.
|
136
157
|
: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)
|
137
|
-
:param pop_size: (int
|
138
|
-
:param weight_evolve: (bool, optional): Activation combinations already optimizes by
|
158
|
+
:param pop_size: (int): Population size of each generation.
|
159
|
+
:param weight_evolve: (bool, optional): Activation combinations already optimizes by ENE genetic search algorithm. Should the weight parameters also evolve or should the weights be determined according to the aggregating learning principle of the PLAN algorithm? Default: True (Evolves Weights)
|
139
160
|
:param neural_web_history: (bool, optional): Draws history of neural web. Default is False. [ONLY FOR PLAN MODELS]
|
140
161
|
:param 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
|
141
162
|
:param auto_normalization: (bool, optional): Normalization may solves overflow problem. Default: False
|
@@ -150,8 +171,8 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
150
171
|
:param loss_impact: (float, optional): Impact of loss for optimization [0-1]. Default: 0.1
|
151
172
|
: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
|
152
173
|
: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
|
153
|
-
:param neurons: (list[int], optional): If you dont want train PLAN model this parameter represents neuron count of each hidden layer for MLP. Number of elements --> Layer count. Default: [] (No hidden layer) --> architecture setted to PLAN, if not --> architecture setted to MLP.
|
154
|
-
:param activation_functions: (list[str], optional): If you dont want train PLAN model this parameter represents activation function of each hidden layer for MLP. if neurons is not [] --> uses default: ['linear'] * len(neurons). if neurons is [] --> uses [].
|
174
|
+
: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.
|
175
|
+
: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 [].
|
155
176
|
:param dtype: (numpy.dtype): Data type for the Weight matrices. np.float32 by default. Example: np.float64 or np.float16.
|
156
177
|
|
157
178
|
Returns:
|
@@ -165,28 +186,58 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
165
186
|
except_this = ['spiral', 'circular']
|
166
187
|
activations = [item for item in all_activations() if item not in except_this]
|
167
188
|
activations_len = len(activations)
|
168
|
-
|
189
|
+
|
169
190
|
# Pre-checks
|
170
191
|
|
171
|
-
if pop_size
|
192
|
+
if pop_size > activations_len and fit_start is True:
|
193
|
+
for _ in range(pop_size - len(activations)):
|
194
|
+
random_index_all_act = random.randint(0, len(activations)-1)
|
195
|
+
activations.append(activations[random_index_all_act])
|
196
|
+
|
172
197
|
y_train = optimize_labels(y_train, cuda=False)
|
173
198
|
|
174
199
|
if pop_size < activations_len: raise ValueError(f"pop_size must be higher or equal to {activations_len}")
|
175
200
|
|
176
|
-
if gen is None: gen = activations_len
|
177
|
-
|
178
201
|
if target_acc is not None and (target_acc < 0 or target_acc > 1): raise ValueError('target_acc must be in range 0 and 1')
|
179
202
|
if fit_start is not True and fit_start is not False: raise ValueError('fit_start parameter only be True or False. Please read doc-string')
|
180
203
|
|
181
204
|
if neurons != []:
|
182
|
-
fit_start = False
|
183
205
|
weight_evolve = True
|
184
|
-
|
206
|
+
|
185
207
|
if activation_functions == []: activation_functions = ['linear'] * len(neurons)
|
186
|
-
|
208
|
+
|
209
|
+
if fit_start is False:
|
210
|
+
# MLP
|
211
|
+
activations = activation_functions
|
212
|
+
model_type = 'MLP'
|
213
|
+
activation_potentiations = [0] * pop_size
|
214
|
+
activation_potentiation = None
|
215
|
+
is_mlp = True
|
216
|
+
transfer_learning = False
|
217
|
+
else:
|
218
|
+
# PTNN
|
219
|
+
model_type = 'PLAN' # First generation index gen[0] is PLAN, other index gen[1] it will change to PTNN (PLAN Connects to MLP and will transfer the learned information).
|
220
|
+
transfer_learning = True
|
221
|
+
|
222
|
+
neurons_copy = neurons.copy()
|
223
|
+
neurons = []
|
224
|
+
gen_copy = gen.copy()
|
225
|
+
gen = gen[0] + gen[1]
|
226
|
+
activation_potentiations = [0] * pop_size
|
227
|
+
activation_potentiation = None
|
228
|
+
is_mlp = False # it will change
|
229
|
+
|
187
230
|
else:
|
231
|
+
# PLAN
|
232
|
+
model_type = 'PLAN'
|
233
|
+
transfer_learning = False
|
234
|
+
|
235
|
+
activation_potentiations = [0] * pop_size # NOTE: For PLAN models, activation_potentiations is needed BUT activations variable already mirros activation_potentiation values.
|
236
|
+
# So, we don't need to use activation_potentiations variable. activation_potentiations variable is only for PTNN models.
|
237
|
+
activation_potentiation = None
|
188
238
|
is_mlp = False
|
189
239
|
|
240
|
+
|
190
241
|
# Initialize visualization components
|
191
242
|
viz_objects = initialize_visualization_for_learner(show_history, neurons_history, neural_web_history, x_train, y_train)
|
192
243
|
|
@@ -201,12 +252,12 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
201
252
|
|
202
253
|
progress = initialize_loading_bar(total=activations_len, desc="", ncols=77, bar_format=bar_format_learner)
|
203
254
|
|
204
|
-
if fit_start is False
|
205
|
-
weight_pop, act_pop = define_genomes(input_shape=len(x_train[0]), output_shape=len(y_train[0]), neurons=neurons, activation_functions=
|
255
|
+
if fit_start is False:
|
256
|
+
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)
|
206
257
|
|
207
258
|
else:
|
208
|
-
weight_pop = [0] *
|
209
|
-
act_pop = [0] *
|
259
|
+
weight_pop = [0] * len(activations)
|
260
|
+
act_pop = [0] * len(activations)
|
210
261
|
|
211
262
|
if start_this_act is not None and start_this_W is not None:
|
212
263
|
weight_pop[0] = start_this_W
|
@@ -214,6 +265,41 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
214
265
|
|
215
266
|
# LEARNING STARTED
|
216
267
|
for i in range(gen):
|
268
|
+
|
269
|
+
# TRANSFORMATION PLAN TO MLP FOR PTNN (in later generations)
|
270
|
+
if model_type == 'PLAN' and transfer_learning:
|
271
|
+
if i == gen_copy[0]:
|
272
|
+
|
273
|
+
model_type = 'PTNN'
|
274
|
+
neurons = neurons_copy
|
275
|
+
|
276
|
+
for individual in range(len(weight_pop)):
|
277
|
+
weight_pop[individual] = np.copy(best_weight)
|
278
|
+
activation_potentiations[individual] = final_activations.copy() if isinstance(final_activations, list) else final_activations
|
279
|
+
|
280
|
+
activation_potentiation = activation_potentiations[0]
|
281
|
+
|
282
|
+
neurons_copy = [len(y_train[0])] + neurons_copy
|
283
|
+
activation_functions = ['linear'] + activation_functions
|
284
|
+
|
285
|
+
weight_pop, act_pop = define_genomes(input_shape=len(x_train[0]), output_shape=len(y_train[0]), neurons=neurons_copy, activation_functions=activation_functions, population_size=pop_size, dtype=dtype)
|
286
|
+
|
287
|
+
# 0 indexed individual will keep PLAN's learned informations and in later generations it will share other individuals.
|
288
|
+
for l in range(1, len(weight_pop[0])):
|
289
|
+
original_shape = weight_pop[0][l].shape
|
290
|
+
|
291
|
+
identity_matrix = np.eye(original_shape[0], original_shape[1], dtype=weight_pop[0][l].dtype)
|
292
|
+
weight_pop[0][l] = identity_matrix
|
293
|
+
|
294
|
+
for l in range(len(weight_pop)):
|
295
|
+
weight_pop[l][0] = np.copy(best_weight)
|
296
|
+
|
297
|
+
best_weight = np.array(weight_pop[0], dtype=object)
|
298
|
+
final_activations = act_pop[0]
|
299
|
+
is_mlp = True
|
300
|
+
fit_start = False
|
301
|
+
|
302
|
+
|
217
303
|
postfix_dict["Gen"] = str(i+1) + '/' + str(gen)
|
218
304
|
progress.set_postfix(postfix_dict)
|
219
305
|
|
@@ -225,18 +311,21 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
225
311
|
|
226
312
|
x_train_batch, y_train_batch = batcher(x_train, y_train, batch_size=batch_size)
|
227
313
|
|
228
|
-
if fit_start is True and i == 0
|
314
|
+
if fit_start is True and i == 0:
|
229
315
|
if start_this_act is not None and j == 0:
|
230
316
|
pass
|
231
317
|
else:
|
318
|
+
|
232
319
|
act_pop[j] = activations[j]
|
233
320
|
W = plan_fit(x_train_batch, y_train_batch, activations=act_pop[j], auto_normalization=auto_normalization, dtype=dtype)
|
234
321
|
weight_pop[j] = W
|
235
|
-
|
322
|
+
|
323
|
+
|
236
324
|
if weight_evolve is False:
|
237
325
|
weight_pop[j] = plan_fit(x_train_batch, y_train_batch, activations=act_pop[j], auto_normalization=auto_normalization, dtype=dtype)
|
238
326
|
|
239
|
-
|
327
|
+
|
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)
|
240
329
|
acc = model[get_acc()]
|
241
330
|
|
242
331
|
if loss == 'categorical_crossentropy':
|
@@ -246,7 +335,7 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
246
335
|
train_loss = binary_crossentropy(y_true_batch=y_train_batch,
|
247
336
|
y_pred_batch=model[get_preds_softmax()])
|
248
337
|
|
249
|
-
fitness
|
338
|
+
fitness = wals(acc, train_loss, acc_impact, loss_impact)
|
250
339
|
target_pop.append(fitness)
|
251
340
|
|
252
341
|
if fitness >= best_fitness:
|
@@ -254,11 +343,11 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
254
343
|
best_fitness = fitness
|
255
344
|
best_acc = acc
|
256
345
|
best_loss = train_loss
|
257
|
-
best_weight = np.copy(weight_pop[j]) if
|
346
|
+
best_weight = np.copy(weight_pop[j]) if model_type == 'PLAN' else copy.deepcopy(weight_pop[j])
|
258
347
|
best_model = model
|
259
348
|
|
260
349
|
final_activations = act_pop[j].copy() if isinstance(act_pop[j], list) else act_pop[j]
|
261
|
-
if
|
350
|
+
if model_type == 'PLAN': final_activations = [final_activations[0]] if len(set(final_activations)) == 1 else final_activations # removing if all same
|
262
351
|
|
263
352
|
if batch_size == 1:
|
264
353
|
postfix_dict[f"{data} Accuracy"] = np.round(best_acc, 4)
|
@@ -293,7 +382,7 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
293
382
|
if target_acc is not None and best_acc >= target_acc:
|
294
383
|
progress.close()
|
295
384
|
train_model = evaluate(x_train, y_train, W=best_weight,
|
296
|
-
activations=final_activations, auto_normalization=auto_normalization,
|
385
|
+
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, model_type=model_type)
|
297
386
|
if loss == 'categorical_crossentropy':
|
298
387
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
299
388
|
y_pred_batch=train_model[get_preds_softmax()])
|
@@ -302,18 +391,20 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
302
391
|
y_pred_batch=train_model[get_preds_softmax()])
|
303
392
|
|
304
393
|
print('\nActivations: ', final_activations)
|
305
|
-
print(
|
306
|
-
print(
|
394
|
+
print('Activation Potentiation: ', activation_potentiation)
|
395
|
+
print('Train Accuracy:', train_model[get_acc()])
|
396
|
+
print('Train Loss: ', train_loss, '\n')
|
397
|
+
print('Model Type:', model_type)
|
307
398
|
|
308
399
|
display_visualizations_for_learner(viz_objects, best_weight, data, best_acc,
|
309
400
|
best_loss, y_train, interval)
|
310
|
-
return best_weight, best_model[get_preds_softmax()], best_acc, final_activations
|
401
|
+
return best_weight, best_model[get_preds_softmax()], best_acc, final_activations, None, None, None, None, None, None, None, activation_potentiation
|
311
402
|
|
312
403
|
# Check target loss
|
313
404
|
if target_loss is not None and best_loss <= target_loss:
|
314
405
|
progress.close()
|
315
406
|
train_model = evaluate(x_train, y_train, W=best_weight,
|
316
|
-
activations=final_activations, auto_normalization=auto_normalization,
|
407
|
+
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, model_type=model_type)
|
317
408
|
|
318
409
|
if loss == 'categorical_crossentropy':
|
319
410
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -323,19 +414,21 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
323
414
|
y_pred_batch=train_model[get_preds_softmax()])
|
324
415
|
|
325
416
|
print('\nActivations: ', final_activations)
|
326
|
-
print(
|
327
|
-
print(
|
417
|
+
print('Activation Potentiation: ', activation_potentiation)
|
418
|
+
print('Train Accuracy:', train_model[get_acc()])
|
419
|
+
print('Train Loss: ', train_loss, '\n')
|
420
|
+
print('Model Type:', model_type)
|
328
421
|
|
329
422
|
# Display final visualizations
|
330
423
|
display_visualizations_for_learner(viz_objects, best_weight, data, best_acc,
|
331
424
|
train_loss, y_train, interval)
|
332
|
-
return best_weight, best_model[get_preds_softmax()], best_acc, final_activations
|
425
|
+
return best_weight, best_model[get_preds_softmax()], best_acc, final_activations, None, None, None, None, None, None, None, activation_potentiation
|
333
426
|
|
334
427
|
|
335
428
|
progress.update(1)
|
336
429
|
|
337
430
|
if batch_size != 1:
|
338
|
-
train_model = evaluate(x_train, y_train, best_weight, final_activations, auto_normalization=auto_normalization,
|
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)
|
339
432
|
|
340
433
|
if loss == 'categorical_crossentropy':
|
341
434
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -355,7 +448,7 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
355
448
|
best_acc_per_gen_list.append(best_acc)
|
356
449
|
loss_list.append(best_loss)
|
357
450
|
|
358
|
-
if
|
451
|
+
if model_type == 'PLAN': weight_pop = np.array(weight_pop, copy=False, dtype=dtype)
|
359
452
|
else: weight_pop = np.array(weight_pop, copy=False, dtype=object)
|
360
453
|
|
361
454
|
weight_pop, act_pop = optimizer(weight_pop, act_pop, i, np.array(target_pop, dtype=dtype, copy=False), weight_evolve=weight_evolve, is_mlp=is_mlp, bar_status=False)
|
@@ -366,7 +459,7 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
366
459
|
if best_acc_per_gen_list[i] == best_acc_per_gen_list[i-1]:
|
367
460
|
progress.close()
|
368
461
|
train_model = evaluate(x_train, y_train, W=best_weight,
|
369
|
-
activations=final_activations, auto_normalization=auto_normalization,
|
462
|
+
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, model_type=model_type)
|
370
463
|
|
371
464
|
if loss == 'categorical_crossentropy':
|
372
465
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -376,19 +469,21 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
376
469
|
y_pred_batch=train_model[get_preds_softmax()])
|
377
470
|
|
378
471
|
print('\nActivations: ', final_activations)
|
379
|
-
print(
|
380
|
-
print(
|
472
|
+
print('Activation Potentiation: ', activation_potentiation)
|
473
|
+
print('Train Accuracy:', train_model[get_acc()])
|
474
|
+
print('Train Loss: ', train_loss, '\n')
|
475
|
+
print('Model Type:', model_type)
|
381
476
|
|
382
477
|
# Display final visualizations
|
383
478
|
display_visualizations_for_learner(viz_objects, best_weight, data, best_acc,
|
384
479
|
train_loss, y_train, interval)
|
385
|
-
return best_weight, best_model[get_preds_softmax()], best_acc, final_activations
|
480
|
+
return best_weight, best_model[get_preds_softmax()], best_acc, final_activations, None, None, None, None, None, None, None, activation_potentiation
|
386
481
|
|
387
482
|
# Final evaluation
|
388
483
|
progress.close()
|
389
484
|
|
390
485
|
train_model = evaluate(x_train, y_train, W=best_weight,
|
391
|
-
activations=final_activations, auto_normalization=auto_normalization,
|
486
|
+
activations=final_activations, activation_potentiations=activation_potentiation, auto_normalization=auto_normalization, model_type=model_type)
|
392
487
|
|
393
488
|
if loss == 'categorical_crossentropy':
|
394
489
|
train_loss = categorical_crossentropy(y_true_batch=y_train,
|
@@ -398,21 +493,24 @@ def learn(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, p
|
|
398
493
|
y_pred_batch=train_model[get_preds_softmax()])
|
399
494
|
|
400
495
|
print('\nActivations: ', final_activations)
|
401
|
-
print(
|
402
|
-
print(
|
496
|
+
print('Activation Potentiation: ', activation_potentiation)
|
497
|
+
print('Train Accuracy:', train_model[get_acc()])
|
498
|
+
print('Train Loss: ', train_loss, '\n')
|
499
|
+
print('Model Type:', model_type)
|
403
500
|
|
404
501
|
# Display final visualizations
|
405
502
|
display_visualizations_for_learner(viz_objects, best_weight, data, best_acc, train_loss, y_train, interval)
|
406
|
-
return best_weight, best_model[get_preds_softmax()], best_acc, final_activations
|
503
|
+
return best_weight, best_model[get_preds_softmax()], best_acc, final_activations, None, None, None, None, None, None, None, activation_potentiation
|
407
504
|
|
408
505
|
|
409
506
|
def evaluate(
|
410
507
|
x_test,
|
411
508
|
y_test,
|
509
|
+
model_type,
|
412
510
|
W,
|
413
511
|
activations=['linear'],
|
414
|
-
|
415
|
-
|
512
|
+
activation_potentiations=[],
|
513
|
+
auto_normalization=False
|
416
514
|
) -> tuple:
|
417
515
|
"""
|
418
516
|
Evaluates the neural network model using the given test data.
|
@@ -422,13 +520,15 @@ def evaluate(
|
|
422
520
|
|
423
521
|
y_test (np.ndarray): Test labels (one-hot encoded).
|
424
522
|
|
523
|
+
model_type: (str): Type of the model. Options: 'PLAN', 'MLP', 'PTNN'.
|
524
|
+
|
425
525
|
W (np.ndarray): Neural net weight matrix.
|
426
526
|
|
427
|
-
activations (list, optional): Activation list. Default = ['linear'].
|
527
|
+
activations (list, optional): Activation list for PLAN or MLP models (MLP layers activations if it PTNN model). Default = ['linear'].
|
528
|
+
|
529
|
+
activation_potentiations (list, optional): Extra activation potentiation list (PLAN layers activations) for PTNN models. Default = [].
|
428
530
|
|
429
531
|
auto_normalization (bool, optional): Normalization for x_test ? Default = False.
|
430
|
-
|
431
|
-
is_mlp (bool, optional): Evaluate PLAN model or MLP model ? Default: False (PLAN)
|
432
532
|
|
433
533
|
Returns:
|
434
534
|
tuple: Model (list).
|
@@ -441,7 +541,7 @@ def evaluate(
|
|
441
541
|
elif isinstance(activations, list):
|
442
542
|
activations = [item if isinstance(item, list) or isinstance(item, str) else [item] for item in activations]
|
443
543
|
|
444
|
-
if
|
544
|
+
if model_type == 'MLP':
|
445
545
|
layer = x_test
|
446
546
|
for i in range(len(W)):
|
447
547
|
if i != len(W) - 1 and i != 0: layer = apply_activation(layer, activations[i])
|
@@ -450,11 +550,28 @@ def evaluate(
|
|
450
550
|
|
451
551
|
result = layer
|
452
552
|
|
453
|
-
|
553
|
+
if model_type == 'PLAN':
|
454
554
|
|
455
555
|
x_test = apply_activation(x_test, activations)
|
456
556
|
result = x_test @ W.T
|
457
557
|
|
558
|
+
if model_type == 'PTNN':
|
559
|
+
|
560
|
+
if isinstance(activation_potentiations, str):
|
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
|
567
|
+
|
568
|
+
for i in range(1, len(W)):
|
569
|
+
if i != len(W) - 1: layer = apply_activation(layer, activations[i])
|
570
|
+
|
571
|
+
layer = layer @ W[i].T
|
572
|
+
|
573
|
+
result = layer
|
574
|
+
|
458
575
|
max_vals = np.max(result, axis=1, keepdims=True)
|
459
576
|
|
460
577
|
softmax_preds = np.exp(result - max_vals) / np.sum(np.exp(result - max_vals), axis=1, keepdims=True)
|