pyerualjetwork 4.1.6__py3-none-any.whl → 4.1.8__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.
@@ -48,7 +48,7 @@ for package_name in package_names:
48
48
 
49
49
  print(f"PyerualJetwork is ready to use with {err} errors")
50
50
 
51
- __version__ = "4.1.6"
51
+ __version__ = "4.1.8"
52
52
  __update__ = "* Changes: https://github.com/HCB06/PyerualJetwork/blob/main/CHANGES\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"
53
53
 
54
54
  def print_version(__version__):
@@ -58,15 +58,4 @@ def print_update_notes(__update__):
58
58
  print(f"Update Notes:\n{__update__}")
59
59
 
60
60
  print_version(__version__)
61
- print_update_notes(__update__)
62
-
63
- from .plan import *
64
- from .planeat import *
65
- from .activation_functions import *
66
- from .data_operations import *
67
- from .loss_functions import *
68
- from .metrics import *
69
- from .model_operations import *
70
- from .ui import *
71
- from .visualizations import *
72
- from .help import *
61
+ print_update_notes(__update__)
@@ -64,17 +64,22 @@ def decode_one_hot(encoded_data):
64
64
 
65
65
 
66
66
 
67
- def split(X, y, test_size, random_state=42, dtype=cp.float32, use_cpu=False):
67
+ def split(X, y, test_size, random_state=42, dtype=cp.float32, shuffle_in_cpu=False):
68
68
  """
69
69
  Splits the given X (features) and y (labels) data into training and testing subsets.
70
70
 
71
71
  Args:
72
72
  X (cupy.ndarray): Features data.
73
+
73
74
  y (cupy.ndarray): Labels data.
75
+
74
76
  test_size (float or int): Proportion or number of samples for the test subset.
77
+
75
78
  random_state (int or None): Seed for random state. Default: 42.
79
+
76
80
  dtype (cupy.dtype): Data type for the arrays. np.float32 by default. Example: cp.float64 or cp.float16. [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not reccomended!] (optional)
77
- use_cpu (bool): If True, output will be same cpu's split function. Default: False.
81
+
82
+ shuffle_in_cpu (bool): If True, output will be same cpu's split function. Default: False. (Use this for direct comparison of cpu training.)
78
83
  Returns:
79
84
  tuple: x_train, x_test, y_train, y_test as ordered training and testing data subsets.
80
85
  """
@@ -94,7 +99,7 @@ def split(X, y, test_size, random_state=42, dtype=cp.float32, use_cpu=False):
94
99
  else:
95
100
  raise ValueError("test_size should be float or int.")
96
101
 
97
- if use_cpu:
102
+ if shuffle_in_cpu:
98
103
  indices = np.arange(num_samples)
99
104
  np.random.seed(random_state)
100
105
  np.random.shuffle(indices)
@@ -117,7 +122,7 @@ def split(X, y, test_size, random_state=42, dtype=cp.float32, use_cpu=False):
117
122
  return x_train, x_test, y_train, y_test
118
123
 
119
124
 
120
- def manuel_balancer(x_train, y_train, target_samples_per_class, dtype=cp.float32, use_cpu=False):
125
+ def manuel_balancer(x_train, y_train, target_samples_per_class, dtype=cp.float32, shuffle_in_cpu=False):
121
126
  """
122
127
  Generates synthetic examples to balance classes to the specified number of examples per class.
123
128
 
@@ -131,7 +136,7 @@ def manuel_balancer(x_train, y_train, target_samples_per_class, dtype=cp.float32
131
136
 
132
137
  dtype (cupy.dtype): Data type for the arrays. np.float32 by default. Example: cp.float64 or cp.float16. [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not reccomended!] (optional)
133
138
 
134
- use_cpu (bool): If True, output will be same cpu's manuel_balancer function. Default: False.
139
+ shuffle_in_cpu (bool): If True, output will be same cpu's manuel_balancer function. Default: False. (Use this for direct comparison of cpu training.)
135
140
 
136
141
  Returns:
137
142
  x_balanced -- Balanced input dataset (cupy array format)
@@ -157,7 +162,7 @@ def manuel_balancer(x_train, y_train, target_samples_per_class, dtype=cp.float32
157
162
 
158
163
  if num_samples > target_samples_per_class:
159
164
 
160
- if use_cpu:
165
+ if shuffle_in_cpu:
161
166
  selected_indices = np.random.choice(
162
167
  class_indices.get(), target_samples_per_class, replace=False)
163
168
  else:
@@ -179,7 +184,7 @@ def manuel_balancer(x_train, y_train, target_samples_per_class, dtype=cp.float32
179
184
 
180
185
  for i in range(samples_to_add):
181
186
 
182
- if use_cpu:
187
+ if shuffle_in_cpu:
183
188
  random_indices = np.random.choice(class_indices.get(), 2, replace=False)
184
189
  else:
185
190
  random_indices = cp.random.choice(class_indices, 2, replace=False)
@@ -187,7 +192,7 @@ def manuel_balancer(x_train, y_train, target_samples_per_class, dtype=cp.float32
187
192
  sample1 = x_train[random_indices[0]]
188
193
  sample2 = x_train[random_indices[1]]
189
194
 
190
- if use_cpu:
195
+ if shuffle_in_cpu:
191
196
  synthetic_sample = sample1 + (sample2 - sample1) * np.random.rand()
192
197
  else:
193
198
  synthetic_sample = sample1 + (sample2 - sample1) * cp.random.rand()
@@ -208,7 +213,7 @@ def manuel_balancer(x_train, y_train, target_samples_per_class, dtype=cp.float32
208
213
  return x_balanced, y_balanced
209
214
 
210
215
 
211
- def auto_balancer(x_train, y_train, dtype=cp.float32, use_cpu=False):
216
+ def auto_balancer(x_train, y_train, dtype=cp.float32, shuffle_in_cpu=False):
212
217
 
213
218
  """
214
219
  Function to balance the training data across different classes.
@@ -220,7 +225,7 @@ def auto_balancer(x_train, y_train, dtype=cp.float32, use_cpu=False):
220
225
 
221
226
  dtype (cupy.dtype): Data type for the arrays. np.float32 by default. Example: cp.float64 or cp.float16. [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not reccomended!] (optional)
222
227
 
223
- use_cpu (bool): If True, output will be same cpu's auto_balancer function. Default: False.
228
+ shuffle_in_cpu (bool): If True, output will be same cpu's auto_balancer function. Default: False. (Use this for direct comparison of cpu training.)
224
229
  Returns:
225
230
  tuple: A tuple containing balanced input data and labels.
226
231
  """
@@ -250,7 +255,7 @@ def auto_balancer(x_train, y_train, dtype=cp.float32, use_cpu=False):
250
255
  for i in tqdm(range(class_count),leave=False, ascii="▱▰",
251
256
  bar_format= bar_format, desc='Balancing Data',ncols=70):
252
257
  if len(ClassIndices[i]) > MinCount:
253
- if use_cpu:
258
+ if shuffle_in_cpu:
254
259
  SelectedIndices = np.random.choice(
255
260
  ClassIndices[i].get(), MinCount, replace=False)
256
261
  else:
@@ -263,7 +268,7 @@ def auto_balancer(x_train, y_train, dtype=cp.float32, use_cpu=False):
263
268
  BalancedInputs = [x_train[idx] for idx in BalancedIndices]
264
269
  BalancedLabels = [y_train[idx] for idx in BalancedIndices]
265
270
 
266
- if use_cpu:
271
+ if shuffle_in_cpu:
267
272
  permutation = np.random.permutation(len(BalancedInputs))
268
273
  else:
269
274
  permutation = cp.random.permutation(len(BalancedInputs))
@@ -279,7 +284,7 @@ def auto_balancer(x_train, y_train, dtype=cp.float32, use_cpu=False):
279
284
  return BalancedInputs, BalancedLabels
280
285
 
281
286
 
282
- def synthetic_augmentation(x_train, y_train, dtype=cp.float32, use_cpu=False):
287
+ def synthetic_augmentation(x_train, y_train, dtype=cp.float32, shuffle_in_cpu=False):
283
288
  """
284
289
  Generates synthetic examples to balance classes with fewer examples using CuPy.
285
290
  Arguments:
@@ -290,7 +295,7 @@ def synthetic_augmentation(x_train, y_train, dtype=cp.float32, use_cpu=False):
290
295
 
291
296
  dtype (cupy.dtype): Data type for the arrays. np.float32 by default. Example: cp.float64 or cp.float16. [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not reccomended!] (optional)
292
297
 
293
- use_cpu (bool): If True, output will be same cpu's synthetic_augmentation function. Default: False.
298
+ shuffle_in_cpu (bool): If True, output will be same cpu's synthetic_augmentation function. Default: False. (Use this for direct comparison of cpu training.)
294
299
 
295
300
  Returns:
296
301
  x_train_balanced -- Balanced input dataset (cupy array format)
@@ -322,7 +327,7 @@ def synthetic_augmentation(x_train, y_train, dtype=cp.float32, use_cpu=False):
322
327
 
323
328
  if num_samples < max_class_count:
324
329
  while num_samples < max_class_count:
325
- if use_cpu:
330
+ if shuffle_in_cpu:
326
331
  random_indices = np.random.choice(
327
332
  class_indices, 2, replace=False)
328
333
  else:
@@ -331,7 +336,7 @@ def synthetic_augmentation(x_train, y_train, dtype=cp.float32, use_cpu=False):
331
336
  sample1 = x[random_indices[0]]
332
337
  sample2 = x[random_indices[1]]
333
338
 
334
- if use_cpu:
339
+ if shuffle_in_cpu:
335
340
  synthetic_sample = sample1 + \
336
341
  (sample2 - sample1) * np.random.rand()
337
342
  else:
@@ -17,15 +17,13 @@ def get_optimal_batch_size_for_cpu(x, data_size_bytes, available_memory):
17
17
  The function calculates the optimal batch size for a given data size and available memory based on
18
18
  the size of each element.
19
19
 
20
- :param x: `x` is a NumPy array representing the input data for which we want to determine the
21
- optimal batch size for processing on the CPU
22
- :param data_size_bytes: The `data_size_bytes` parameter represents the size of the data in bytes
23
- that you want to process in batches
24
- :param available_memory: The `available_memory` parameter represents the total memory available on
25
- the CPU in bytes. This function calculates the optimal batch size for processing data based on the
26
- provided parameters. Let me know if you need any further assistance or explanation!
27
- :return: the optimal batch size for a given array `x` based on the available memory and the size of
28
- each element in bytes.
20
+ :param x: `x` is a NumPy array representing the input data for which we want to determine the optimal batch size for processing on the CPU
21
+
22
+ :param data_size_bytes: The `data_size_bytes` parameter represents the size of the data in bytes that you want to process in batches
23
+
24
+ :param available_memory: The `available_memory` parameter represents the total memory available on the CPU in bytes. This function calculates the optimal batch size for processing data based on the provided parameters. Let me know if you need any further assistance or explanation!
25
+
26
+ :return: the optimal batch size for a given array `x` based on the available memory and the size of each element in bytes.
29
27
  """
30
28
  safe_memory = available_memory * 0.25
31
29
  element_size = data_size_bytes / x.size
@@ -37,10 +35,12 @@ def transfer_to_cpu(x, dtype=np.float32):
37
35
  by batching the conversion process and ensuring complete GPU memory cleanup.
38
36
 
39
37
  :param x: Input data to transfer to CPU (CuPy array)
38
+
40
39
  :param dtype: Target NumPy dtype for the output array (default: np.float32)
40
+
41
41
  :return: NumPy array with the specified dtype
42
42
  """
43
- from .ui import loading_bars, initialize_loading_bar
43
+ from ui import loading_bars, initialize_loading_bar
44
44
  try:
45
45
  if isinstance(x, np.ndarray):
46
46
  return x.astype(dtype) if x.dtype != dtype else x
@@ -144,16 +144,11 @@ def transfer_to_gpu(x, dtype=cp.float32):
144
144
  The `transfer_to_gpu` function in Python converts input data to GPU arrays, optimizing memory usage by
145
145
  batching and handling out-of-memory errors.
146
146
 
147
- :param x: The `x` parameter in the `transfer_to_gpu` function is the input data that you want to transfer to
148
- the GPU for processing. It can be either a NumPy array or a CuPy array. If it's a NumPy array, the
149
- function will convert it to a CuPy array and
150
- :param dtype: The `dtype` parameter in the `transfer_to_gpu` function specifies the data type to which the
151
- input array `x` should be converted when moving it to the GPU. By default, it is set to
152
- `cp.float32`, which is a 32-bit floating-point data type provided by the Cu
153
- :return: The `transfer_to_gpu` function returns the input data `x` converted to a GPU array of type `dtype`
154
- (default is `cp.float32`). If the input `x` is already a GPU array with the same dtype, it returns
155
- `x` as is. If the data size of `x` exceeds 25% of the free GPU memory, it processes the data in
156
- batches to
147
+ :param x: The `x` parameter in the `transfer_to_gpu` function is the input data that you want to transfer to the GPU for processing. It can be either a NumPy array or a CuPy array. If it's a NumPy array, the function will convert it to a CuPy array and
148
+
149
+ :param dtype: The `dtype` parameter in the `transfer_to_gpu` function specifies the data type to which the input array `x` should be converted when moving it to the GPU. By default, it is set to `cp.float32`, which is a 32-bit floating-point data type provided by the CuPy
150
+
151
+ :return: The `transfer_to_gpu` function returns the input data `x` converted to a GPU array of type `dtype` (default is `cp.float32`). If the input `x` is already a GPU array with the same dtype, it returns `x` as is. If the data size of `x` exceeds 25% of the free GPU memory, it processes the data in batches to
157
152
  """
158
153
  from .ui import loading_bars, initialize_loading_bar
159
154
  try:
pyerualjetwork/plan.py CHANGED
@@ -3,8 +3,8 @@
3
3
 
4
4
  MAIN MODULE FOR PLAN
5
5
 
6
- PLAN document: https://github.com/HCB06/Anaplan/blob/main/Welcome_to_PLAN/PLAN.pdf
7
- ANAPLAN document: https://github.com/HCB06/Anaplan/blob/main/Welcome_to_Anaplan/ANAPLAN_USER_MANUEL_AND_LEGAL_INFORMATION(EN).pdf
6
+ PLAN document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PLAN/PLAN.pdf
7
+ PYERUALJETWORK document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PyerualJetwork/PYERUALJETWORK_USER_MANUEL_AND_LEGAL_INFORMATION(EN).pdf
8
8
 
9
9
  @author: Hasan Can Beydili
10
10
  @YouTube: https://www.youtube.com/@HasanCanBeydili
@@ -24,6 +24,7 @@ from .loss_functions import binary_crossentropy, categorical_crossentropy
24
24
  from .activation_functions import apply_activation, Softmax, all_activations
25
25
  from .metrics import metrics
26
26
  from .model_operations import get_acc, get_preds, get_preds_softmax
27
+ from .memory_operations import optimize_labels
27
28
  from .visualizations import (
28
29
  draw_neural_web,
29
30
  update_neural_web_for_fit,
@@ -102,8 +103,6 @@ def fit(
102
103
  Returns:
103
104
  numpyarray([num]): (Weight matrix).
104
105
  """
105
-
106
- from model_operations import get_acc
107
106
 
108
107
  # Pre-checks
109
108
 
@@ -173,45 +172,61 @@ def fit(
173
172
  return normalization(LTPW, dtype=dtype)
174
173
 
175
174
 
176
- def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', batch_size=1,
175
+ def learner(x_train, y_train, optimizer, x_test=None, y_test=None, strategy='accuracy', gen=None, batch_size=1,
177
176
  neural_web_history=False, show_current_activations=False, auto_normalization=True,
178
- neurons_history=False, patience=None, depth=None, early_shifting=False,
179
- early_stop=False, loss='categorical_crossentropy', show_history=False,
177
+ neurons_history=False, early_stop=False, loss='categorical_crossentropy', show_history=False,
180
178
  interval=33.33, target_acc=None, target_loss=None, except_this=None,
181
- only_this=None, start_this=None, dtype=np.float32):
179
+ only_this=None, start_this_act=None, start_this_W=None, target_fitness='max', dtype=np.float32):
182
180
  """
183
181
  Optimizes the activation functions for a neural network by leveraging train data to find
184
- the most accurate combination of activation potentiation for the given dataset.
182
+ the most accurate combination of activation potentiation for the given dataset using genetic algorithm NEAT (Neuroevolution of Augmenting Topologies). But modifided for PLAN version. Created by me: PLANEAT.
185
183
 
184
+ Why genetic optimization and not backpropagation?
185
+ Because PLAN is different from other neural network architectures. In PLAN, the learnable parameters are not the weights; instead, the learnable parameters are the activation functions.
186
+ Since activation functions are not differentiable, we cannot use gradient descent or backpropagation. However, I developed a more powerful genetic optimization algorithm: PLANEAT.
187
+
186
188
  Args:
187
189
 
188
190
  x_train (array-like): Training input data.
189
191
 
190
192
  y_train (array-like): Labels for training data. one-hot encoded.
191
193
 
194
+ optimizer (function): PLAN optimization technique with hyperparameters. (PLAN using NEAT(PLANEAT) for optimization.) Please use this: from pyerualjetwork import planeat (and) optimizer = lambda *args, **kwargs: planeat.evolve(*args, 'here give your neat hyperparameters for example: activation_add_prob=0.85', **kwargs) Example:
195
+ ```python
196
+ genetic_optimizer = lambda *args, **kwargs: planeat.evolve(*args,
197
+ activation_add_prob=0.85,
198
+ mutations=False,
199
+ strategy='cross_over',
200
+ **kwargs)
201
+
202
+ model = plan.learner(x_train,
203
+ y_train,
204
+ optimizer=genetic_optimizer,
205
+ strategy='accuracy',
206
+ show_history=True,
207
+ target_acc=0.94,
208
+ interval=16.67)
209
+ ```
210
+
192
211
  x_test (array-like, optional): Test input data (for improve next gen generilization). If test data is not given then train feedback learning active
193
212
 
194
213
  y_test (array-like, optional): Test Labels (for improve next gen generilization). If test data is not given then train feedback learning active
195
214
 
196
- strategy (str, optional): Learning strategy. (options: 'accuracy', 'loss', 'f1', 'precision', 'recall', 'adaptive_accuracy', 'adaptive_loss', 'all'): 'accuracy', Maximizes test accuracy during learning. 'f1', Maximizes test f1 score during learning. 'precision', Maximizes test preciison score during learning. 'recall', Maximizes test recall during learning. loss', Minimizes test loss during learning. 'adaptive_accuracy', The model compares the current accuracy with the accuracy from the past based on the number specified by the patience value. If no improvement is observed it adapts to the condition by switching to the 'loss' strategy quickly starts minimizing loss and continues learning. 'adaptive_loss',The model adopts the 'loss' strategy until the loss reaches or falls below the value specified by the patience parameter. However, when the patience threshold is reached, it automatically switches to the 'accuracy' strategy and begins to maximize accuracy. 'all', Maximizes all test scores and minimizes test loss, 'all' strategy most strong and most robust strategy. Default is 'accuracy'.
197
-
198
- patience ((int, float), optional): patience value for adaptive strategies. For 'adaptive_accuracy' Default value: 5. For 'adaptive_loss' Default value: 0.150.
215
+ strategy (str, optional): Learning strategy. (options: 'accuracy', 'f1', 'precision', 'recall'): 'accuracy', Maximizes train (or test if given) accuracy during learning. 'f1', Maximizes train (or test if given) f1 score during learning. 'precision', Maximizes train (or test if given) precision score during learning. 'recall', Maximizes train (or test if given) recall during learning. Default is 'accuracy'.
199
216
 
200
- depth (int, optional): The depth of the PLAN neural networks Aggreagation layers.
217
+ gen (int, optional): The generation count for genetic optimization.
201
218
 
202
219
  batch_size (float, optional): Batch size is used in the prediction process to receive test feedback by dividing the test data into chunks and selecting activations based on randomly chosen partitions. This process reduces computational cost and time while still covering the entire test set due to random selection, so it doesn't significantly impact accuracy. For example, a batch size of 0.08 means each test batch represents 8% of the test set. Default is 1. (%100 of test)
203
220
 
204
221
  auto_normalization (bool, optional): If auto normalization=False this makes more faster training times and much better accuracy performance for some datasets. Default is True.
205
222
 
206
- early_shifting (int, optional): Early shifting checks if the test accuracy improves after a given number of activation attempts while inside a depth. If there's no improvement, it automatically shifts to the next depth. Basically, if no progress, it’s like, “Alright, let’s move on!” Default is False
207
-
208
- early_stop (bool, optional): If True, implements early stopping during training.(If test accuracy not improves in two depth stops learning.) Default is False.
223
+ early_stop (bool, optional): If True, implements early stopping during training.(If test accuracy not improves in two gen stops learning.) Default is False.
209
224
 
210
225
  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
211
226
 
212
227
  show_history (bool, optional): If True, displays the training history after optimization. Default is False.
213
228
 
214
- loss (str, optional): For visualizing and monitoring. PLAN neural networks doesn't need any loss function in training(if strategy not 'loss'). options: ('categorical_crossentropy' or 'binary_crossentropy') Default is 'categorical_crossentropy'.
229
+ 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'.
215
230
 
216
231
  interval (int, optional): The interval at which evaluations are conducted during training. (33.33 = 30 FPS, 16.67 = 60 FPS) Default is 100.
217
232
 
@@ -223,81 +238,54 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
223
238
 
224
239
  only_this (list, optional): A list of activations to focus on during optimization. Default is None. (For avaliable activation functions, run this code: plan.activations_list())
225
240
 
226
- start_this (list, optional): To resume a previously canceled or interrupted training from where it left off, or to continue from that point with a different strategy, provide the list of activation functions selected up to the learned portion to this parameter. Default is None
241
+ start_this_act (list, optional): To resume a previously canceled or interrupted training from where it left off, or to continue from that point with a different strategy, provide the list of activation functions selected up to the learned portion to this parameter. Default is None
242
+
243
+ start_this_W (numpy.array, optional): To resume a previously canceled or interrupted training from where it left off, or to continue from that point with a different strategy, provide the weight matrix of this genome. Default is None
227
244
 
228
245
  neurons_history (bool, optional): Shows the history of changes that neurons undergo during the TFL (Test or Train Feedback Learning) stages. True or False. Default is False.
229
246
 
230
247
  neural_web_history (bool, optional): Draws history of neural web. Default is False.
231
248
 
249
+ target_fitness (str, optional): Target fitness strategy for PLANEAT optimization. ('max' for machine learning, 'min' for machine unlearning.) Default: 'max'
250
+
232
251
  dtype (numpy.dtype): Data type for the arrays. np.float32 by default. Example: np.float64 or np.float16. [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not reccomended!] (optional)
233
252
 
234
253
  Returns:
235
254
  tuple: A list for model parameters: [Weight matrix, Test loss, Test Accuracy, [Activations functions]].
236
255
 
237
256
  """
238
- print(Fore.WHITE + "\nRemember, optimization on large datasets can be very time-consuming and computationally expensive. Therefore, if you are working with such a dataset, our recommendation is to include activation function: ['circular'] in the 'except_this' parameter unless absolutely necessary, as they can significantly prolong the process. from: learner\n" + Fore.RESET)
257
+
258
+ print(Fore.WHITE + "\nRemember, optimization on large datasets can be very time-consuming and computationally expensive. Therefore, if you are working with such a dataset, our recommendation is to include activation function: ['circular', 'spiral'] in the 'except_this' parameter unless absolutely necessary, as they can significantly prolong the process. from: learner\n" + Fore.RESET)
239
259
 
240
260
  activation_potentiation = all_activations()
241
261
 
242
262
  # Pre-checks
243
263
 
244
264
  x_train = x_train.astype(dtype, copy=False)
245
-
246
- if len(y_train[0]) < 256:
247
- if y_train.dtype != np.uint8:
248
- y_train = np.array(y_train, copy=False).astype(np.uint8, copy=False)
249
- elif len(y_train[0]) <= 32767:
250
- if y_train.dtype != np.uint16:
251
- y_train = np.array(y_train, copy=False).astype(np.uint16, copy=False)
252
- else:
253
- if y_train.dtype != np.uint32:
254
- y_train = np.array(y_train, copy=False).astype(np.uint32, copy=False)
255
-
256
- if x_test is not None:
257
- x_test = x_test.astype(dtype, copy=False)
258
-
259
- if len(y_test[0]) < 256:
260
- if y_test.dtype != np.uint8:
261
- y_test = np.array(y_test, copy=False).astype(np.uint8, copy=False)
262
- elif len(y_test[0]) <= 32767:
263
- if y_test.dtype != np.uint16:
264
- y_test = np.array(y_test, copy=False).astype(np.uint16, copy=False)
265
- else:
266
- if y_test.dtype != np.uint32:
267
- y_test = np.array(y_test, copy=False).astype(np.uint32, copy=False)
265
+ y_train = optimize_labels(y_train, cuda=False)
268
266
 
269
267
  if x_test is None and y_test is None:
270
268
  x_test = x_train
271
269
  y_test = y_train
272
270
  data = 'Train'
273
271
  else:
272
+ x_test = x_test.astype(dtype, copy=False)
273
+ y_test = optimize_labels(y_test, cuda=False)
274
274
  data = 'Test'
275
275
 
276
- if early_shifting != False:
277
- shift_patience = early_shifting
278
-
279
- # Strategy initialization
280
- if strategy == 'adaptive_accuracy':
281
- strategy = 'accuracy'
282
- adaptive = True
283
- if patience == None:
284
- patience = 5
285
- elif strategy == 'adaptive_loss':
286
- strategy = 'loss'
287
- adaptive = True
288
- if patience == None:
289
- patience = 0.150
290
- else:
291
- adaptive = False
292
-
293
276
  # Filter activation functions
294
- if only_this != None:
277
+ if only_this is not None:
295
278
  activation_potentiation = only_this
296
- if except_this != None:
279
+ if except_this is not None:
297
280
  activation_potentiation = [item for item in activation_potentiation if item not in except_this]
298
- if depth is None:
299
- depth = len(activation_potentiation)
281
+ if gen is None:
282
+ gen = len(activation_potentiation)
283
+
284
+ if strategy != 'accuracy' and strategy != 'f1' and strategy != 'recall' and strategy != 'precision': raise ValueError("Strategy parameter only be 'accuracy' or 'f1' or 'recall' or 'precision'.")
300
285
 
286
+ if start_this_act is None and len(activation_potentiation) % 2 != 0: raise ValueError("Activation length must be even number. Please use 'except_this' parameter and except some activation. For example: except_this=['linear']")
287
+ if start_this_act is not None and len(activation_potentiation) + 1 % 2 != 0: raise ValueError("You are using start_this parameter, activation length still must be even number. Please use 'except_this' parameter and except some activation. For example: except_this=['linear']")
288
+
301
289
  # Initialize visualization components
302
290
  viz_objects = initialize_visualization_for_learner(show_history, neurons_history, neural_web_history, x_train, y_train)
303
291
 
@@ -306,19 +294,20 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
306
294
  ncols = 76
307
295
  else:
308
296
  ncols = 89
309
- progress = initialize_loading_bar(total=len(activation_potentiation), desc="", ncols=ncols, bar_format=bar_format_learner)
310
297
 
311
298
  # Initialize variables
312
- activations = []
313
- if start_this is None:
314
- best_activations = []
299
+ act_pop = []
300
+ weight_pop = []
301
+
302
+ if start_this_act is None and start_this_W is None:
315
303
  best_acc = 0
316
304
  else:
317
- best_activations = start_this
305
+ act_pop.append(start_this_act)
306
+ weight_pop.append(start_this_W)
307
+
318
308
  x_test_batch, y_test_batch = batcher(x_test, y_test, batch_size=batch_size)
319
309
 
320
- W = fit(x_train, y_train, activation_potentiation=best_activations, train_bar=False, auto_normalization=auto_normalization, dtype=dtype)
321
- model = evaluate(x_test_batch, y_test_batch, W=W, loading_bar_status=False, activation_potentiation=activations, dtype=dtype)
310
+ model = evaluate(x_test_batch, y_test_batch, W=start_this_W, loading_bar_status=False, activation_potentiation=act_pop, dtype=dtype)
322
311
 
323
312
  if loss == 'categorical_crossentropy':
324
313
  test_loss = categorical_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
@@ -328,12 +317,15 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
328
317
  best_acc = model[get_acc()]
329
318
  best_loss = test_loss
330
319
 
331
- best_acc_per_depth_list = []
320
+ best_acc_per_gen_list = []
332
321
  postfix_dict = {}
333
322
  loss_list = []
334
-
335
- for i in range(depth):
336
- postfix_dict["Depth"] = str(i+1) + '/' + str(depth)
323
+ target_pop = []
324
+
325
+ progress = initialize_loading_bar(total=len(activation_potentiation), desc="", ncols=ncols, bar_format=bar_format_learner)
326
+
327
+ for i in range(gen):
328
+ postfix_dict["Gen"] = str(i+1) + '/' + str(gen)
337
329
  progress.set_postfix(postfix_dict)
338
330
 
339
331
  progress.n = 0
@@ -341,80 +333,65 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
341
333
  progress.update(0)
342
334
 
343
335
  for j in range(len(activation_potentiation)):
344
- for k in range(len(best_activations)):
345
- activations.append(best_activations[k])
346
-
347
- activations.append(activation_potentiation[j])
348
336
 
349
337
  x_test_batch, y_test_batch = batcher(x_test, y_test, batch_size=batch_size)
338
+
339
+ if i == 0:
340
+ act_pop.append(activation_potentiation[j])
341
+ W = fit(x_train, y_train, activation_potentiation=act_pop[-1], train_bar=False, auto_normalization=auto_normalization, dtype=dtype)
342
+ weight_pop.append(W)
350
343
 
351
- W = fit(x_train, y_train, activation_potentiation=activations, train_bar=False, auto_normalization=auto_normalization, dtype=dtype)
352
- model = evaluate(x_test_batch, y_test_batch, W=W, loading_bar_status=False, activation_potentiation=activations, dtype=dtype)
353
-
344
+ model = evaluate(x_test_batch, y_test_batch, W=weight_pop[j], loading_bar_status=False, activation_potentiation=act_pop[j], dtype=dtype)
354
345
  acc = model[get_acc()]
346
+
347
+ if strategy == 'accuracy': target_pop.append(acc)
355
348
 
356
- if strategy == 'loss' or strategy == 'all':
357
- if loss == 'categorical_crossentropy':
358
- test_loss = categorical_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
359
- else:
360
- test_loss = binary_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
361
-
362
- if i == 0 and j == 0 and start_this is None:
363
- best_loss = test_loss
364
-
365
- if strategy == 'f1' or strategy == 'precision' or strategy == 'recall' or strategy == 'all':
349
+ elif strategy == 'f1' or strategy == 'precision' or strategy == 'recall':
366
350
  precision_score, recall_score, f1_score = metrics(y_test_batch, model[get_preds()])
367
351
 
368
- if strategy == 'precision' or strategy == 'all':
352
+ if strategy == 'precision':
353
+ target_pop.append(precision_score)
354
+
369
355
  if i == 0 and j == 0:
370
356
  best_precision = precision_score
371
357
 
372
- if strategy == 'recall' or strategy == 'all':
358
+ if strategy == 'recall':
359
+ target_pop.append(recall_score)
360
+
373
361
  if i == 0 and j == 0:
374
362
  best_recall = recall_score
375
363
 
376
- if strategy == 'f1' or strategy == 'all':
364
+ if strategy == 'f1':
365
+ target_pop.append(f1_score)
366
+
377
367
  if i == 0 and j == 0:
378
368
  best_f1 = f1_score
379
369
 
380
- if early_shifting != False:
381
- if acc <= best_acc:
382
- early_shifting -= 1
383
- if early_shifting == 0:
384
- early_shifting = shift_patience
385
- break
386
-
387
370
  if ((strategy == 'accuracy' and acc >= best_acc) or
388
- (strategy == 'loss' and test_loss <= best_loss) or
389
371
  (strategy == 'f1' and f1_score >= best_f1) or
390
- (strategy == 'precision' and precision_score >= best_precision) or
391
- (strategy == 'recall' and recall_score >= best_recall) or
392
- (strategy == 'all' and f1_score >= best_f1 and acc >= best_acc and
393
- test_loss <= best_loss and precision_score >= best_precision and
394
- recall_score >= best_recall)):
372
+ (strategy == 'precision' and precision_score >= best_precision) or
373
+ (strategy == 'recall' and recall_score >= best_recall)):
395
374
 
396
- current_best_activation = activation_potentiation[j]
397
375
  best_acc = acc
398
-
376
+ best_weights = weight_pop[j]
377
+ final_activations = act_pop[j]
378
+ best_model = model
379
+
380
+ final_activations = [final_activations[0]] if len(set(final_activations)) == 1 else final_activations # removing if all same
381
+
399
382
  if batch_size == 1:
400
383
  postfix_dict[f"{data} Accuracy"] = best_acc
401
384
  else:
402
385
  postfix_dict[f"{data} Batch Accuracy"] = acc
403
386
  progress.set_postfix(postfix_dict)
404
-
405
- final_activations = activations
406
387
 
407
388
  if show_current_activations:
408
389
  print(f", Current Activations={final_activations}", end='')
409
390
 
410
- best_weights = W
411
- best_model = model
412
-
413
- if strategy != 'loss':
414
- if loss == 'categorical_crossentropy':
415
- test_loss = categorical_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
416
- else:
417
- test_loss = binary_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
391
+ if loss == 'categorical_crossentropy':
392
+ test_loss = categorical_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
393
+ else:
394
+ test_loss = binary_crossentropy(y_true_batch=y_test_batch, y_pred_batch=model[get_preds_softmax()])
418
395
 
419
396
  if batch_size == 1:
420
397
  postfix_dict[f"{data} Loss"] = test_loss
@@ -426,9 +403,9 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
426
403
 
427
404
  # Update visualizations during training
428
405
  if show_history:
429
- depth_list = range(1, len(best_acc_per_depth_list) + 2)
430
- update_history_plots_for_learner(viz_objects, depth_list, loss_list + [test_loss],
431
- best_acc_per_depth_list + [best_acc], x_train, final_activations)
406
+ gen_list = range(1, len(best_acc_per_gen_list) + 2)
407
+ update_history_plots_for_learner(viz_objects, gen_list, loss_list + [test_loss],
408
+ best_acc_per_gen_list + [best_acc], x_train, final_activations)
432
409
 
433
410
  if neurons_history:
434
411
  viz_objects['neurons']['artists'] = (
@@ -496,25 +473,16 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
496
473
  return best_weights, best_model[get_preds()], best_acc, final_activations
497
474
 
498
475
  progress.update(1)
499
- activations = []
500
476
 
501
- best_activations.append(current_best_activation)
502
- best_acc_per_depth_list.append(best_acc)
477
+ best_acc_per_gen_list.append(best_acc)
503
478
  loss_list.append(best_loss)
504
479
 
505
- # Check adaptive strategy conditions
506
- if adaptive == True and strategy == 'accuracy' and i + 1 >= patience:
507
- check = best_acc_per_depth_list[-patience:]
508
- if all(x == check[0] for x in check):
509
- strategy = 'loss'
510
- adaptive = False
511
- elif adaptive == True and strategy == 'loss' and best_loss <= patience:
512
- strategy = 'accuracy'
513
- adaptive = False
480
+ weight_pop, act_pop = optimizer(np.array(weight_pop, dtype=dtype), act_pop, i, np.array(target_pop, dtype=dtype, copy=False), target_fitness=target_fitness, bar_status=False)
481
+ target_pop = []
514
482
 
515
483
  # Early stopping check
516
484
  if early_stop == True and i > 0:
517
- if best_acc_per_depth_list[i] == best_acc_per_depth_list[i-1]:
485
+ if best_acc_per_gen_list[i] == best_acc_per_gen_list[i-1]:
518
486
  progress.close()
519
487
  train_model = evaluate(x_train, y_train, W=best_weights, loading_bar_status=False,
520
488
  activation_potentiation=final_activations, dtype=dtype)
@@ -548,7 +516,7 @@ def learner(x_train, y_train, x_test=None, y_test=None, strategy='accuracy', bat
548
516
  else:
549
517
  train_loss = binary_crossentropy(y_true_batch=y_train, y_pred_batch=train_model[get_preds_softmax()])
550
518
 
551
- print('\nActivations: ', final_activations)
519
+ print('\nActivations: ', act_pop[-1])
552
520
  print(f'Train Accuracy (%{batch_size * 100} of train samples):', train_model[get_acc()])
553
521
  print(f'Train Loss (%{batch_size * 100} of train samples): ', train_loss, '\n')
554
522
  if data == 'Test':