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,7 +2,6 @@ import networkx as nx
|
|
2
2
|
import matplotlib.pyplot as plt
|
3
3
|
import cupy as cp
|
4
4
|
from scipy.spatial import ConvexHull
|
5
|
-
import seaborn as sns
|
6
5
|
from matplotlib.animation import ArtistAnimation
|
7
6
|
|
8
7
|
def draw_neural_web(W, ax, G, return_objs=False):
|
@@ -87,13 +86,13 @@ def draw_model_architecture(model_name, model_path=''):
|
|
87
86
|
Visualizes the architecture of a neural network model with multiple inputs based on activation functions.
|
88
87
|
"""
|
89
88
|
|
90
|
-
from
|
89
|
+
from ..model_ops import load_model
|
91
90
|
|
92
91
|
model = load_model(model_name=model_name, model_path=model_path)
|
93
92
|
|
94
|
-
W = model
|
95
|
-
activations = model
|
96
|
-
scaler_params = model
|
93
|
+
W = model.weights
|
94
|
+
activations = model.activations
|
95
|
+
scaler_params = model.scaler_params
|
97
96
|
|
98
97
|
# Calculate dimensions based on number of activation functions
|
99
98
|
num_activations = len(activations)
|
@@ -183,14 +182,11 @@ def draw_model_architecture(model_name, model_path=''):
|
|
183
182
|
|
184
183
|
def draw_activations(x_train, activation):
|
185
184
|
|
186
|
-
from . import
|
185
|
+
from . import activation_functions as af
|
187
186
|
|
188
187
|
if activation == 'sigmoid':
|
189
188
|
result = af.Sigmoid(x_train)
|
190
189
|
|
191
|
-
elif activation == 'swish':
|
192
|
-
result = af.swish(x_train)
|
193
|
-
|
194
190
|
elif activation == 'circular':
|
195
191
|
result = af.circular_activation(x_train)
|
196
192
|
|
@@ -206,18 +202,6 @@ def draw_activations(x_train, activation):
|
|
206
202
|
elif activation == 'relu':
|
207
203
|
result = af.Relu(x_train)
|
208
204
|
|
209
|
-
elif activation == 'softplus':
|
210
|
-
result = af.softplus(x_train)
|
211
|
-
|
212
|
-
elif activation == 'elu':
|
213
|
-
result = af.elu(x_train)
|
214
|
-
|
215
|
-
elif activation == 'gelu':
|
216
|
-
result = af.gelu(x_train)
|
217
|
-
|
218
|
-
elif activation == 'selu':
|
219
|
-
result = af.selu(x_train)
|
220
|
-
|
221
205
|
elif activation == 'softmax':
|
222
206
|
result = af.Softmax(x_train)
|
223
207
|
|
@@ -236,24 +220,12 @@ def draw_activations(x_train, activation):
|
|
236
220
|
elif activation == 'dlrelu':
|
237
221
|
result = af.dlrelu(x_train)
|
238
222
|
|
239
|
-
elif activation == 'exsig':
|
240
|
-
result = af.exsig(x_train)
|
241
|
-
|
242
223
|
elif activation == 'sin_plus':
|
243
224
|
result = af.sin_plus(x_train)
|
244
225
|
|
245
226
|
elif activation == 'acos':
|
246
227
|
result = af.acos(x_train, alpha=1.0, beta=0.0)
|
247
228
|
|
248
|
-
elif activation == 'gla':
|
249
|
-
result = af.gla(x_train, alpha=1.0, mu=0.0)
|
250
|
-
|
251
|
-
elif activation == 'srelu':
|
252
|
-
result = af.srelu(x_train)
|
253
|
-
|
254
|
-
elif activation == 'qelu':
|
255
|
-
result = af.qelu(x_train)
|
256
|
-
|
257
229
|
elif activation == 'isra':
|
258
230
|
result = af.isra(x_train)
|
259
231
|
|
@@ -266,54 +238,27 @@ def draw_activations(x_train, activation):
|
|
266
238
|
elif activation == 'bent_identity':
|
267
239
|
result = af.bent_identity(x_train)
|
268
240
|
|
269
|
-
elif activation == 'sech':
|
270
|
-
result = af.sech(x_train)
|
271
|
-
|
272
241
|
elif activation == 'softsign':
|
273
242
|
result = af.softsign(x_train)
|
274
243
|
|
275
244
|
elif activation == 'pwl':
|
276
245
|
result = af.pwl(x_train)
|
277
246
|
|
278
|
-
elif activation == 'cubic':
|
279
|
-
result = af.cubic(x_train)
|
280
|
-
|
281
|
-
elif activation == 'gaussian':
|
282
|
-
result = af.gaussian(x_train)
|
283
|
-
|
284
247
|
elif activation == 'sine':
|
285
248
|
result = af.sine(x_train)
|
286
249
|
|
287
250
|
elif activation == 'tanh_square':
|
288
251
|
result = af.tanh_square(x_train)
|
289
252
|
|
290
|
-
elif activation == 'mod_sigmoid':
|
291
|
-
result = af.mod_sigmoid(x_train)
|
292
|
-
|
293
253
|
elif activation == 'linear':
|
294
254
|
result = x_train
|
295
255
|
|
296
|
-
elif activation == 'quartic':
|
297
|
-
result = af.quartic(x_train)
|
298
|
-
|
299
|
-
elif activation == 'square_quartic':
|
300
|
-
result = af.square_quartic(x_train)
|
301
|
-
|
302
|
-
elif activation == 'cubic_quadratic':
|
303
|
-
result = af.cubic_quadratic(x_train)
|
304
|
-
|
305
|
-
elif activation == 'exp_cubic':
|
306
|
-
result = af.exp_cubic(x_train)
|
307
|
-
|
308
256
|
elif activation == 'sine_square':
|
309
257
|
result = af.sine_square(x_train)
|
310
258
|
|
311
259
|
elif activation == 'logarithmic':
|
312
260
|
result = af.logarithmic(x_train)
|
313
261
|
|
314
|
-
elif activation == 'scaled_cubic':
|
315
|
-
result = af.scaled_cubic(x_train, 1.0)
|
316
|
-
|
317
262
|
elif activation == 'sine_offset':
|
318
263
|
result = af.sine_offset(x_train, 1.0)
|
319
264
|
|
@@ -325,192 +270,11 @@ def draw_activations(x_train, activation):
|
|
325
270
|
print('\rWARNING: error in drawing some activation.', end='')
|
326
271
|
return x_train
|
327
272
|
|
328
|
-
|
329
|
-
def plot_evaluate(x_test, y_test, y_preds, acc_list, W, activations):
|
330
|
-
|
331
|
-
from .metrics_cuda import metrics, confusion_matrix, roc_curve
|
332
|
-
from .ui import loading_bars, initialize_loading_bar
|
333
|
-
from .data_operations_cuda import decode_one_hot
|
334
|
-
from .model_operations_cuda import predict_model_ram
|
335
|
-
|
336
|
-
bar_format_normal = loading_bars()[0]
|
337
|
-
|
338
|
-
acc = acc_list[len(acc_list) - 1]
|
339
|
-
y_true = decode_one_hot(y_test)
|
340
|
-
|
341
|
-
y_true = cp.array(y_true, copy=True)
|
342
|
-
y_preds = cp.array(y_preds, copy=True)
|
343
|
-
Class = cp.unique(decode_one_hot(y_test))
|
344
|
-
|
345
|
-
precision, recall, f1 = metrics(y_test, y_preds)
|
346
|
-
|
347
|
-
|
348
|
-
cm = confusion_matrix(y_true, y_preds, len(Class))
|
349
|
-
fig, axs = plt.subplots(2, 2, figsize=(16, 12))
|
350
|
-
|
351
|
-
sns.heatmap(cm.get(), annot=True, fmt='d', ax=axs[0, 0])
|
352
|
-
axs[0, 0].set_title("Confusion Matrix")
|
353
|
-
axs[0, 0].set_xlabel("Predicted Class")
|
354
|
-
axs[0, 0].set_ylabel("Actual Class")
|
355
|
-
|
356
|
-
if len(Class) == 2:
|
357
|
-
fpr, tpr, thresholds = roc_curve(y_true, y_preds)
|
358
|
-
|
359
|
-
roc_auc = cp.trapz(tpr, fpr)
|
360
|
-
axs[1, 0].plot(fpr.get(), tpr.get(), color='darkorange', lw=2, label=f'ROC curve (area = {roc_auc:.2f})')
|
361
|
-
axs[1, 0].plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
|
362
|
-
axs[1, 0].set_xlim([0.0, 1.0])
|
363
|
-
axs[1, 0].set_ylim([0.0, 1.05])
|
364
|
-
axs[1, 0].set_xlabel('False Positive Rate')
|
365
|
-
axs[1, 0].set_ylabel('True Positive Rate')
|
366
|
-
axs[1, 0].set_title('Receiver Operating Characteristic (ROC) Curve')
|
367
|
-
axs[1, 0].legend(loc="lower right")
|
368
|
-
axs[1, 0].legend(loc="lower right")
|
369
|
-
else:
|
370
|
-
|
371
|
-
for i in range(len(Class)):
|
372
|
-
|
373
|
-
y_true_copy = cp.copy(y_true)
|
374
|
-
y_preds_copy = cp.copy(y_preds)
|
375
|
-
|
376
|
-
y_true_copy[y_true_copy == i] = 0
|
377
|
-
y_true_copy[y_true_copy != 0] = 1
|
378
|
-
|
379
|
-
y_preds_copy[y_preds_copy == i] = 0
|
380
|
-
y_preds_copy[y_preds_copy != 0] = 1
|
381
|
-
|
382
|
-
|
383
|
-
fpr, tpr, thresholds = roc_curve(y_true_copy, y_preds_copy)
|
384
|
-
|
385
|
-
roc_auc = cp.trapz(tpr, fpr)
|
386
|
-
axs[1, 0].plot(fpr.get(), tpr.get(), color='darkorange', lw=2, label=f'ROC curve (area = {roc_auc:.2f})')
|
387
|
-
axs[1, 0].plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
|
388
|
-
axs[1, 0].set_xlim([0.0, 1.0])
|
389
|
-
axs[1, 0].set_ylim([0.0, 1.05])
|
390
|
-
axs[1, 0].set_xlabel('False Positive Rate')
|
391
|
-
axs[1, 0].set_ylabel('True Positive Rate')
|
392
|
-
axs[1, 0].set_title('Receiver Operating Characteristic (ROC) Curve')
|
393
|
-
axs[1, 0].legend(loc="lower right")
|
394
|
-
axs[1, 0].legend(loc="lower right")
|
395
|
-
|
396
|
-
|
397
|
-
metric = ['Precision', 'Recall', 'F1 Score', 'Accuracy']
|
398
|
-
values = [precision, recall, f1, acc.get()]
|
399
|
-
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
|
400
|
-
|
401
|
-
|
402
|
-
bars = axs[0, 1].bar(metric, values, color=colors)
|
403
|
-
|
404
|
-
|
405
|
-
for bar, value in zip(bars, values):
|
406
|
-
axs[0, 1].text(bar.get_x() + bar.get_width() / 2, bar.get_height() - 0.05, f'{value:.2f}',
|
407
|
-
ha='center', va='bottom', fontsize=12, color='white', weight='bold')
|
408
|
-
|
409
|
-
axs[0, 1].set_ylim(0, 1)
|
410
|
-
axs[0, 1].set_xlabel('Metrics')
|
411
|
-
axs[0, 1].set_ylabel('Score')
|
412
|
-
axs[0, 1].set_title('Precision, Recall, F1 Score, and Accuracy (Weighted)')
|
413
|
-
axs[0, 1].grid(True, axis='y', linestyle='--', alpha=0.7)
|
414
|
-
|
415
|
-
feature_indices=[0, 1]
|
416
|
-
|
417
|
-
h = .02
|
418
|
-
x_min, x_max = x_test[:, feature_indices[0]].min() - 1, x_test[:, feature_indices[0]].max() + 1
|
419
|
-
y_min, y_max = x_test[:, feature_indices[1]].min() - 1, x_test[:, feature_indices[1]].max() + 1
|
420
|
-
xx, yy = cp.meshgrid(cp.arange(x_min, x_max, h),
|
421
|
-
cp.arange(y_min, y_max, h))
|
422
|
-
|
423
|
-
grid = cp.c_[xx.ravel(), yy.ravel()]
|
424
|
-
|
425
|
-
grid_full = cp.zeros((grid.shape[0], x_test.shape[1]), dtype=cp.float32)
|
426
|
-
grid_full[:, feature_indices] = grid
|
427
|
-
|
428
|
-
Z = [None] * len(grid_full)
|
429
|
-
|
430
|
-
predict_progress = initialize_loading_bar(total=len(grid_full),leave=False,
|
431
|
-
bar_format=bar_format_normal ,desc="Predicts For Decision Boundary",ncols= 65)
|
432
|
-
|
433
|
-
for i in range(len(grid_full)):
|
434
|
-
|
435
|
-
Z[i] = cp.argmax(predict_model_ram(grid_full[i], W=W, activations=activations))
|
436
|
-
predict_progress.update(1)
|
437
|
-
|
438
|
-
predict_progress.close()
|
439
|
-
|
440
|
-
Z = cp.array(Z)
|
441
|
-
Z = Z.reshape(xx.shape)
|
442
|
-
|
443
|
-
axs[1,1].contourf(xx.get(), yy.get(), Z.get(), alpha=0.8)
|
444
|
-
axs[1,1].scatter(x_test[:, feature_indices[0]].get(), x_test[:, feature_indices[1]].get(), c=decode_one_hot(y_test).get(), edgecolors='k', marker='o', s=20, alpha=0.9)
|
445
|
-
axs[1,1].set_xlabel(f'Feature {0 + 1}')
|
446
|
-
axs[1,1].set_ylabel(f'Feature {1 + 1}')
|
447
|
-
axs[1,1].set_title('Decision Boundary')
|
448
|
-
|
449
|
-
plt.show()
|
450
|
-
|
451
|
-
|
452
|
-
def plot_decision_boundary(x, y, activations, W, artist=None, ax=None):
|
453
|
-
|
454
|
-
from .model_operations_cuda import predict_model_ram
|
455
|
-
from .data_operations_cuda import decode_one_hot
|
456
|
-
|
457
|
-
feature_indices = [0, 1]
|
458
|
-
|
459
|
-
h = .02
|
460
|
-
x_min, x_max = x[:, feature_indices[0]].min() - 1, x[:, feature_indices[0]].max() + 1
|
461
|
-
y_min, y_max = x[:, feature_indices[1]].min() - 1, x[:, feature_indices[1]].max() + 1
|
462
|
-
xx, yy = cp.meshgrid(cp.arange(x_min, x_max, h),
|
463
|
-
cp.arange(y_min, y_max, h))
|
464
|
-
|
465
|
-
grid = cp.c_[xx.ravel(), yy.ravel()]
|
466
|
-
grid_full = cp.zeros((grid.shape[0], x.shape[1]))
|
467
|
-
grid_full[:, feature_indices] = grid
|
468
|
-
|
469
|
-
Z = [None] * len(grid_full)
|
470
|
-
|
471
|
-
for i in range(len(grid_full)):
|
472
|
-
Z[i] = cp.argmax(predict_model_ram(grid_full[i], W=W, activations=activations))
|
473
|
-
|
474
|
-
Z = cp.array(Z, dtype=cp.int32)
|
475
|
-
Z = Z.reshape(xx.shape)
|
476
|
-
|
477
|
-
if ax is None:
|
478
|
-
|
479
|
-
plt.contourf(xx.get(), yy.get(), Z.get(), alpha=0.8)
|
480
|
-
plt.scatter(x[:, feature_indices[0]].get(), x[:, feature_indices[1]].get(), c=decode_one_hot(y).get(), edgecolors='k', marker='o', s=20, alpha=0.9)
|
481
|
-
plt.xlabel(f'Feature {0 + 1}')
|
482
|
-
plt.ylabel(f'Feature {1 + 1}')
|
483
|
-
plt.title('Decision Boundary')
|
484
|
-
|
485
|
-
plt.show()
|
486
|
-
|
487
|
-
else:
|
488
|
-
|
489
|
-
try:
|
490
|
-
art1_1 = ax[1, 0].contourf(xx.get(), yy.get(), Z.get(), alpha=0.8)
|
491
|
-
art1_2 = ax[1, 0].scatter(x[:, feature_indices[0]].get(), x[:, feature_indices[1]].get(), c=decode_one_hot(y).get(), edgecolors='k', marker='o', s=20, alpha=0.9)
|
492
|
-
ax[1, 0].set_xlabel(f'Feature {0 + 1}')
|
493
|
-
ax[1, 0].set_ylabel(f'Feature {1 + 1}')
|
494
|
-
ax[1, 0].set_title('Decision Boundary')
|
495
|
-
|
496
|
-
return art1_1, art1_2
|
497
|
-
|
498
|
-
except:
|
499
|
-
|
500
|
-
art1_1 = ax.contourf(xx.get(), yy.get(), Z.get(), alpha=0.8)
|
501
|
-
art1_2 = ax.scatter(x[:, feature_indices[0]].get(), x[:, feature_indices[1]].get(), c=decode_one_hot(y).get(), edgecolors='k', marker='o', s=20, alpha=0.9)
|
502
|
-
ax.set_xlabel(f'Feature {0 + 1}')
|
503
|
-
ax.set_ylabel(f'Feature {1 + 1}')
|
504
|
-
ax.set_title('Decision Boundary')
|
505
|
-
|
506
|
-
|
507
|
-
return art1_1, art1_2
|
508
|
-
|
509
273
|
|
510
274
|
def plot_decision_space(x, y, y_preds=None, s=100, color='tab20'):
|
511
275
|
|
512
|
-
from .
|
513
|
-
from .
|
276
|
+
from .metrics import pca
|
277
|
+
from .data_ops import decode_one_hot
|
514
278
|
|
515
279
|
if x.shape[1] > 2:
|
516
280
|
|
@@ -699,7 +463,7 @@ def update_neuron_history_for_learner(LTPW, ax1, row, col, class_count, artist5,
|
|
699
463
|
|
700
464
|
def initialize_visualization_for_learner(show_history, neurons_history, neural_web_history, x_train, y_train):
|
701
465
|
|
702
|
-
from .
|
466
|
+
from .data_ops import find_closest_factors
|
703
467
|
viz_objects = {}
|
704
468
|
|
705
469
|
if show_history:
|
@@ -1,17 +1,16 @@
|
|
1
1
|
"""
|
2
2
|
|
3
3
|
|
4
|
-
ENE (Eugenic NeuroEvolution)
|
4
|
+
ENE (Eugenic NeuroEvolution)
|
5
5
|
===================================
|
6
6
|
|
7
|
-
This module contains all the functions necessary for implementing and testing the ENE (Eugenic NeuroEvolution)
|
7
|
+
This module contains all the functions necessary for implementing and testing the ENE (Eugenic NeuroEvolution).
|
8
8
|
For more information about the ENE algorithm: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PLAN/PLAN.pdf
|
9
9
|
|
10
10
|
Module functions:
|
11
11
|
-----------------
|
12
12
|
- evolver()
|
13
13
|
- define_genomes()
|
14
|
-
- evaluate()
|
15
14
|
- cross_over()
|
16
15
|
- mutation()
|
17
16
|
- dominant_parent_selection()
|
@@ -21,7 +20,7 @@ Examples: https://github.com/HCB06/PyerualJetwork/tree/main/Welcome_to_PyerualJe
|
|
21
20
|
|
22
21
|
PyerualJetwork document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PyerualJetwork/PYERUALJETWORK_USER_MANUEL_AND_LEGAL_INFORMATION(EN).pdf
|
23
22
|
|
24
|
-
-
|
23
|
+
- Creator: Hasan Can Beydili
|
25
24
|
- YouTube: https://www.youtube.com/@HasanCanBeydili
|
26
25
|
- Linkedin: https://www.linkedin.com/in/hasan-can-beydili-77a1b9270/
|
27
26
|
- Instagram: https://www.instagram.com/canbeydilj
|
@@ -34,9 +33,9 @@ import math
|
|
34
33
|
import copy
|
35
34
|
|
36
35
|
### LIBRARY IMPORTS ###
|
37
|
-
from .
|
36
|
+
from .cpu.data_ops import non_neg_normalization
|
38
37
|
from .ui import loading_bars, initialize_loading_bar
|
39
|
-
from .
|
38
|
+
from .cpu.activation_functions import all_activations
|
40
39
|
|
41
40
|
def define_genomes(input_shape, output_shape, population_size, neurons=[], activation_functions=[], dtype=np.float32):
|
42
41
|
"""
|
@@ -97,13 +96,6 @@ def define_genomes(input_shape, output_shape, population_size, neurons=[], activ
|
|
97
96
|
if l != hidden:
|
98
97
|
population_activations[i][l] = activation_functions[l]
|
99
98
|
|
100
|
-
# ACTIVATIONS APPLYING IN WEIGHTS SPECIFIC OUTPUT CONNECTIONS (MORE PLAN LIKE FEATURES(FOR NON-LINEARITY)):
|
101
|
-
|
102
|
-
for j in range(population_weights[i][l].shape[0]):
|
103
|
-
|
104
|
-
population_weights[i][l][j,:] = apply_activation(population_weights[i][l][j,:], population_activations[i])
|
105
|
-
population_weights[i][l][j,:] = normalization(population_weights[i][l][j,:], dtype=dtype)
|
106
|
-
|
107
99
|
return population_weights, population_activations
|
108
100
|
|
109
101
|
else:
|
@@ -118,13 +110,6 @@ def define_genomes(input_shape, output_shape, population_size, neurons=[], activ
|
|
118
110
|
population_weights[i] = np.random.uniform(-1, 1, (output_shape, input_shape)).astype(dtype)
|
119
111
|
population_activations[i] = activations[int(random.uniform(0, len(activations)-1))]
|
120
112
|
|
121
|
-
# ACTIVATIONS APPLYING IN WEIGHTS SPECIFIC OUTPUT CONNECTIONS (MORE PLAN LIKE FEATURES(FOR NON-LINEARITY)):
|
122
|
-
|
123
|
-
for j in range(population_weights[i].shape[0]):
|
124
|
-
|
125
|
-
population_weights[i][j,:] = apply_activation(population_weights[i][j,:], population_activations[i])
|
126
|
-
population_weights[i][j,:] = normalization(population_weights[i][j,:], dtype=dtype)
|
127
|
-
|
128
113
|
return np.array(population_weights, dtype=dtype), population_activations
|
129
114
|
|
130
115
|
|
@@ -137,7 +122,7 @@ def evolver(weights,
|
|
137
122
|
policy='aggressive',
|
138
123
|
bad_genomes_selection_prob=None,
|
139
124
|
bar_status=True,
|
140
|
-
strategy='
|
125
|
+
strategy='more_selective',
|
141
126
|
bad_genomes_mutation_prob=None,
|
142
127
|
fitness_bias=1,
|
143
128
|
cross_over_mode='tpm',
|
@@ -152,7 +137,7 @@ def evolver(weights,
|
|
152
137
|
weight_mutate_threshold=16,
|
153
138
|
weight_mutate_prob=1,
|
154
139
|
is_mlp=False,
|
155
|
-
save_best_genome=
|
140
|
+
save_best_genome=True,
|
156
141
|
dtype=np.float32):
|
157
142
|
"""
|
158
143
|
Applies the evolving process of a population of genomes using selection, crossover, mutation, and activation function potentiation.
|
@@ -171,7 +156,7 @@ def evolver(weights,
|
|
171
156
|
what_gen (int): The current generation number, used for informational purposes or logging.
|
172
157
|
|
173
158
|
fitness (numpy.ndarray): A 1D array containing the fitness values of each genome.
|
174
|
-
The array is used to rank the genomes based on their performance.
|
159
|
+
The array is used to rank the genomes based on their performance. ENE maximizes or minimizes this fitness based on the `target_fitness` parameter.
|
175
160
|
|
176
161
|
weight_evolve (bool, optional): Are weights to be evolves or just activation combinations Default: True. Note: Regardless of whether this parameter is True or False, you must give the evolver function a list of weights equal to the number of activation potentiations. You can create completely random weights if you want. If this parameter is False, the weights entering the evolver function and the resulting weights will be exactly the same.
|
177
162
|
|
@@ -182,7 +167,7 @@ def evolver(weights,
|
|
182
167
|
- 'normal_selective': Normal selection based on fitness, where a portion of the bad genes are discarded.
|
183
168
|
- 'more_selective': A more selective strategy, where fewer bad genes survive.
|
184
169
|
- 'less_selective': A less selective strategy, where more bad genes survive.
|
185
|
-
Default is '
|
170
|
+
Default is 'more_selective'.
|
186
171
|
|
187
172
|
bar_status (bool, optional): Loading bar status during evolving process of genomes. True or False. Default: True
|
188
173
|
|
@@ -241,7 +226,7 @@ def evolver(weights,
|
|
241
226
|
|
242
227
|
is_mlp (bool, optional): Evolve PLAN model or MLP model ? Default: False (PLAN)
|
243
228
|
|
244
|
-
save_best_genome (bool, optional): Save the best genome of the previous generation to the next generation. Default:
|
229
|
+
save_best_genome (bool, optional): Save the best genome of the previous generation to the next generation. (index of best individual: 0) Default: True
|
245
230
|
|
246
231
|
dtype (numpy.dtype, optional): Data type for the arrays. Default: np.float32.
|
247
232
|
Example: np.float64 or np.float16 [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not recommended!].
|
@@ -328,7 +313,7 @@ def evolver(weights,
|
|
328
313
|
else:
|
329
314
|
raise ValueError("genome population size must be even number. for example: not 99, make 100 or 98.")
|
330
315
|
|
331
|
-
if weight_evolve is False: origin_weights =
|
316
|
+
if weight_evolve is False: origin_weights = copy.deepcopy(weights)
|
332
317
|
|
333
318
|
if is_mlp:
|
334
319
|
activation_mutate_add_prob = 0
|
@@ -350,14 +335,14 @@ def evolver(weights,
|
|
350
335
|
|
351
336
|
good_weights = weights[slice_center:]
|
352
337
|
bad_weights = weights[:slice_center]
|
353
|
-
best_weight =
|
338
|
+
best_weight = copy.deepcopy(good_weights[-1])
|
354
339
|
|
355
340
|
good_activations = list(activations[slice_center:])
|
356
341
|
bad_activations = list(activations[:slice_center])
|
357
|
-
best_activations = good_activations[-1]
|
342
|
+
best_activations = copy.deepcopy(good_activations[-1]) if isinstance(good_activations[-1], list) else good_activations[-1]
|
358
343
|
|
359
344
|
|
360
|
-
###
|
345
|
+
### ENE IS APPLIED ACCORDING TO THE SPECIFIED POLICY, STRATEGY, AND PROBABILITY CONFIGURATION:
|
361
346
|
|
362
347
|
bar_format = loading_bars()[0]
|
363
348
|
|
@@ -367,23 +352,23 @@ def evolver(weights,
|
|
367
352
|
best_fitness = normalized_fitness[-1]
|
368
353
|
epsilon = np.finfo(float).eps
|
369
354
|
|
370
|
-
child_W =
|
371
|
-
child_act =
|
355
|
+
child_W = copy.deepcopy(bad_weights)
|
356
|
+
child_act = copy.deepcopy(bad_activations)
|
372
357
|
|
373
|
-
mutated_W =
|
374
|
-
mutated_act =
|
358
|
+
mutated_W = copy.deepcopy(bad_weights)
|
359
|
+
mutated_act = copy.deepcopy(bad_activations)
|
375
360
|
|
376
361
|
|
377
362
|
for i in range(len(bad_weights)):
|
378
363
|
|
379
364
|
if policy == 'aggressive':
|
380
|
-
first_parent_W =
|
381
|
-
first_parent_act = best_activations
|
365
|
+
first_parent_W = copy.deepcopy(best_weight)
|
366
|
+
first_parent_act = copy.deepcopy(best_activations)
|
382
367
|
first_parent_fitness = best_fitness
|
383
368
|
|
384
369
|
elif policy == 'explorer':
|
385
|
-
first_parent_W = good_weights[i]
|
386
|
-
first_parent_act = good_activations[i]
|
370
|
+
first_parent_W = copy.deepcopy(good_weights[i])
|
371
|
+
first_parent_act = copy.deepcopy(good_activations[i])
|
387
372
|
first_parent_fitness = normalized_fitness[len(good_weights) + i]
|
388
373
|
|
389
374
|
else: raise ValueError("policy parameter must be: 'aggressive' or 'explorer'")
|
@@ -489,8 +474,8 @@ def evolver(weights,
|
|
489
474
|
activations = child_act + mutated_act
|
490
475
|
|
491
476
|
if save_best_genome:
|
492
|
-
weights[0] = best_weight
|
493
|
-
activations[0] = best_activations
|
477
|
+
weights[0] = copy.deepcopy(best_weight)
|
478
|
+
activations[0] = copy.deepcopy(best_activations)
|
494
479
|
|
495
480
|
### INFO PRINTING CONSOLE
|
496
481
|
|
@@ -532,57 +517,6 @@ def evolver(weights,
|
|
532
517
|
return weights, activations
|
533
518
|
|
534
519
|
|
535
|
-
def evaluate(Input, weights, activations, is_mlp=False):
|
536
|
-
"""
|
537
|
-
Evaluates the performance of a population of genomes, applying different activation functions
|
538
|
-
and weights depending on whether reinforcement learning mode is enabled or not.
|
539
|
-
|
540
|
-
Args:
|
541
|
-
Input (list or numpy.ndarray): A list or 2D numpy array where each element represents
|
542
|
-
a genome (A list of input features for each genome, or a single set of input features for one genome).
|
543
|
-
weights (list or numpy.ndarray): A list or 2D numpy array of weights corresponding to each genome
|
544
|
-
in `x_population`. This determines the strength of connections.
|
545
|
-
activations (list or str): A list where each entry represents an activation function
|
546
|
-
or a potentiation strategy applied to each genome. If only one
|
547
|
-
activation function is used, this can be a single string.
|
548
|
-
is_mlp (bool, optional): Evaluate PLAN model or MLP model ? Default: False (PLAN)
|
549
|
-
|
550
|
-
Returns:
|
551
|
-
list: A list of outputs corresponding to each genome in the population after applying the respective
|
552
|
-
activation function and weights.
|
553
|
-
|
554
|
-
Example:
|
555
|
-
```python
|
556
|
-
outputs = evaluate(Input, weights, activations)
|
557
|
-
```
|
558
|
-
|
559
|
-
- The function returns a list of outputs after processing the population, where each element corresponds to
|
560
|
-
the output for each genome in population.
|
561
|
-
"""
|
562
|
-
### THE OUTPUTS ARE RETURNED, WHERE EACH GENOME'S OUTPUT MATCHES ITS INDEX:
|
563
|
-
|
564
|
-
if isinstance(activations, str):
|
565
|
-
activations = [activations]
|
566
|
-
elif isinstance(activations, list):
|
567
|
-
activations = [item if isinstance(item, list) or isinstance(item, str) else [item] for item in activations]
|
568
|
-
|
569
|
-
|
570
|
-
if is_mlp:
|
571
|
-
layer = Input
|
572
|
-
for i in range(len(weights)):
|
573
|
-
if i != len(weights) - 1 and i != 0: layer = apply_activation(layer, activations[i])
|
574
|
-
|
575
|
-
layer = layer @ weights[i].T
|
576
|
-
|
577
|
-
return layer
|
578
|
-
|
579
|
-
else:
|
580
|
-
|
581
|
-
Input = apply_activation(Input, activations)
|
582
|
-
result = Input @ weights.T
|
583
|
-
|
584
|
-
return result
|
585
|
-
|
586
520
|
def cross_over(first_parent_W,
|
587
521
|
second_parent_W,
|
588
522
|
first_parent_act,
|
@@ -678,18 +612,18 @@ def cross_over(first_parent_W,
|
|
678
612
|
decision = dominant_parent_selection(bad_genomes_selection_prob)
|
679
613
|
|
680
614
|
if decision == 'first_parent':
|
681
|
-
dominant_parent_W =
|
615
|
+
dominant_parent_W = copy.deepcopy(first_parent_W)
|
682
616
|
dominant_parent_act = first_parent_act
|
683
617
|
|
684
|
-
undominant_parent_W =
|
618
|
+
undominant_parent_W = copy.deepcopy(second_parent_W)
|
685
619
|
undominant_parent_act = second_parent_act
|
686
620
|
succes = second_parent_fitness + epsilon
|
687
621
|
|
688
622
|
elif decision == 'second_parent':
|
689
|
-
dominant_parent_W =
|
623
|
+
dominant_parent_W = copy.deepcopy(second_parent_W)
|
690
624
|
dominant_parent_act = second_parent_act
|
691
625
|
|
692
|
-
undominant_parent_W =
|
626
|
+
undominant_parent_W = copy.deepcopy(first_parent_W)
|
693
627
|
undominant_parent_act = first_parent_act
|
694
628
|
succes = first_parent_fitness + epsilon
|
695
629
|
|
@@ -727,7 +661,7 @@ def cross_over(first_parent_W,
|
|
727
661
|
if isinstance(dominant_parent_act, str): dominant_parent_act = [dominant_parent_act]
|
728
662
|
if isinstance(undominant_parent_act, str): undominant_parent_act = [undominant_parent_act]
|
729
663
|
|
730
|
-
child_act = list(
|
664
|
+
child_act = list(copy.deepcopy(dominant_parent_act))
|
731
665
|
|
732
666
|
activation_selection_add_prob = 1 - activation_selection_add_prob # if prob 0.8 (%80) then 1 - 0.8. Because 0-1 random number probably greater than 0.2
|
733
667
|
potential_activation_selection_add = random.uniform(0, 1)
|
pyerualjetwork/help.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from pyerualjetwork.
|
1
|
+
from pyerualjetwork.cpu.activation_functions import all_activations
|
2
2
|
|
3
3
|
|
4
4
|
def activation_potentiation():
|
@@ -11,7 +11,7 @@ def activation_potentiation():
|
|
11
11
|
|
12
12
|
def docs_and_examples():
|
13
13
|
|
14
|
-
print('PLAN document: https://github.com/HCB06/
|
15
|
-
print('PLAN examples: https://github.com/HCB06/
|
16
|
-
print('
|
17
|
-
print('
|
14
|
+
print('PLAN & ENE document: https://github.com/HCB06/PyerualJetwork/tree/main/Welcome_to_PLAN\n')
|
15
|
+
print('PLAN examples: https://github.com/HCB06/PyerualJetwork/tree/main/Welcome_to_PyerualJetwork/ExampleCodes\n')
|
16
|
+
print('ENE examples: https://github.com/HCB06/PyerualJetwork/tree/main/Welcome_to_PyerualJetwork/ExampleCodes/ENE\n')
|
17
|
+
print('PyerualJetwork document and examples: https://github.com/HCB06/PyerualJetwork/tree/main/Welcome_to_PyerualJetwork')
|