pyerualjetwork 4.3.8.dev3__py3-none-any.whl → 4.3.8.dev4__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.
@@ -1,4 +1,4 @@
1
- __version__ = "4.3.8dev3"
1
+ __version__ = "4.3.8dev4"
2
2
  __update__ = "* Changes: https://github.com/HCB06/PyerualJetwork/blob/main/CHANGES\n* PyerualJetwork Homepage: https://github.com/HCB06/PyerualJetwork/tree/main\n* PyerualJetwork document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PyerualJetwork/PYERUALJETWORK_USER_MANUEL_AND_LEGAL_INFORMATION(EN).pdf\n* YouTube tutorials: https://www.youtube.com/@HasanCanBeydili"
3
3
 
4
4
  def print_version(__version__):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyerualjetwork
3
- Version: 4.3.8.dev3
3
+ Version: 4.3.8.dev4
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=TigQhP6yP1luXiX5fdCVYqBZQTjPRdboBfy_KU5-g_4,643
1
+ pyerualjetwork/__init__.py,sha256=tTsCaO21gpTHXANBa1BxXVjtXNtwRBZbEgajdSreUyc,643
2
2
  pyerualjetwork/activation_functions.py,sha256=AR91fQV2W2rc-Qb4Yp7b8ucYpGjwyQUewO-M-lyEMs8,7729
3
3
  pyerualjetwork/activation_functions_cuda.py,sha256=ztIw6rMR4t1289_TPIGYwE6qarl_YbSOGj5Ep3rUMqs,11803
4
4
  pyerualjetwork/data_operations.py,sha256=Flteouu6rfSo2uHMqBHuzO02dXmbNa-I5qWmUpGTZ5Y,14760
@@ -18,7 +18,7 @@ pyerualjetwork/planeat_cuda.py,sha256=QNHCQLkR0MNFqyN2iHAtC7cbf8qZiD3p_54YH3lnMF
18
18
  pyerualjetwork/ui.py,sha256=wu2BhU1k-w3Kcho5Jtq4SEKe68ftaUeRGneUOSCVDjU,575
19
19
  pyerualjetwork/visualizations.py,sha256=VL00sX2DZz83F__PyEJH9s1LizuXpOBzWjnoSjMJIJ0,28770
20
20
  pyerualjetwork/visualizations_cuda.py,sha256=KbMhfsLlxujy_i3QrwCf734Q-k6d7Zn_7CEbm3gzK9w,29186
21
- pyerualjetwork_afterburner/__init__.py,sha256=W9d7H3PMu6MRcdGYPHpUa0q9Kx7-ogu5xLq1g928y64,655
21
+ pyerualjetwork_afterburner/__init__.py,sha256=Pw-QCXxnDb7n0onhtNr3b3rW1p44D68garrl-OJdouQ,655
22
22
  pyerualjetwork_afterburner/activation_functions.py,sha256=bKf00lsuuLJNO-4vVp4OqBi4zJ-qZ8L3v-vl52notkY,7721
23
23
  pyerualjetwork_afterburner/activation_functions_cuda.py,sha256=5y1Ti3GDfDteQDCUmODwe7tAyDAUlDTKmIikChQ8d6g,7772
24
24
  pyerualjetwork_afterburner/data_operations.py,sha256=Flteouu6rfSo2uHMqBHuzO02dXmbNa-I5qWmUpGTZ5Y,14760
@@ -31,14 +31,14 @@ pyerualjetwork_afterburner/metrics.py,sha256=q7MkhnZDRbCjFBDDfUgrl8lBYnUT_1ro1Lx
31
31
  pyerualjetwork_afterburner/metrics_cuda.py,sha256=73h9GC7XwmnFCVzFEEiPQfF8CwHIz2wsCbxpZrJtYgw,5061
32
32
  pyerualjetwork_afterburner/model_operations.py,sha256=MCSCNYiiICRVZITobtS3ZIWmH5Q9gjyELuH32sAdgg4,12649
33
33
  pyerualjetwork_afterburner/model_operations_cuda.py,sha256=NT01BK5nrDYE7H1x3KnSI8gmx0QTGGB0mP_LqEb1uuU,13157
34
- pyerualjetwork_afterburner/plan.py,sha256=Gxv8ii4brTYMzzFZBP-X6kkwc6w6vtTPiMmqVOAqoq8,21972
34
+ pyerualjetwork_afterburner/plan.py,sha256=EOXngujG7DQRf3cooFigKB7heQsEoK96JtrcKivT_pE,22449
35
35
  pyerualjetwork_afterburner/plan_cuda.py,sha256=fg5YunEuBE7sK6q9paP_yAGONr9x0e19oF0J0DucejM,23380
36
36
  pyerualjetwork_afterburner/planeat.py,sha256=Lq5R0aMS4UIdZdbUKsKDv5g0WLwYryomR3IQYb8vAa4,37573
37
- pyerualjetwork_afterburner/planeat_cuda.py,sha256=SG7Oq1F2m3lJBbG9cgmu7q_ApmwSn2SvTpcbtEVAoDE,37630
37
+ pyerualjetwork_afterburner/planeat_cuda.py,sha256=VbeaoKlqquKDLcRaQHdoERvoxzO75Day0RgJtOSU9wk,38898
38
38
  pyerualjetwork_afterburner/ui.py,sha256=wu2BhU1k-w3Kcho5Jtq4SEKe68ftaUeRGneUOSCVDjU,575
39
39
  pyerualjetwork_afterburner/visualizations.py,sha256=1SKMZaJ80OD2qHUyMxW1IOv8zwmxzMPxclfbeq1Xr4g,28772
40
40
  pyerualjetwork_afterburner/visualizations_cuda.py,sha256=KbMhfsLlxujy_i3QrwCf734Q-k6d7Zn_7CEbm3gzK9w,29186
41
- pyerualjetwork-4.3.8.dev3.dist-info/METADATA,sha256=VFNiB4kXQ8sU6wa_9uGjkHi_s-b-rzCY_wIJOLbnALM,8384
42
- pyerualjetwork-4.3.8.dev3.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
43
- pyerualjetwork-4.3.8.dev3.dist-info/top_level.txt,sha256=uK64ge08QQoPuXM3aiRVPgiQQtl8Fxm2-HieIut5Lwo,42
44
- pyerualjetwork-4.3.8.dev3.dist-info/RECORD,,
41
+ pyerualjetwork-4.3.8.dev4.dist-info/METADATA,sha256=4Gq7RqhoiGuEirXF6ZFFgs2fyZnZm46lQxj5IMsO9JU,8384
42
+ pyerualjetwork-4.3.8.dev4.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
43
+ pyerualjetwork-4.3.8.dev4.dist-info/top_level.txt,sha256=uK64ge08QQoPuXM3aiRVPgiQQtl8Fxm2-HieIut5Lwo,42
44
+ pyerualjetwork-4.3.8.dev4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
- __version__ = "4.3.8dev3-afterburner"
1
+ __version__ = "4.3.8dev4-afterburner"
2
2
  __update__ = "* Changes: https://github.com/HCB06/PyerualJetwork/blob/main/CHANGES\n* PyerualJetwork Homepage: https://github.com/HCB06/PyerualJetwork/tree/main\n* PyerualJetwork document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PyerualJetwork/PYERUALJETWORK_USER_MANUEL_AND_LEGAL_INFORMATION(EN).pdf\n* YouTube tutorials: https://www.youtube.com/@HasanCanBeydili"
3
3
 
4
4
  def print_version(__version__):
@@ -78,7 +78,7 @@ def fit(
78
78
  return normalization(LTPW, dtype=dtype)
79
79
 
80
80
 
81
- def learner(x_train, y_train, optimizer, fit_start, strategy='accuracy', gen=None, batch_size=1,
81
+ def learner(x_train, y_train, optimizer, fit_start, strategy='accuracy', gen=None, batch_size=1, pop_size=None,
82
82
  neural_web_history=False, show_current_activations=False,
83
83
  neurons_history=False, early_stop=False, loss='categorical_crossentropy', show_history=False,
84
84
  interval=33.33, target_acc=None, target_loss=None,
@@ -123,6 +123,8 @@ def learner(x_train, y_train, optimizer, fit_start, strategy='accuracy', gen=Non
123
123
 
124
124
  batch_size (float, optional): Batch size is used in the prediction process to receive train feedback by dividing the test data into chunks and selecting activations based on randomly chosen partitions. This process reduces computational cost and time while still covering the entire test set due to random selection, so it doesn't significantly impact accuracy. For example, a batch size of 0.08 means each train batch represents 8% of the train set. Default is 1. (%100 of train)
125
125
 
126
+ pop_size (int, optional): Population size of each generation. Default: count of activation functions
127
+
126
128
  early_stop (bool, optional): If True, implements early stopping during training.(If accuracy not improves in two gen stops learning.) Default is False.
127
129
 
128
130
  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
@@ -156,14 +158,19 @@ def learner(x_train, y_train, optimizer, fit_start, strategy='accuracy', gen=Non
156
158
 
157
159
  data = 'Train'
158
160
 
159
- activation_potentiation = all_activations()
161
+ except_this = ['spiral', 'circular']
162
+ activation_potentiation = [item for item in all_activations() if item not in except_this]
160
163
  activation_potentiation_len = len(activation_potentiation)
161
164
 
162
165
  # Pre-checks
163
166
 
167
+ if pop_size is None: pop_size = activation_potentiation_len
168
+
164
169
  x_train = x_train.astype(dtype, copy=False)
165
170
  y_train = optimize_labels(y_train, cuda=False)
166
171
 
172
+ if pop_size < activation_potentiation_len: raise ValueError(f"pop_size must be higher or equal to {activation_potentiation_len}")
173
+
167
174
  if gen is None:
168
175
  gen = activation_potentiation_len
169
176
 
@@ -192,16 +199,16 @@ def learner(x_train, y_train, optimizer, fit_start, strategy='accuracy', gen=Non
192
199
 
193
200
  progress = initialize_loading_bar(total=activation_potentiation_len, desc="", ncols=ncols, bar_format=bar_format_learner)
194
201
 
195
- if fit_start is False:
196
- weight_pop, act_pop = define_genomes(input_shape=len(x_train[0]), output_shape=len(y_train[0]), population_size=activation_potentiation_len, dtype=dtype)
202
+ if fit_start is False or pop_size > activation_potentiation_len:
203
+ weight_pop, act_pop = define_genomes(input_shape=len(x_train[0]), output_shape=len(y_train[0]), population_size=pop_size, dtype=dtype)
197
204
 
198
205
  if start_this_act is not None and start_this_W is not None:
199
206
  weight_pop[0] = start_this_W
200
207
  act_pop[0] = start_this_act
201
208
 
202
209
  else:
203
- weight_pop = []
204
- act_pop = []
210
+ weight_pop = [0] * pop_size
211
+ act_pop = [0] * pop_size
205
212
 
206
213
  for i in range(gen):
207
214
  postfix_dict["Gen"] = str(i+1) + '/' + str(gen)
@@ -211,14 +218,14 @@ def learner(x_train, y_train, optimizer, fit_start, strategy='accuracy', gen=Non
211
218
  progress.last_print_n = 0
212
219
  progress.update(0)
213
220
 
214
- for j in range(activation_potentiation_len):
221
+ for j in range(pop_size):
215
222
 
216
223
  x_train_batch, y_train_batch = batcher(x_train, y_train, batch_size=batch_size)
217
224
 
218
- if fit_start is True and i == 0:
219
- act_pop.append(activation_potentiation[j])
225
+ if fit_start is True and i == 0 and j < activation_potentiation_len:
226
+ act_pop[j] = activation_potentiation[j]
220
227
  W = fit(x_train_batch, y_train_batch, activation_potentiation=act_pop[-1], dtype=dtype)
221
- weight_pop.append(W)
228
+ weight_pop[j] = W
222
229
 
223
230
  model = evaluate(x_train_batch, y_train_batch, W=weight_pop[j], activation_potentiation=act_pop[j])
224
231
  acc = model[get_acc()]
@@ -16,6 +16,9 @@ import cupy as cp
16
16
  import numpy as np
17
17
  import random
18
18
  import math
19
+ from numba import cuda
20
+ import concurrent.futures
21
+ from functools import partial
19
22
 
20
23
 
21
24
  ### LIBRARY IMPORTS ###
@@ -438,20 +441,20 @@ def evaluate(x_population, weights, activation_potentiations):
438
441
  return result
439
442
 
440
443
 
441
- def cross_over(first_parent_W,
442
- second_parent_W,
443
- first_parent_act,
444
- second_parent_act,
445
- cross_over_mode,
446
- activation_selection_add_prob,
447
- activation_selection_change_prob,
448
- activation_selection_threshold,
449
- bad_genomes_selection_prob,
450
- first_parent_fitness,
451
- second_parent_fitness,
452
- fitness_bias,
453
- epsilon):
454
- """
444
+ @cuda.jit
445
+ def crossover_kernel(undominant_W, child_W, row_start, row_end, col_start, col_end):
446
+ idx = cuda.grid(1)
447
+ if idx < (row_end - row_start) * (col_end - col_start):
448
+ row = row_start + (idx // (col_end - col_start))
449
+ col = col_start + (idx % (col_end - col_start))
450
+ if row < row_end and col < col_end:
451
+ child_W[row, col] = undominant_W[row, col]
452
+
453
+ def cross_over(first_parent_W, second_parent_W, first_parent_act, second_parent_act,
454
+ first_parent_fitness, second_parent_fitness, bad_genomes_selection_prob,
455
+ fitness_bias, cross_over_mode, activation_selection_add_prob,
456
+ activation_selection_change_prob, activation_selection_threshold, epsilon=1e-10):
457
+ """
455
458
  Performs a crossover operation on two sets of weights and activation functions.
456
459
  This function combines two individuals (represented by their weights and activation functions)
457
460
  to create a new individual by exchanging parts of their weight matrices and activation functions.
@@ -513,131 +516,128 @@ def cross_over(first_parent_W,
513
516
  fitness_bias=0.6,
514
517
  epsilon=cp.finfo(float).eps
515
518
  )
516
- ```
517
- """
518
-
519
- ### THE GIVEN GENOMES' WEIGHTS ARE RANDOMLY SELECTED AND COMBINED OVER A RANDOM RANGE. SIMILARLY, THEIR ACTIVATIONS ARE COMBINED. A NEW GENOME IS RETURNED WITH THE COMBINED WEIGHTS FIRST, FOLLOWED BY THE ACTIVATIONS:
520
-
521
- start = 0
522
-
523
- row_end = first_parent_W.shape[0]
524
- col_end = first_parent_W.shape[1]
525
-
526
- total_gene = row_end * col_end
527
- half_of_gene = int(total_gene / 2)
528
-
529
- decision = dominant_parent_selection(bad_genomes_selection_prob)
530
-
531
- if decision == 'first_parent':
532
- dominant_parent_W = cp.copy(first_parent_W)
533
- dominant_parent_act = first_parent_act
534
-
535
- undominant_parent_W = cp.copy(second_parent_W)
536
- undominant_parent_act = second_parent_act
537
- succes = second_parent_fitness + epsilon
538
-
539
- elif decision == 'second_parent':
540
- dominant_parent_W = cp.copy(second_parent_W)
541
- dominant_parent_act = second_parent_act
542
-
543
- undominant_parent_W = cp.copy(first_parent_W)
544
- undominant_parent_act = first_parent_act
545
- succes = first_parent_fitness + epsilon
546
-
547
- while True:
548
-
549
- row_cut_start = int(random.uniform(start, row_end))
550
- col_cut_start = int(random.uniform(start, col_end))
551
-
552
- row_cut_end = int(random.uniform(start, row_end))
553
- col_cut_end = int(random.uniform(start, col_end))
554
-
555
- if ((row_cut_end > row_cut_start) and
556
- (col_cut_end > col_cut_start) and
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)
561
-
562
- if fitness_bias > selection_bias:
563
- row_cut_start = math.floor(row_cut_start * succes)
564
- row_cut_end = math.ceil(row_cut_end * succes)
565
-
566
- col_cut_start = math.floor(col_cut_start * succes)
567
- col_cut_end = math.ceil(col_cut_end * succes)
568
-
569
- child_W = dominant_parent_W
570
-
571
- if cross_over_mode == 'tpm':
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]
573
-
574
-
575
- if isinstance(dominant_parent_act, str): dominant_parent_act = [dominant_parent_act]
576
- if isinstance(undominant_parent_act, str): undominant_parent_act = [undominant_parent_act]
577
-
578
- child_act = list(np.copy(dominant_parent_act))
579
-
580
- 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
581
- potential_activation_selection_add = random.uniform(0, 1)
582
-
583
- if potential_activation_selection_add > activation_selection_add_prob:
584
-
585
- threshold = abs(activation_selection_threshold / succes)
586
- new_threshold = threshold
587
-
588
- while True:
589
-
590
- random_index = int(random.uniform(0, len(undominant_parent_act)-1))
591
- random_undominant_activation = undominant_parent_act[random_index]
592
-
593
- child_act.append(random_undominant_activation)
594
- new_threshold += threshold
595
-
596
- if len(dominant_parent_act) > new_threshold:
597
- pass
598
-
599
- else:
519
+ ```"""
520
+
521
+ d_first_parent_W = cp.copy(first_parent_W)
522
+ d_second_parent_W = cp.copy(second_parent_W)
523
+
524
+ row_end = first_parent_W.shape[0]
525
+ col_end = first_parent_W.shape[1]
526
+ total_gene = row_end * col_end
527
+ half_of_gene = int(total_gene / 2)
528
+
529
+ decision = dominant_parent_selection(bad_genomes_selection_prob)
530
+ if decision == 'first_parent':
531
+ dominant_parent_W = cp.copy(d_first_parent_W)
532
+ dominant_parent_act = first_parent_act
533
+ undominant_parent_W = cp.copy(d_second_parent_W)
534
+ undominant_parent_act = second_parent_act
535
+ succes = second_parent_fitness + epsilon
536
+ else:
537
+ dominant_parent_W = cp.copy(d_second_parent_W)
538
+ dominant_parent_act = second_parent_act
539
+ undominant_parent_W = cp.copy(d_first_parent_W)
540
+ undominant_parent_act = first_parent_act
541
+ succes = first_parent_fitness + epsilon
542
+
543
+ while True:
544
+ row_cut_start = int(random.uniform(0, row_end))
545
+ col_cut_start = int(random.uniform(0, col_end))
546
+ row_cut_end = int(random.uniform(0, row_end))
547
+ col_cut_end = int(random.uniform(0, col_end))
548
+
549
+ if ((row_cut_end > row_cut_start) and
550
+ (col_cut_end > col_cut_start) and
551
+ (((row_cut_end + 1) - (row_cut_start + 1) * 2) +
552
+ ((col_cut_end + 1) - (col_cut_start + 1) * 2) <= half_of_gene)):
600
553
  break
554
+
555
+ selection_bias = random.uniform(0, 1)
556
+ if fitness_bias > selection_bias:
557
+ row_cut_start = math.floor(row_cut_start * succes)
558
+ row_cut_end = math.ceil(row_cut_end * succes)
559
+ col_cut_start = math.floor(col_cut_start * succes)
560
+ col_cut_end = math.ceil(col_cut_end * succes)
561
+
562
+ child_W = cp.copy(dominant_parent_W)
563
+
564
+ if cross_over_mode == 'tpm':
565
+ threadsperblock = 256
566
+ blockspergrid = (total_gene + (threadsperblock - 1)) // threadsperblock
601
567
 
602
- activation_selection_change_prob = 1 - activation_selection_change_prob
603
- potential_activation_selection_change_prob = random.uniform(0, 1)
604
-
605
- if potential_activation_selection_change_prob > activation_selection_change_prob:
606
-
607
- threshold = abs(activation_selection_threshold / succes)
608
- new_threshold = threshold
609
-
610
- while True:
611
-
612
- random_index_undominant = int(random.uniform(0, len(undominant_parent_act)-1))
613
- random_index_dominant = int(random.uniform(0, len(dominant_parent_act)-1))
614
- random_undominant_activation = undominant_parent_act[random_index_undominant]
568
+ crossover_kernel[blockspergrid, threadsperblock](undominant_parent_W, child_W,
569
+ row_cut_start, row_cut_end, col_cut_start, col_cut_end
570
+ )
571
+
572
+ with concurrent.futures.ThreadPoolExecutor() as executor:
573
+ if isinstance(dominant_parent_act, str):
574
+ dominant_parent_act = [dominant_parent_act]
575
+ if isinstance(undominant_parent_act, str):
576
+ undominant_parent_act = [undominant_parent_act]
577
+
578
+ child_act = list(np.copy(dominant_parent_act))
615
579
 
616
- child_act[random_index_dominant] = random_undominant_activation
617
- new_threshold += threshold
580
+ if random.uniform(0, 1) > (1 - activation_selection_add_prob):
581
+ threshold = abs(activation_selection_threshold / succes)
582
+ new_threshold = threshold
583
+
584
+ futures = []
585
+ while len(dominant_parent_act) > new_threshold:
586
+ random_index = int(random.uniform(0, len(undominant_parent_act)-1))
587
+ futures.append(
588
+ executor.submit(
589
+ lambda idx: undominant_parent_act[idx],
590
+ random_index
591
+ )
592
+ )
593
+ new_threshold += threshold
594
+
595
+ for future in concurrent.futures.as_completed(futures):
596
+ child_act.append(future.result())
597
+
598
+ if random.uniform(0, 1) > (1 - activation_selection_change_prob):
599
+ threshold = abs(activation_selection_threshold / succes)
600
+ new_threshold = threshold
601
+
602
+ futures = []
603
+ while len(dominant_parent_act) > new_threshold:
604
+ random_index_undominant = int(random.uniform(0, len(undominant_parent_act)-1))
605
+ random_index_dominant = int(random.uniform(0, len(dominant_parent_act)-1))
606
+ futures.append(
607
+ executor.submit(
608
+ lambda u_idx, d_idx: (d_idx, undominant_parent_act[u_idx]),
609
+ random_index_undominant,
610
+ random_index_dominant
611
+ )
612
+ )
613
+ new_threshold += threshold
614
+
615
+ for future in concurrent.futures.as_completed(futures):
616
+ idx, val = future.result()
617
+ child_act[idx] = val
618
618
 
619
- if len(dominant_parent_act) > new_threshold:
620
- pass
621
-
622
- else:
623
- break
619
+ return child_W, child_act
624
620
 
625
- return child_W, child_act
626
621
 
622
+ @cuda.jit
623
+ def weight_mutation_kernel(weight, rows, cols, num_mutations, rng_states):
624
+ idx = cuda.grid(1)
625
+ if idx < num_mutations:
627
626
 
628
- def mutation(weight,
629
- activations,
630
- activation_mutate_prob,
631
- activation_add_prob,
632
- activation_delete_prob,
633
- activation_change_prob,
634
- weight_mutate_prob,
635
- weight_mutate_threshold,
636
- genome_fitness,
637
- activation_mutate_threshold,
638
- epsilon):
639
- """
640
- Performs mutation on the given weight matrix and activation functions.
627
+ row = int(cuda.random.xoroshiro128p_uniform_float32(rng_states, idx) * rows)
628
+ col = int(cuda.random.xoroshiro128p_uniform_float32(rng_states, idx) * cols)
629
+ mutation_value = -1.0 + 2.0 * cuda.random.xoroshiro128p_uniform_float32(rng_states, idx)
630
+
631
+ if row < rows and col < cols:
632
+ weight[row, col] = mutation_value
633
+
634
+ def mutation(weight, activations, genome_fitness, weight_mutate_prob,
635
+ weight_mutate_threshold, activation_mutate_prob,
636
+ activation_mutate_threshold, activation_add_prob,
637
+ activation_delete_prob, activation_change_prob,
638
+ epsilon=1e-10):
639
+ """
640
+ Performs mutation on the given weight matrix and activation functions.
641
641
  - The weight matrix is mutated by randomly changing its values based on the mutation probability.
642
642
  - The activation functions are mutated by adding, removing, or replacing them with predefined probabilities.
643
643
 
@@ -679,97 +679,81 @@ def mutation(weight,
679
679
  `activation_change_prob`).
680
680
  - The mutation probabilities should be chosen carefully to balance exploration and exploitation during
681
681
  the optimization process.
682
- """
683
-
684
- if isinstance(activations, str): activations = [activations]
685
-
686
- 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
687
- potential_weight_mutation = random.uniform(0, 1)
688
-
689
- if potential_weight_mutation > weight_mutate_prob:
682
+ """
683
+
684
+ if isinstance(activations, str):
685
+ activations = [activations]
690
686
 
691
- start = 0
692
- row_end = weight.shape[0]
693
- col_end = weight.shape[1]
687
+ weight_mutate_prob = 1 - weight_mutate_prob
688
+ if random.uniform(0, 1) > weight_mutate_prob:
689
+ # GPU'ya veri transferi
690
+ d_weight = cp.copy(weight)
691
+
692
+ row_end = weight.shape[0]
693
+ col_end = weight.shape[1]
694
+ max_threshold = row_end * col_end
695
+ threshold = weight_mutate_threshold * genome_fitness
696
+ num_mutations = int(min(max_threshold, threshold))
697
+
698
+ threadsperblock = 256
699
+ blockspergrid = (num_mutations + (threadsperblock - 1)) // threadsperblock
700
+
701
+ rng_states = cuda.random.create_xoroshiro128p_states(threadsperblock * blockspergrid, seed=random.randint(0, 1000))
694
702
 
695
- max_threshold = row_end * col_end
696
-
697
- threshold = weight_mutate_threshold * genome_fitness
698
- new_threshold = threshold
699
-
700
- for _ in range(max_threshold):
701
-
702
- selected_row = int(random.uniform(start, row_end))
703
- selected_col = int(random.uniform(start, col_end))
704
-
705
- weight[selected_row, selected_col] = random.uniform(-1, 1)
706
- new_threshold += threshold
707
-
708
- if max_threshold > new_threshold:
709
- pass
710
-
711
- else:
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)
722
-
723
- 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
-
732
- for _ in range(max_threshold):
733
-
734
- potential_activation_add_prob = random.uniform(0, 1)
735
- potential_activation_delete_prob = random.uniform(0, 1)
736
- potential_activation_change_prob = random.uniform(0, 1)
737
-
703
+ weight_mutation_kernel[blockspergrid, threadsperblock](
704
+ d_weight, row_end, col_end, num_mutations, rng_states
705
+ )
706
+
707
+ activation_mutate_prob = 1 - activation_mutate_prob
708
+ if random.uniform(0, 1) > activation_mutate_prob:
709
+ genome_fitness += epsilon
710
+ threshold = abs(activation_mutate_threshold / genome_fitness)
711
+ max_threshold = len(activations)
712
+
713
+ except_this = ['spiral', 'circular']
714
+ all_acts = [item for item in all_activations() if item not in except_this]
715
+
716
+ activation_add_prob = 1 - activation_add_prob
717
+ activation_delete_prob = 1 - activation_delete_prob
718
+ activation_change_prob = 1 - activation_change_prob
719
+
720
+ def process_mutation(_, activations, all_acts, probs):
721
+ """Tek bir mutasyon işlemi için yardımcı fonksiyon"""
722
+ add_prob, delete_prob, change_prob = probs
723
+ local_activations = activations.copy()
738
724
 
739
- if potential_activation_delete_prob > activation_delete_prob and len(activations) > 1:
740
-
741
- random_index = random.randint(0, len(activations) - 1)
742
- activations.pop(random_index)
743
-
744
-
745
- if potential_activation_add_prob > activation_add_prob:
746
-
747
- try:
748
-
749
- random_index_all_act = int(random.uniform(0, len(all_acts)-1))
750
- activations.append(all_acts[random_index_all_act])
751
-
752
- except:
753
-
754
- activation = activations
755
- activations = []
756
-
757
- activations.append(activation)
758
- activations.append(all_acts[int(random.uniform(0, len(all_acts)-1))])
759
-
760
- if potential_activation_change_prob > activation_change_prob:
761
-
762
- random_index_all_act = int(random.uniform(0, len(all_acts)-1))
763
- random_index_genom_act = int(random.uniform(0, len(activations)-1))
764
-
765
- activations[random_index_genom_act] = all_acts[random_index_all_act]
766
-
767
- new_threshold += threshold
768
-
769
- if max_threshold > new_threshold: pass
770
- else: break
725
+ if random.uniform(0, 1) > delete_prob and len(local_activations) > 1:
726
+ random_index = random.randint(0, len(local_activations) - 1)
727
+ local_activations.pop(random_index)
728
+
729
+ if random.uniform(0, 1) > add_prob:
730
+ try:
731
+ random_index_all_act = int(random.uniform(0, len(all_acts)-1))
732
+ local_activations.append(all_acts[random_index_all_act])
733
+ except:
734
+ activation = local_activations[0]
735
+ local_activations = [activation]
736
+ local_activations.append(all_acts[int(random.uniform(0, len(all_acts)-1))])
737
+
738
+ if random.uniform(0, 1) > change_prob:
739
+ random_index_all_act = int(random.uniform(0, len(all_acts)-1))
740
+ random_index_genom_act = int(random.uniform(0, len(local_activations)-1))
741
+ local_activations[random_index_genom_act] = all_acts[random_index_all_act]
742
+
743
+ return local_activations
744
+
745
+ num_iterations = int(min(max_threshold, threshold))
746
+ with concurrent.futures.ThreadPoolExecutor() as executor:
747
+ probs = (activation_add_prob, activation_delete_prob, activation_change_prob)
748
+ process_func = partial(process_mutation, activations=activations,
749
+ all_acts=all_acts, probs=probs)
750
+
751
+ future_results = list(executor.map(process_func, range(num_iterations)))
771
752
 
772
- return weight, activations
753
+ if future_results:
754
+ activations = future_results[-1]
755
+
756
+ return weight, activations
773
757
 
774
758
 
775
759
  def second_parent_selection(good_weights, bad_weights, good_activations, bad_activations, bad_genomes_selection_prob):