pyerualjetwork 4.3.11__py3-none-any.whl → 4.3.13__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 +1 -1
- pyerualjetwork/plan.py +13 -4
- pyerualjetwork/plan_cuda.py +10 -4
- pyerualjetwork/planeat.py +104 -82
- pyerualjetwork/planeat_cuda.py +106 -85
- pyerualjetwork/visualizations.py +3 -3
- {pyerualjetwork-4.3.11.dist-info → pyerualjetwork-4.3.13.dist-info}/METADATA +1 -1
- {pyerualjetwork-4.3.11.dist-info → pyerualjetwork-4.3.13.dist-info}/RECORD +10 -10
- {pyerualjetwork-4.3.11.dist-info → pyerualjetwork-4.3.13.dist-info}/WHEEL +0 -0
- {pyerualjetwork-4.3.11.dist-info → pyerualjetwork-4.3.13.dist-info}/top_level.txt +0 -0
pyerualjetwork/__init__.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
__version__ = "4.3.
|
1
|
+
__version__ = "4.3.13"
|
2
2
|
__update__ = """* Changes: https://github.com/HCB06/PyerualJetwork/blob/main/CHANGES
|
3
3
|
* PyerualJetwork Homepage: https://github.com/HCB06/PyerualJetwork/tree/main
|
4
4
|
* PyerualJetwork document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PyerualJetwork/PYERUALJETWORK_USER_MANUEL_AND_LEGAL_INFORMATION(EN).pdf
|
pyerualjetwork/plan.py
CHANGED
@@ -84,7 +84,7 @@ def fit(
|
|
84
84
|
|
85
85
|
|
86
86
|
def learner(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, pop_size=None,
|
87
|
-
neural_web_history=False, show_current_activations=False, auto_normalization=False,
|
87
|
+
weight_evolve=False, neural_web_history=False, show_current_activations=False, auto_normalization=False,
|
88
88
|
neurons_history=False, early_stop=False, show_history=False, target_loss=None,
|
89
89
|
interval=33.33, target_acc=None, loss='categorical_crossentropy', acc_impact=0.9, loss_impact=0.1,
|
90
90
|
start_this_act=None, start_this_W=None, dtype=np.float32):
|
@@ -119,13 +119,19 @@ def learner(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1,
|
|
119
119
|
batch_size=0.05,
|
120
120
|
interval=16.67)
|
121
121
|
```
|
122
|
-
|
123
|
-
|
122
|
+
|
123
|
+
weight_evolve (bool, optional): Activation combinations already optimizes by PLANEAT 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)
|
124
|
+
|
125
|
+
loss (str, optional): options: ('categorical_crossentropy' or 'binary_crossentropy') Default is 'categorical_crossentropy'.
|
124
126
|
|
125
127
|
target_acc (float, optional): The target accuracy to stop training early when achieved. Default is None.
|
126
128
|
|
127
129
|
target_loss (float, optional): The target loss to stop training early when achieved. Default is None.
|
128
130
|
|
131
|
+
acc_impact (float, optional): Impact of accuracy for optimization [0-1]. Default: 0.9
|
132
|
+
|
133
|
+
loss_impact (float, optional): Impact of loss for optimization [0-1]. Default: 0.1
|
134
|
+
|
129
135
|
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
|
130
136
|
|
131
137
|
gen (int, optional): The generation count for genetic optimization.
|
@@ -229,6 +235,9 @@ def learner(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1,
|
|
229
235
|
W = fit(x_train_batch, y_train_batch, activation_potentiation=act_pop[j], auto_normalization=auto_normalization, dtype=dtype)
|
230
236
|
weight_pop[j] = W
|
231
237
|
|
238
|
+
if weight_evolve is False:
|
239
|
+
weight_pop[j] = fit(x_train_batch, y_train_batch, activation_potentiation=act_pop[j], auto_normalization=auto_normalization, dtype=dtype)
|
240
|
+
|
232
241
|
model = evaluate(x_train_batch, y_train_batch, W=weight_pop[j], activation_potentiation=act_pop[j])
|
233
242
|
acc = model[get_acc()]
|
234
243
|
|
@@ -348,7 +357,7 @@ def learner(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1,
|
|
348
357
|
best_acc_per_gen_list.append(best_acc)
|
349
358
|
loss_list.append(best_loss)
|
350
359
|
|
351
|
-
weight_pop, act_pop = optimizer(np.array(weight_pop, copy=False, dtype=dtype), act_pop, i, np.array(target_pop, dtype=dtype, copy=False), bar_status=False)
|
360
|
+
weight_pop, act_pop = optimizer(np.array(weight_pop, copy=False, dtype=dtype), act_pop, i, np.array(target_pop, dtype=dtype, copy=False), weight_evolve=weight_evolve, bar_status=False)
|
352
361
|
target_pop = []
|
353
362
|
|
354
363
|
# Early stopping check
|
pyerualjetwork/plan_cuda.py
CHANGED
@@ -83,7 +83,7 @@ def fit(
|
|
83
83
|
|
84
84
|
|
85
85
|
def learner(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1, pop_size=None,
|
86
|
-
neural_web_history=False, show_current_activations=False, auto_normalization=False, target_acc=None,
|
86
|
+
weight_evolve=False, neural_web_history=False, show_current_activations=False, auto_normalization=False, target_acc=None,
|
87
87
|
neurons_history=False, early_stop=False, show_history=False, loss='categorical_crossentropy',
|
88
88
|
interval=33.33, target_loss=None, loss_impact=0.1, acc_impact=0.9,
|
89
89
|
start_this_act=None, start_this_W=None, dtype=cp.float32, memory='gpu'):
|
@@ -118,6 +118,9 @@ def learner(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1,
|
|
118
118
|
batch_size=0.05,
|
119
119
|
interval=16.67)
|
120
120
|
```
|
121
|
+
|
122
|
+
weight_evolve (bool, optional): Activation combinations already optimizes by PLANEAT 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)
|
123
|
+
|
121
124
|
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'.
|
122
125
|
|
123
126
|
target_acc (float, optional): The target accuracy to stop training early when achieved. Default is None.
|
@@ -130,9 +133,9 @@ def learner(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1,
|
|
130
133
|
|
131
134
|
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 test 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)
|
132
135
|
|
133
|
-
|
136
|
+
acc_impact (float, optional): Impact of accuracy for optimization [0-1]. Default: 0.9
|
134
137
|
|
135
|
-
|
138
|
+
loss_impact (float, optional): Impact of loss for optimization [0-1]. Default: 0.1
|
136
139
|
|
137
140
|
pop_size (int, optional): Population size of each generation. Default: count of activation functions
|
138
141
|
|
@@ -247,6 +250,9 @@ def learner(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1,
|
|
247
250
|
W = fit(x_train_batch, y_train_batch, activation_potentiation=act_pop[j], auto_normalization=auto_normalization, dtype=dtype)
|
248
251
|
weight_pop[j] = W
|
249
252
|
|
253
|
+
if weight_evolve is False:
|
254
|
+
weight_pop[j] = fit(x_train_batch, y_train_batch, activation_potentiation=act_pop[j], auto_normalization=auto_normalization, dtype=dtype)
|
255
|
+
|
250
256
|
model = evaluate(x_train_batch, y_train_batch, W=weight_pop[j], activation_potentiation=act_pop[j])
|
251
257
|
acc = model[get_acc()]
|
252
258
|
|
@@ -367,7 +373,7 @@ def learner(x_train, y_train, optimizer, fit_start=True, gen=None, batch_size=1,
|
|
367
373
|
best_acc_per_gen_list.append(best_acc)
|
368
374
|
loss_list.append(best_loss)
|
369
375
|
|
370
|
-
weight_pop, act_pop = optimizer(cp.array(weight_pop, copy=False, dtype=dtype), act_pop, i, cp.array(target_pop, dtype=dtype, copy=False), bar_status=False)
|
376
|
+
weight_pop, act_pop = optimizer(cp.array(weight_pop, copy=False, dtype=dtype), act_pop, i, cp.array(target_pop, dtype=dtype, copy=False), weight_evolve=weight_evolve, bar_status=False)
|
371
377
|
target_pop = []
|
372
378
|
|
373
379
|
# Early stopping check
|
pyerualjetwork/planeat.py
CHANGED
@@ -73,7 +73,8 @@ def define_genomes(input_shape, output_shape, population_size, dtype=np.float32)
|
|
73
73
|
def evolver(weights,
|
74
74
|
activation_potentiations,
|
75
75
|
what_gen,
|
76
|
-
fitness,
|
76
|
+
fitness,
|
77
|
+
weight_evolve=True,
|
77
78
|
show_info=False,
|
78
79
|
policy='aggressive',
|
79
80
|
bad_genomes_selection_prob=None,
|
@@ -112,11 +113,13 @@ def evolver(weights,
|
|
112
113
|
fitness (numpy.ndarray): A 1D array containing the fitness values of each genome.
|
113
114
|
The array is used to rank the genomes based on their performance. PLANEAT maximizes or minimizes this fitness based on the `target_fitness` parameter.
|
114
115
|
|
116
|
+
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.
|
117
|
+
|
115
118
|
show_info (bool, optional): If True, prints information about the current generation and the
|
116
119
|
maximum reward obtained. Also shows the current configuration. Default is False.
|
117
120
|
|
118
121
|
strategy (str, optional): The strategy for combining the best and bad genomes. Options:
|
119
|
-
- 'normal_selective': Normal selection based on
|
122
|
+
- 'normal_selective': Normal selection based on fitness, where a portion of the bad genes are discarded.
|
120
123
|
- 'more_selective': A more selective strategy, where fewer bad genes survive.
|
121
124
|
- 'less_selective': A less selective strategy, where more bad genes survive.
|
122
125
|
Default is 'normal_selective'.
|
@@ -143,6 +146,8 @@ def evolver(weights,
|
|
143
146
|
Must be in the range [0, 1]. Also affects the mutation probability of the best genomes inversely.
|
144
147
|
For example, a value of 0.7 for bad genomes implies 0.3 for best genomes. Default: Determined by `policy`.
|
145
148
|
|
149
|
+
bad_genomes_selection_prob (float, optional): The probability of crossover parents are bad genomes ? [0-1] Default: Determined by `policy`.
|
150
|
+
|
146
151
|
activation_mutate_prob (float, optional): The probability of applying mutation to the activation functions.
|
147
152
|
Must be in the range [0, 1]. Default is 1 (%100).
|
148
153
|
|
@@ -259,7 +264,8 @@ def evolver(weights,
|
|
259
264
|
else:
|
260
265
|
raise ValueError("genome population size must be even number. for example: not 99, make 100 or 98.")
|
261
266
|
|
262
|
-
|
267
|
+
if weight_evolve is False: origin_weights = np.copy(weights)
|
268
|
+
|
263
269
|
### FITNESS IS SORTED IN ASCENDING ORDER, AND THE WEIGHT AND ACTIVATIONS OF EACH GENOME ARE SORTED ACCORDING TO THIS ORDER:
|
264
270
|
|
265
271
|
sort_indices = np.argsort(fitness)
|
@@ -323,6 +329,7 @@ def evolver(weights,
|
|
323
329
|
first_parent_fitness=best_fitness,
|
324
330
|
fitness_bias=fitness_bias,
|
325
331
|
second_parent_fitness=normalized_fitness[s_i],
|
332
|
+
weight_evolve=weight_evolve,
|
326
333
|
epsilon=epsilon
|
327
334
|
)
|
328
335
|
|
@@ -350,6 +357,7 @@ def evolver(weights,
|
|
350
357
|
weight_mutate_threshold=weight_mutate_threshold,
|
351
358
|
genome_fitness=normalized_fitness[fitness_index],
|
352
359
|
activation_mutate_threshold=activation_mutate_threshold,
|
360
|
+
weight_evolve=weight_evolve,
|
353
361
|
epsilon=epsilon
|
354
362
|
)
|
355
363
|
|
@@ -395,6 +403,7 @@ def evolver(weights,
|
|
395
403
|
print(" BEST GENOME INDEX: ", str(0))
|
396
404
|
print(" NOTE: The returned genome at the first index is the best of the previous generation." + '\n')
|
397
405
|
|
406
|
+
if weight_evolve is False: weights = origin_weights
|
398
407
|
|
399
408
|
return weights, activation_potentiations
|
400
409
|
|
@@ -450,6 +459,7 @@ def cross_over(first_parent_W,
|
|
450
459
|
first_parent_fitness,
|
451
460
|
second_parent_fitness,
|
452
461
|
fitness_bias,
|
462
|
+
weight_evolve,
|
453
463
|
epsilon):
|
454
464
|
"""
|
455
465
|
Performs a crossover operation on two sets of weights and activation functions.
|
@@ -484,6 +494,8 @@ def cross_over(first_parent_W,
|
|
484
494
|
|
485
495
|
fitness_bias (float): A bias factor used to favor fitter parents during crossover operations.
|
486
496
|
|
497
|
+
weight_evolve (bool, optional): Are weights to be evolves or just activation combinations.
|
498
|
+
|
487
499
|
epsilon (float): Small epsilon constant
|
488
500
|
|
489
501
|
Returns:
|
@@ -511,6 +523,7 @@ def cross_over(first_parent_W,
|
|
511
523
|
first_parent_fitness=0.9,
|
512
524
|
second_parent_fitness=0.85,
|
513
525
|
fitness_bias=0.6,
|
526
|
+
weight_evolve=True,
|
514
527
|
epsilon=np.finfo(float).eps
|
515
528
|
)
|
516
529
|
```
|
@@ -544,33 +557,37 @@ def cross_over(first_parent_W,
|
|
544
557
|
undominant_parent_act = first_parent_act
|
545
558
|
succes = first_parent_fitness + epsilon
|
546
559
|
|
547
|
-
|
560
|
+
if weight_evolve is True:
|
548
561
|
|
549
|
-
|
550
|
-
col_cut_start = int(random.uniform(start, col_end))
|
562
|
+
while True:
|
551
563
|
|
552
|
-
|
553
|
-
|
564
|
+
row_cut_start = int(random.uniform(start, row_end))
|
565
|
+
col_cut_start = int(random.uniform(start, col_end))
|
554
566
|
|
555
|
-
|
556
|
-
|
557
|
-
(((row_cut_end + 1) - (row_cut_start + 1) * 2) + ((col_cut_end + 1) - (col_cut_start + 1) * 2) <= half_of_gene)):
|
558
|
-
break
|
559
|
-
|
560
|
-
selection_bias = random.uniform(0, 1)
|
567
|
+
row_cut_end = int(random.uniform(start, row_end))
|
568
|
+
col_cut_end = int(random.uniform(start, col_end))
|
561
569
|
|
562
|
-
|
563
|
-
|
564
|
-
|
570
|
+
if ((row_cut_end > row_cut_start) and
|
571
|
+
(col_cut_end > col_cut_start) and
|
572
|
+
(((row_cut_end + 1) - (row_cut_start + 1) * 2) + ((col_cut_end + 1) - (col_cut_start + 1) * 2) <= half_of_gene)):
|
573
|
+
break
|
574
|
+
|
575
|
+
selection_bias = random.uniform(0, 1)
|
565
576
|
|
566
|
-
|
567
|
-
|
577
|
+
if fitness_bias > selection_bias:
|
578
|
+
row_cut_start = math.floor(row_cut_start * succes)
|
579
|
+
row_cut_end = math.ceil(row_cut_end * succes)
|
568
580
|
|
569
|
-
|
581
|
+
col_cut_start = math.floor(col_cut_start * succes)
|
582
|
+
col_cut_end = math.ceil(col_cut_end * succes)
|
570
583
|
|
571
|
-
|
572
|
-
child_W[row_cut_start:row_cut_end, col_cut_start:col_cut_end] = undominant_parent_W[row_cut_start:row_cut_end, col_cut_start:col_cut_end]
|
584
|
+
child_W = dominant_parent_W
|
573
585
|
|
586
|
+
if cross_over_mode == 'tpm':
|
587
|
+
child_W[row_cut_start:row_cut_end, col_cut_start:col_cut_end] = undominant_parent_W[row_cut_start:row_cut_end, col_cut_start:col_cut_end]
|
588
|
+
|
589
|
+
else: child_W = dominant_parent_W
|
590
|
+
|
574
591
|
if isinstance(dominant_parent_act, str): dominant_parent_act = [dominant_parent_act]
|
575
592
|
if isinstance(undominant_parent_act, str): undominant_parent_act = [undominant_parent_act]
|
576
593
|
|
@@ -633,6 +650,7 @@ def mutation(weight,
|
|
633
650
|
weight_mutate_threshold,
|
634
651
|
genome_fitness,
|
635
652
|
activation_mutate_threshold,
|
653
|
+
weight_evolve,
|
636
654
|
epsilon):
|
637
655
|
"""
|
638
656
|
Performs mutation on the given weight matrix and activation functions.
|
@@ -660,6 +678,8 @@ def mutation(weight,
|
|
660
678
|
|
661
679
|
activation_mutate_threshold (float): Determines max how much activation mutaiton operation applying. (Function automaticly determines to min)
|
662
680
|
|
681
|
+
weight_evolve (bool, optional): Are weights to be mutates or just activation combinations.
|
682
|
+
|
663
683
|
epsilon (float): Small epsilon constant
|
664
684
|
|
665
685
|
Returns:
|
@@ -681,92 +701,94 @@ def mutation(weight,
|
|
681
701
|
|
682
702
|
if isinstance(activations, str): activations = [activations]
|
683
703
|
|
684
|
-
|
685
|
-
potential_weight_mutation = random.uniform(0, 1)
|
704
|
+
if weight_evolve is True:
|
686
705
|
|
687
|
-
|
706
|
+
weight_mutate_prob = 1 - weight_mutate_prob # if prob 0.8 (%80) then 1 - 0.8. Because 0-1 random number probably greater than 0.2
|
707
|
+
potential_weight_mutation = random.uniform(0, 1)
|
688
708
|
|
689
|
-
|
690
|
-
row_end = weight.shape[0]
|
691
|
-
col_end = weight.shape[1]
|
709
|
+
if potential_weight_mutation > weight_mutate_prob:
|
692
710
|
|
693
|
-
|
711
|
+
start = 0
|
712
|
+
row_end = weight.shape[0]
|
713
|
+
col_end = weight.shape[1]
|
694
714
|
|
695
|
-
|
696
|
-
new_threshold = threshold
|
697
|
-
|
698
|
-
for _ in range(max_threshold):
|
699
|
-
|
700
|
-
selected_row = int(random.uniform(start, row_end))
|
701
|
-
selected_col = int(random.uniform(start, col_end))
|
715
|
+
max_threshold = row_end * col_end
|
702
716
|
|
703
|
-
|
704
|
-
new_threshold
|
705
|
-
|
706
|
-
if max_threshold > new_threshold:
|
707
|
-
pass
|
717
|
+
threshold = weight_mutate_threshold * (genome_fitness + epsilon)
|
718
|
+
new_threshold = threshold
|
708
719
|
|
709
|
-
|
710
|
-
|
720
|
+
for _ in range(max_threshold):
|
721
|
+
|
722
|
+
selected_row = int(random.uniform(start, row_end))
|
723
|
+
selected_col = int(random.uniform(start, col_end))
|
711
724
|
|
712
|
-
|
713
|
-
|
725
|
+
weight[selected_row, selected_col] = random.uniform(-1, 1)
|
726
|
+
new_threshold += threshold
|
714
727
|
|
715
|
-
|
728
|
+
if max_threshold > new_threshold:
|
729
|
+
pass
|
716
730
|
|
717
|
-
|
718
|
-
|
719
|
-
max_threshold = len(activations)
|
731
|
+
else:
|
732
|
+
break
|
720
733
|
|
721
|
-
|
734
|
+
activation_mutate_prob = 1 - activation_mutate_prob
|
735
|
+
potential_activation_mutation = random.uniform(0, 1)
|
722
736
|
|
723
|
-
|
724
|
-
all_acts = [item for item in all_activations() if item not in except_this] # SPIRAL AND CIRCULAR ACTIVATION DISCARDED
|
737
|
+
if potential_activation_mutation > activation_mutate_prob:
|
725
738
|
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
for _ in range(max_threshold):
|
739
|
+
genome_fitness += epsilon
|
740
|
+
threshold = abs(activation_mutate_threshold / genome_fitness)
|
741
|
+
max_threshold = len(activations)
|
731
742
|
|
732
|
-
|
733
|
-
potential_activation_delete_prob = random.uniform(0, 1)
|
734
|
-
potential_activation_change_prob = random.uniform(0, 1)
|
743
|
+
new_threshold = threshold
|
735
744
|
|
745
|
+
except_this = ['spiral', 'circular']
|
746
|
+
all_acts = [item for item in all_activations() if item not in except_this] # SPIRAL AND CIRCULAR ACTIVATION DISCARDED
|
747
|
+
|
748
|
+
activation_add_prob = 1 - activation_add_prob
|
749
|
+
activation_delete_prob = 1 - activation_delete_prob
|
750
|
+
activation_change_prob = 1 - activation_change_prob
|
736
751
|
|
737
|
-
|
738
|
-
|
739
|
-
random_index = random.randint(0, len(activations) - 1)
|
740
|
-
activations.pop(random_index)
|
752
|
+
for _ in range(max_threshold):
|
741
753
|
|
754
|
+
potential_activation_add_prob = random.uniform(0, 1)
|
755
|
+
potential_activation_delete_prob = random.uniform(0, 1)
|
756
|
+
potential_activation_change_prob = random.uniform(0, 1)
|
742
757
|
|
743
|
-
if potential_activation_add_prob > activation_add_prob:
|
744
758
|
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
759
|
+
if potential_activation_delete_prob > activation_delete_prob and len(activations) > 1:
|
760
|
+
|
761
|
+
random_index = random.randint(0, len(activations) - 1)
|
762
|
+
activations.pop(random_index)
|
749
763
|
|
750
|
-
except:
|
751
764
|
|
752
|
-
|
753
|
-
activations = []
|
765
|
+
if potential_activation_add_prob > activation_add_prob:
|
754
766
|
|
755
|
-
|
756
|
-
activations.append(all_acts[int(random.uniform(0, len(all_acts)-1))])
|
757
|
-
|
758
|
-
|
759
|
-
if potential_activation_change_prob > activation_change_prob:
|
767
|
+
try:
|
760
768
|
|
761
769
|
random_index_all_act = int(random.uniform(0, len(all_acts)-1))
|
762
|
-
|
770
|
+
activations.append(all_acts[random_index_all_act])
|
763
771
|
|
764
|
-
|
772
|
+
except:
|
765
773
|
|
766
|
-
|
774
|
+
activation = activations
|
775
|
+
activations = []
|
776
|
+
|
777
|
+
activations.append(activation)
|
778
|
+
activations.append(all_acts[int(random.uniform(0, len(all_acts)-1))])
|
779
|
+
|
780
|
+
|
781
|
+
if potential_activation_change_prob > activation_change_prob:
|
782
|
+
|
783
|
+
random_index_all_act = int(random.uniform(0, len(all_acts)-1))
|
784
|
+
random_index_genom_act = int(random.uniform(0, len(activations)-1))
|
785
|
+
|
786
|
+
activations[random_index_genom_act] = all_acts[random_index_all_act]
|
787
|
+
|
788
|
+
new_threshold += threshold
|
767
789
|
|
768
|
-
|
769
|
-
|
790
|
+
if max_threshold > new_threshold: pass
|
791
|
+
else: break
|
770
792
|
|
771
793
|
return weight, activations
|
772
794
|
|
pyerualjetwork/planeat_cuda.py
CHANGED
@@ -75,7 +75,8 @@ def define_genomes(input_shape, output_shape, population_size, dtype=cp.float32)
|
|
75
75
|
def evolver(weights,
|
76
76
|
activation_potentiations,
|
77
77
|
what_gen,
|
78
|
-
fitness,
|
78
|
+
fitness,
|
79
|
+
weight_evolve=True,
|
79
80
|
show_info=False,
|
80
81
|
policy='aggressive',
|
81
82
|
bad_genomes_selection_prob=None,
|
@@ -114,6 +115,8 @@ def evolver(weights,
|
|
114
115
|
fitness (cupy.ndarray): A 1D array containing the fitness values of each genome.
|
115
116
|
The array is used to rank the genomes based on their performance. PLANEAT maximizes or minimizes this fitness based on the `target_fitness` parameter.
|
116
117
|
|
118
|
+
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.
|
119
|
+
|
117
120
|
show_info (bool, optional): If True, prints information about the current generation and the
|
118
121
|
maximum reward obtained. Also shows the current configuration. Default is False.
|
119
122
|
|
@@ -145,6 +148,8 @@ def evolver(weights,
|
|
145
148
|
Must be in the range [0, 1]. Also affects the mutation probability of the best genomes inversely.
|
146
149
|
For example, a value of 0.7 for bad genomes implies 0.3 for best genomes. Default: Determined by `policy`.
|
147
150
|
|
151
|
+
bad_genomes_selection_prob (float, optional): The probability of crossover parents are bad genomes ? [0-1] Default: Determined by `policy`.
|
152
|
+
|
148
153
|
activation_mutate_prob (float, optional): The probability of applying mutation to the activation functions.
|
149
154
|
Must be in the range [0, 1]. Default is 0.5 (50%).
|
150
155
|
|
@@ -260,6 +265,8 @@ def evolver(weights,
|
|
260
265
|
else:
|
261
266
|
raise ValueError("genome population size must be even number. for example: not 99, make 100 or 98.")
|
262
267
|
|
268
|
+
if weight_evolve is False: origin_weights = cp.copy(weights)
|
269
|
+
|
263
270
|
### FITNESS LIST IS SORTED IN ASCENDING ORDER, AND THE WEIGHT AND ACTIVATIONS OF EACH GENOME ARE SORTED ACCORDING TO THIS ORDER:
|
264
271
|
|
265
272
|
sort_indices = cp.argsort(fitness)
|
@@ -323,6 +330,7 @@ def evolver(weights,
|
|
323
330
|
first_parent_fitness=best_fitness,
|
324
331
|
fitness_bias=fitness_bias,
|
325
332
|
second_parent_fitness=normalized_fitness[s_i],
|
333
|
+
weight_evolve=weight_evolve,
|
326
334
|
epsilon=epsilon
|
327
335
|
)
|
328
336
|
|
@@ -350,6 +358,7 @@ def evolver(weights,
|
|
350
358
|
weight_mutate_threshold=weight_mutate_threshold,
|
351
359
|
genome_fitness=normalized_fitness[fitness_index],
|
352
360
|
activation_mutate_threshold=activation_mutate_threshold,
|
361
|
+
weight_evolve=weight_evolve,
|
353
362
|
epsilon=epsilon
|
354
363
|
)
|
355
364
|
|
@@ -394,6 +403,7 @@ def evolver(weights,
|
|
394
403
|
print(" BEST GENOME INDEX: ", str(0))
|
395
404
|
print(" NOTE: The returned genome at the first index is the best of the previous generation." + '\n')
|
396
405
|
|
406
|
+
if weight_evolve is False: weights = origin_weights
|
397
407
|
|
398
408
|
return weights, activation_potentiations
|
399
409
|
|
@@ -450,6 +460,7 @@ def cross_over(first_parent_W,
|
|
450
460
|
first_parent_fitness,
|
451
461
|
second_parent_fitness,
|
452
462
|
fitness_bias,
|
463
|
+
weight_evolve,
|
453
464
|
epsilon):
|
454
465
|
"""
|
455
466
|
Performs a crossover operation on two sets of weights and activation functions.
|
@@ -484,6 +495,8 @@ def cross_over(first_parent_W,
|
|
484
495
|
|
485
496
|
fitness_bias (float): A bias factor used to favor fitter parents during crossover operations.
|
486
497
|
|
498
|
+
weight_evolve (bool, optional): Are weights to be evolves or just activation combinations.
|
499
|
+
|
487
500
|
epsilon (float): Small epsilon constant
|
488
501
|
|
489
502
|
Returns:
|
@@ -511,6 +524,7 @@ def cross_over(first_parent_W,
|
|
511
524
|
first_parent_fitness=0.9,
|
512
525
|
second_parent_fitness=0.85,
|
513
526
|
fitness_bias=0.6,
|
527
|
+
weight_evolve=True,
|
514
528
|
epsilon=cp.finfo(float).eps
|
515
529
|
)
|
516
530
|
```
|
@@ -544,33 +558,35 @@ def cross_over(first_parent_W,
|
|
544
558
|
undominant_parent_act = first_parent_act
|
545
559
|
succes = first_parent_fitness + epsilon
|
546
560
|
|
547
|
-
|
548
|
-
|
549
|
-
row_cut_start = int(random.uniform(start, row_end))
|
550
|
-
col_cut_start = int(random.uniform(start, col_end))
|
561
|
+
if weight_evolve is True:
|
562
|
+
while True:
|
551
563
|
|
552
|
-
|
553
|
-
|
564
|
+
row_cut_start = int(random.uniform(start, row_end))
|
565
|
+
col_cut_start = int(random.uniform(start, col_end))
|
554
566
|
|
555
|
-
|
556
|
-
|
557
|
-
(((row_cut_end + 1) - (row_cut_start + 1) * 2) + ((col_cut_end + 1) - (col_cut_start + 1) * 2) <= half_of_gene)):
|
558
|
-
break
|
559
|
-
|
560
|
-
selection_bias = random.uniform(0, 1)
|
567
|
+
row_cut_end = int(random.uniform(start, row_end))
|
568
|
+
col_cut_end = int(random.uniform(start, col_end))
|
561
569
|
|
562
|
-
|
563
|
-
|
564
|
-
|
570
|
+
if ((row_cut_end > row_cut_start) and
|
571
|
+
(col_cut_end > col_cut_start) and
|
572
|
+
(((row_cut_end + 1) - (row_cut_start + 1) * 2) + ((col_cut_end + 1) - (col_cut_start + 1) * 2) <= half_of_gene)):
|
573
|
+
break
|
574
|
+
|
575
|
+
selection_bias = random.uniform(0, 1)
|
565
576
|
|
566
|
-
|
567
|
-
|
577
|
+
if fitness_bias > selection_bias:
|
578
|
+
row_cut_start = math.floor(row_cut_start * succes)
|
579
|
+
row_cut_end = math.ceil(row_cut_end * succes)
|
568
580
|
|
569
|
-
|
581
|
+
col_cut_start = math.floor(col_cut_start * succes)
|
582
|
+
col_cut_end = math.ceil(col_cut_end * succes)
|
570
583
|
|
571
|
-
|
572
|
-
child_W[row_cut_start:row_cut_end, col_cut_start:col_cut_end] = undominant_parent_W[row_cut_start:row_cut_end, col_cut_start:col_cut_end]
|
584
|
+
child_W = dominant_parent_W
|
573
585
|
|
586
|
+
if cross_over_mode == 'tpm':
|
587
|
+
child_W[row_cut_start:row_cut_end, col_cut_start:col_cut_end] = undominant_parent_W[row_cut_start:row_cut_end, col_cut_start:col_cut_end]
|
588
|
+
|
589
|
+
else: child_W = dominant_parent_W
|
574
590
|
|
575
591
|
if isinstance(dominant_parent_act, str): dominant_parent_act = [dominant_parent_act]
|
576
592
|
if isinstance(undominant_parent_act, str): undominant_parent_act = [undominant_parent_act]
|
@@ -635,6 +651,7 @@ def mutation(weight,
|
|
635
651
|
weight_mutate_threshold,
|
636
652
|
genome_fitness,
|
637
653
|
activation_mutate_threshold,
|
654
|
+
weight_evolve,
|
638
655
|
epsilon):
|
639
656
|
"""
|
640
657
|
Performs mutation on the given weight matrix and activation functions.
|
@@ -662,6 +679,8 @@ def mutation(weight,
|
|
662
679
|
|
663
680
|
activation_mutate_threshold (float): Determines max how much activation mutaiton operation applying. (Function automaticly determines to min)
|
664
681
|
|
682
|
+
weight_evolve (bool, optional): Are weights to be mutates or just activation combinations.
|
683
|
+
|
665
684
|
epsilon (float): Small epsilon constant
|
666
685
|
|
667
686
|
Returns:
|
@@ -683,91 +702,93 @@ def mutation(weight,
|
|
683
702
|
|
684
703
|
if isinstance(activations, str): activations = [activations]
|
685
704
|
|
686
|
-
|
687
|
-
potential_weight_mutation = random.uniform(0, 1)
|
688
|
-
|
689
|
-
if potential_weight_mutation > weight_mutate_prob:
|
690
|
-
|
691
|
-
start = 0
|
692
|
-
row_end = weight.shape[0]
|
693
|
-
col_end = weight.shape[1]
|
694
|
-
|
695
|
-
max_threshold = row_end * col_end
|
705
|
+
if weight_evolve is True:
|
696
706
|
|
697
|
-
|
698
|
-
|
707
|
+
weight_mutate_prob = 1 - weight_mutate_prob # if prob 0.8 (%80) then 1 - 0.8. Because 0-1 random number probably greater than 0.2
|
708
|
+
potential_weight_mutation = random.uniform(0, 1)
|
699
709
|
|
700
|
-
|
701
|
-
|
702
|
-
selected_row = int(random.uniform(start, row_end))
|
703
|
-
selected_col = int(random.uniform(start, col_end))
|
710
|
+
if potential_weight_mutation > weight_mutate_prob:
|
704
711
|
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
if max_threshold > new_threshold:
|
709
|
-
pass
|
712
|
+
start = 0
|
713
|
+
row_end = weight.shape[0]
|
714
|
+
col_end = weight.shape[1]
|
710
715
|
|
711
|
-
|
712
|
-
break
|
713
|
-
|
714
|
-
activation_mutate_prob = 1 - activation_mutate_prob
|
715
|
-
potential_activation_mutation = random.uniform(0, 1)
|
716
|
-
|
717
|
-
if potential_activation_mutation > activation_mutate_prob:
|
718
|
-
|
719
|
-
genome_fitness += epsilon
|
720
|
-
threshold = abs(activation_mutate_threshold / genome_fitness)
|
721
|
-
max_threshold = len(activations)
|
716
|
+
max_threshold = row_end * col_end
|
722
717
|
|
718
|
+
threshold = weight_mutate_threshold * (genome_fitness + epsilon)
|
723
719
|
new_threshold = threshold
|
724
|
-
|
725
|
-
except_this = ['spiral', 'circular']
|
726
|
-
all_acts = [item for item in all_activations() if item not in except_this] # SPIRAL AND CIRCULAR ACTIVATION DISCARDED
|
727
|
-
|
728
|
-
activation_add_prob = 1 - activation_add_prob
|
729
|
-
activation_delete_prob = 1 - activation_delete_prob
|
730
|
-
activation_change_prob = 1 - activation_change_prob
|
731
720
|
|
732
721
|
for _ in range(max_threshold):
|
722
|
+
|
723
|
+
selected_row = int(random.uniform(start, row_end))
|
724
|
+
selected_col = int(random.uniform(start, col_end))
|
733
725
|
|
734
|
-
|
735
|
-
|
736
|
-
potential_activation_change_prob = random.uniform(0, 1)
|
726
|
+
weight[selected_row, selected_col] = random.uniform(-1, 1)
|
727
|
+
new_threshold += threshold
|
737
728
|
|
729
|
+
if max_threshold > new_threshold:
|
730
|
+
pass
|
738
731
|
|
739
|
-
|
740
|
-
|
741
|
-
random_index = random.randint(0, len(activations) - 1)
|
742
|
-
activations.pop(random_index)
|
743
|
-
|
732
|
+
else:
|
733
|
+
break
|
744
734
|
|
745
|
-
|
735
|
+
activation_mutate_prob = 1 - activation_mutate_prob
|
736
|
+
potential_activation_mutation = random.uniform(0, 1)
|
746
737
|
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
738
|
+
if potential_activation_mutation > activation_mutate_prob:
|
739
|
+
|
740
|
+
genome_fitness += epsilon
|
741
|
+
threshold = abs(activation_mutate_threshold / genome_fitness)
|
742
|
+
max_threshold = len(activations)
|
751
743
|
|
752
|
-
|
744
|
+
new_threshold = threshold
|
745
|
+
|
746
|
+
except_this = ['spiral', 'circular']
|
747
|
+
all_acts = [item for item in all_activations() if item not in except_this] # SPIRAL AND CIRCULAR ACTIVATION DISCARDED
|
748
|
+
|
749
|
+
activation_add_prob = 1 - activation_add_prob
|
750
|
+
activation_delete_prob = 1 - activation_delete_prob
|
751
|
+
activation_change_prob = 1 - activation_change_prob
|
753
752
|
|
754
|
-
|
755
|
-
activations = []
|
753
|
+
for _ in range(max_threshold):
|
756
754
|
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
755
|
+
potential_activation_add_prob = random.uniform(0, 1)
|
756
|
+
potential_activation_delete_prob = random.uniform(0, 1)
|
757
|
+
potential_activation_change_prob = random.uniform(0, 1)
|
758
|
+
|
759
|
+
|
760
|
+
if potential_activation_delete_prob > activation_delete_prob and len(activations) > 1:
|
761
|
+
|
762
|
+
random_index = random.randint(0, len(activations) - 1)
|
763
|
+
activations.pop(random_index)
|
764
|
+
|
765
|
+
|
766
|
+
if potential_activation_add_prob > activation_add_prob:
|
767
|
+
|
768
|
+
try:
|
761
769
|
|
762
770
|
random_index_all_act = int(random.uniform(0, len(all_acts)-1))
|
763
|
-
|
771
|
+
activations.append(all_acts[random_index_all_act])
|
764
772
|
|
765
|
-
|
773
|
+
except:
|
766
774
|
|
767
|
-
|
775
|
+
activation = activations
|
776
|
+
activations = []
|
777
|
+
|
778
|
+
activations.append(activation)
|
779
|
+
activations.append(all_acts[int(random.uniform(0, len(all_acts)-1))])
|
780
|
+
|
781
|
+
if potential_activation_change_prob > activation_change_prob:
|
782
|
+
|
783
|
+
random_index_all_act = int(random.uniform(0, len(all_acts)-1))
|
784
|
+
random_index_genom_act = int(random.uniform(0, len(activations)-1))
|
785
|
+
|
786
|
+
activations[random_index_genom_act] = all_acts[random_index_all_act]
|
787
|
+
|
788
|
+
new_threshold += threshold
|
768
789
|
|
769
|
-
|
770
|
-
|
790
|
+
if max_threshold > new_threshold: pass
|
791
|
+
else: break
|
771
792
|
|
772
793
|
return weight, activations
|
773
794
|
|
pyerualjetwork/visualizations.py
CHANGED
@@ -300,9 +300,9 @@ def draw_activations(x_train, activation):
|
|
300
300
|
|
301
301
|
elif activation == 'cubic_quadratic':
|
302
302
|
result = af.cubic_quadratic(x_train)
|
303
|
-
|
304
|
-
elif activation == 'exp_cubic':
|
305
|
-
result = af.exp_cubic(x_train)
|
303
|
+
|
304
|
+
#elif activation == 'exp_cubic':
|
305
|
+
#result = af.exp_cubic(x_train)
|
306
306
|
|
307
307
|
elif activation == 'sine_square':
|
308
308
|
result = af.sine_square(x_train)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pyerualjetwork
|
3
|
-
Version: 4.3.
|
3
|
+
Version: 4.3.13
|
4
4
|
Summary: PyerualJetwork is a machine learning library supported with GPU(CUDA) acceleration written in Python for professionals and researchers including with PLAN algorithm, PLANEAT algorithm (genetic optimization). Also includes data pre-process and memory manegament
|
5
5
|
Author: Hasan Can Beydili
|
6
6
|
Author-email: tchasancan@gmail.com
|
@@ -1,4 +1,4 @@
|
|
1
|
-
pyerualjetwork/__init__.py,sha256=
|
1
|
+
pyerualjetwork/__init__.py,sha256=8QxVhLrF9q38cHUgWG-XtQMIkD9w6SgPTgnyjl5PiG8,1280
|
2
2
|
pyerualjetwork/activation_functions.py,sha256=Ms0AGBqkJuCA42ht64MSQnO54Td_1eDGquedpoBDVbc,7642
|
3
3
|
pyerualjetwork/activation_functions_cuda.py,sha256=5y1Ti3GDfDteQDCUmODwe7tAyDAUlDTKmIikChQ8d6g,7772
|
4
4
|
pyerualjetwork/data_operations.py,sha256=Flteouu6rfSo2uHMqBHuzO02dXmbNa-I5qWmUpGTZ5Y,14760
|
@@ -12,14 +12,14 @@ pyerualjetwork/metrics.py,sha256=q7MkhnZDRbCjFBDDfUgrl8lBYnUT_1ro1LxeBq105pI,607
|
|
12
12
|
pyerualjetwork/metrics_cuda.py,sha256=73h9GC7XwmnFCVzFEEiPQfF8CwHIz2wsCbxpZrJtYgw,5061
|
13
13
|
pyerualjetwork/model_operations.py,sha256=MCSCNYiiICRVZITobtS3ZIWmH5Q9gjyELuH32sAdgg4,12649
|
14
14
|
pyerualjetwork/model_operations_cuda.py,sha256=NT01BK5nrDYE7H1x3KnSI8gmx0QTGGB0mP_LqEb1uuU,13157
|
15
|
-
pyerualjetwork/plan.py,sha256=
|
16
|
-
pyerualjetwork/plan_cuda.py,sha256=
|
17
|
-
pyerualjetwork/planeat.py,sha256=
|
18
|
-
pyerualjetwork/planeat_cuda.py,sha256=
|
15
|
+
pyerualjetwork/plan.py,sha256=X2mzc9s36xCzUy0SzKeimbeVVlvajhOpXDaME8x83yQ,22974
|
16
|
+
pyerualjetwork/plan_cuda.py,sha256=l-2xK2vu-SM64EEOOA8GXsfbXTUNcSL6Sc3ora5Ze3k,23966
|
17
|
+
pyerualjetwork/planeat.py,sha256=oAu0a2rs6BQ2HUpLjKFR4m7xDbhUVOzLstop75u35Tg,38889
|
18
|
+
pyerualjetwork/planeat_cuda.py,sha256=E_pJEsNKfiF97FvGZGSsxmdqzLAJub05enmneymozcg,38922
|
19
19
|
pyerualjetwork/ui.py,sha256=wu2BhU1k-w3Kcho5Jtq4SEKe68ftaUeRGneUOSCVDjU,575
|
20
|
-
pyerualjetwork/visualizations.py,sha256=
|
20
|
+
pyerualjetwork/visualizations.py,sha256=1QSisYAaGnO5kug6qo1qOssTkQM-MgR7L8h4c3sczzU,28294
|
21
21
|
pyerualjetwork/visualizations_cuda.py,sha256=PYRqj4QYUbuYMYcNwO8yaTPB-jK7E6kZHhTrAi0lwPU,28749
|
22
|
-
pyerualjetwork-4.3.
|
23
|
-
pyerualjetwork-4.3.
|
24
|
-
pyerualjetwork-4.3.
|
25
|
-
pyerualjetwork-4.3.
|
22
|
+
pyerualjetwork-4.3.13.dist-info/METADATA,sha256=yGTaFrahQ_b369UOVc11vEtUGG3My1ykykLcJ7e3Jmg,7506
|
23
|
+
pyerualjetwork-4.3.13.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
24
|
+
pyerualjetwork-4.3.13.dist-info/top_level.txt,sha256=BRyt62U_r3ZmJpj-wXNOoA345Bzamrj6RbaWsyW4tRg,15
|
25
|
+
pyerualjetwork-4.3.13.dist-info/RECORD,,
|
File without changes
|
File without changes
|