pyerualjetwork 4.3.8.dev14__py3-none-any.whl → 4.3.9b0__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.
Files changed (38) hide show
  1. pyerualjetwork/__init__.py +1 -1
  2. pyerualjetwork/activation_functions.py +2 -2
  3. pyerualjetwork/activation_functions_cuda.py +63 -114
  4. pyerualjetwork/data_operations_cuda.py +1 -1
  5. pyerualjetwork/model_operations.py +14 -14
  6. pyerualjetwork/model_operations_cuda.py +16 -17
  7. pyerualjetwork/plan.py +87 -268
  8. pyerualjetwork/plan_cuda.py +82 -276
  9. pyerualjetwork/planeat.py +12 -44
  10. pyerualjetwork/planeat_cuda.py +9 -45
  11. pyerualjetwork/visualizations.py +29 -26
  12. pyerualjetwork/visualizations_cuda.py +19 -20
  13. {pyerualjetwork-4.3.8.dev14.dist-info → pyerualjetwork-4.3.9b0.dist-info}/METADATA +2 -19
  14. pyerualjetwork-4.3.9b0.dist-info/RECORD +24 -0
  15. pyerualjetwork-4.3.9b0.dist-info/top_level.txt +1 -0
  16. pyerualjetwork-4.3.8.dev14.dist-info/RECORD +0 -44
  17. pyerualjetwork-4.3.8.dev14.dist-info/top_level.txt +0 -2
  18. pyerualjetwork_afterburner/__init__.py +0 -11
  19. pyerualjetwork_afterburner/activation_functions.py +0 -290
  20. pyerualjetwork_afterburner/activation_functions_cuda.py +0 -289
  21. pyerualjetwork_afterburner/data_operations.py +0 -406
  22. pyerualjetwork_afterburner/data_operations_cuda.py +0 -461
  23. pyerualjetwork_afterburner/help.py +0 -17
  24. pyerualjetwork_afterburner/loss_functions.py +0 -21
  25. pyerualjetwork_afterburner/loss_functions_cuda.py +0 -21
  26. pyerualjetwork_afterburner/memory_operations.py +0 -298
  27. pyerualjetwork_afterburner/metrics.py +0 -190
  28. pyerualjetwork_afterburner/metrics_cuda.py +0 -163
  29. pyerualjetwork_afterburner/model_operations.py +0 -408
  30. pyerualjetwork_afterburner/model_operations_cuda.py +0 -420
  31. pyerualjetwork_afterburner/plan.py +0 -432
  32. pyerualjetwork_afterburner/plan_cuda.py +0 -441
  33. pyerualjetwork_afterburner/planeat.py +0 -793
  34. pyerualjetwork_afterburner/planeat_cuda.py +0 -840
  35. pyerualjetwork_afterburner/ui.py +0 -22
  36. pyerualjetwork_afterburner/visualizations.py +0 -823
  37. pyerualjetwork_afterburner/visualizations_cuda.py +0 -825
  38. {pyerualjetwork-4.3.8.dev14.dist-info → pyerualjetwork-4.3.9b0.dist-info}/WHEEL +0 -0
@@ -1,441 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
-
4
- MAIN MODULE FOR PLAN_CUDA
5
-
6
- Examples: https://github.com/HCB06/PyerualJetwork/tree/main/Welcome_to_PyerualJetwork/ExampleCodes
7
-
8
- PLAN document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PLAN/PLAN.pdf
9
- PYERUALJETWORK document: https://github.com/HCB06/PyerualJetwork/blob/main/Welcome_to_PyerualJetwork/PYERUALJETWORK_USER_MANUEL_AND_LEGAL_INFORMATION(EN).pdf
10
-
11
- @author: Hasan Can Beydili
12
- @YouTube: https://www.youtube.com/@HasanCanBeydili
13
- @Linkedin: https://www.linkedin.com/in/hasan-can-beydili-77a1b9270/
14
- @Instagram: https://www.instagram.com/canbeydilj/
15
- @contact: tchasancan@gmail.com
16
- """
17
-
18
- import cupy as cp
19
-
20
- ### LIBRARY IMPORTS ###
21
- from .ui import loading_bars, initialize_loading_bar
22
- from .data_operations_cuda import normalization
23
- from .loss_functions_cuda import binary_crossentropy, categorical_crossentropy
24
- from .activation_functions_cuda import apply_activation, all_activations
25
- from .metrics_cuda import metrics
26
- from .model_operations_cuda import get_acc, get_preds, get_preds_softmax
27
- from .memory_operations import transfer_to_gpu, transfer_to_cpu, optimize_labels
28
- from .visualizations_cuda import (
29
- draw_neural_web,
30
- display_visualizations_for_learner,
31
- update_history_plots_for_learner,
32
- initialize_visualization_for_learner,
33
- update_neuron_history_for_learner
34
- )
35
-
36
- ### GLOBAL VARIABLES ###
37
- bar_format_normal = loading_bars()[0]
38
- bar_format_learner = loading_bars()[1]
39
-
40
- # BUILD -----
41
-
42
- def fit(
43
- x_train,
44
- y_train,
45
- activation_potentiation=['linear'],
46
- W=None,
47
- dtype=cp.float32
48
- ):
49
- """
50
- Creates a model to fitting data.,
51
-
52
- fit Args:
53
-
54
- x_train (aray-like[cupy]): List or cupy array of input data.
55
-
56
- y_train (aray-like[cupy]): List or cupy array of target labels. (one hot encoded)
57
-
58
- activation_potentiation (list): For deeper PLAN networks, activation function parameters. For more information please run this code: plan.activations_list() default: [None] (optional)
59
-
60
- W (cupy.ndarray): If you want to re-continue or update model
61
-
62
- dtype (cupy.dtype): Data type for the arrays. cp.float32 by default. Example: cp.float64 or cp.float16. [fp32 for balanced devices, fp64 for strong devices, fp16 for weak devices: not reccomended!] (optional)
63
-
64
- Returns:
65
- cupyarray: (Weight matrix).
66
- """
67
- # Pre-check
68
-
69
- if len(x_train) != len(y_train): raise ValueError("x_train and y_train must have the same length.")
70
-
71
- LTPW = cp.zeros((len(y_train[0]), len(x_train[0].ravel()))).astype(dtype, copy=False) if W is None else W
72
-
73
- x_train = apply_activation(x_train, activation_potentiation)
74
- LTPW += cp.array(y_train, dtype=optimize_labels(y_train, cuda=True).dtype).T @ x_train
75
-
76
- return normalization(LTPW, dtype=dtype)
77
-
78
-
79
- def learner(x_train, y_train, optimizer, fit_start, strategy='accuracy', gen=None, batch_size=1, pop_size=None,
80
- neural_web_history=False, show_current_activations=False,
81
- neurons_history=False, early_stop=False, loss='categorical_crossentropy', show_history=False,
82
- interval=33.33, target_acc=None, target_loss=None,
83
- start_this_act=None, start_this_W=None, dtype=cp.float32, memory='gpu'):
84
- """
85
- Optimizes the activation functions for a neural network by leveraging train data to find
86
- the most accurate combination of activation potentiation for the given dataset.
87
-
88
- Why genetic optimization and not backpropagation?
89
- 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.
90
- Since activation functions are not differentiable, we cannot use gradient descent or backpropagation. However, I developed a more powerful genetic optimization algorithm: PLANEAT.
91
-
92
- Args:
93
-
94
- x_train (array-like): Training input data.
95
-
96
- y_train (array-like): Labels for training data.
97
-
98
- optimizer (function): PLAN optimization technique with hyperparameters. (PLAN using NEAT(PLANEAT) for optimization.) Please use this: from pyerualjetwork import planeat_cuda (and) optimizer = lambda *args, **kwargs: planeat_cuda.evolve(*args, 'here give your neat hyperparameters for example: activation_add_prob=0.85', **kwargs) Example:
99
- ```python
100
- genetic_optimizer = lambda *args, **kwargs: planeat_cuda.evolver(*args,
101
- activation_add_prob=0.85,
102
- strategy='aggressive',
103
- **kwargs)
104
-
105
- model = plan_cuda.learner(x_train,
106
- y_train,
107
- optimizer=genetic_optimizer,
108
- fit_start=True,
109
- strategy='accuracy',
110
- show_history=True,
111
- gen=15,
112
- batch_size=0.05,
113
- interval=16.67)
114
- ```
115
- fit_start (bool): 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. The fit_start parameter is MANDATORY and must be provided.
116
-
117
- 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'.
118
-
119
- gen (int, optional): The generation count for genetic optimization.
120
-
121
- 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)
122
-
123
- pop_size (int, optional): Population size of each generation. Default: count of activation functions
124
-
125
- early_stop (bool, optional): If True, implements early stopping during training.(If train accuracy not improves in two gen stops learning.) Default is False.
126
-
127
- 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
128
-
129
- show_history (bool, optional): If True, displays the training history after optimization. Default is False.
130
-
131
- 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'.
132
-
133
- interval (int, optional): The interval at which evaluations are conducted during training. (33.33 = 30 FPS, 16.67 = 60 FPS) Default is 100.
134
-
135
- target_acc (int, optional): The target accuracy to stop training early when achieved. Default is None.
136
-
137
- target_loss (float, optional): The target loss to stop training early when achieved. Default is None.
138
-
139
- 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
140
-
141
- start_this_W (cupy.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
142
-
143
- 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.
144
-
145
- neural_web_history (bool, optional): Draws history of neural web. Default is False.
146
-
147
- 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)
148
-
149
- memory (str): The memory parameter determines whether the dataset to be processed on the GPU will be stored in the CPU's RAM or the GPU's RAM. Options: 'gpu', 'cpu'. Default: 'gpu'.
150
-
151
- Returns:
152
- tuple: A list for model parameters: [Weight matrix, Preds, Accuracy, [Activations functions]]. You can acces this parameters in model_operations module. For example: model_operations.get_weights() for Weight matrix.
153
-
154
- """
155
-
156
- from .planeat_cuda import define_genomes
157
-
158
- data = 'Train'
159
-
160
- except_this = ['spiral', 'circular']
161
- activation_potentiation = [item for item in all_activations() if item not in except_this]
162
- activation_potentiation_len = len(activation_potentiation)
163
-
164
- if pop_size is None: pop_size = activation_potentiation_len
165
- y_train = optimize_labels(y_train, cuda=True)
166
-
167
- if pop_size < activation_potentiation_len: raise ValueError(f"pop_size must be higher or equal to {activation_potentiation_len}")
168
-
169
- if memory == 'gpu':
170
- x_train = transfer_to_gpu(x_train, dtype=dtype)
171
- y_train = transfer_to_gpu(y_train, dtype=y_train.dtype)
172
-
173
- from .data_operations_cuda import batcher
174
-
175
- elif memory == 'cpu':
176
- x_train = transfer_to_cpu(x_train, dtype=dtype)
177
- y_train = transfer_to_cpu(y_train, dtype=y_train.dtype)
178
-
179
- from .data_operations import batcher
180
-
181
- else:
182
- raise ValueError("memory parameter must be 'cpu' or 'gpu'.")
183
-
184
- 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'.")
185
- if target_acc is not None and (target_acc < 0 or target_acc > 1): raise ValueError('target_acc must be in range 0 and 1')
186
- if fit_start is not True and fit_start is not False: raise ValueError('fit_start parameter only be True or False. Please read doc-string')
187
-
188
- # Initialize visualization components
189
- viz_objects = initialize_visualization_for_learner(show_history, neurons_history, neural_web_history, x_train, y_train)
190
-
191
- # Initialize progress bar
192
- if batch_size == 1:
193
- ncols = 76
194
- else:
195
- ncols = 89
196
-
197
- # Initialize variables
198
- best_acc = 0
199
- best_f1 = 0
200
- best_recall = 0
201
- best_precision = 0
202
- best_acc_per_gen_list = []
203
- postfix_dict = {}
204
- loss_list = []
205
- target_pop = []
206
-
207
- progress = initialize_loading_bar(total=activation_potentiation_len, desc="", ncols=ncols, bar_format=bar_format_learner)
208
-
209
- if fit_start is False or pop_size > activation_potentiation_len:
210
- weight_pop, act_pop = define_genomes(input_shape=len(x_train[0]), output_shape=len(y_train[0]), population_size=pop_size, dtype=dtype)
211
-
212
- if start_this_act is not None and start_this_W is not None:
213
- weight_pop[0] = start_this_W
214
- act_pop[0] = start_this_act
215
-
216
- else:
217
- weight_pop = [0] * pop_size
218
- act_pop = [0] * pop_size
219
-
220
- for i in range(gen):
221
- postfix_dict["Gen"] = str(i+1) + '/' + str(gen)
222
- progress.set_postfix(postfix_dict)
223
-
224
- progress.n = 0
225
- progress.last_print_n = 0
226
- progress.update(0)
227
-
228
- for j in range(pop_size):
229
-
230
- x_train_batch, y_train_batch = batcher(x_train, y_train, batch_size=batch_size)
231
-
232
- x_train_batch = cp.array(x_train_batch, dtype=dtype, copy=False)
233
- y_train_batch = cp.array(y_train_batch, dtype=dtype, copy=False)
234
-
235
- if fit_start is True and i == 0 and j < activation_potentiation_len:
236
- act_pop[j] = activation_potentiation[j]
237
- W = fit(x_train_batch, y_train_batch, activation_potentiation=act_pop[-1], dtype=dtype)
238
- weight_pop[j] = W
239
-
240
- model = evaluate(x_train_batch, y_train_batch, W=weight_pop[j], activation_potentiation=act_pop[j])
241
- acc = model[get_acc()]
242
-
243
- if strategy == 'accuracy': target_pop.append(acc)
244
-
245
- elif strategy == 'f1' or strategy == 'precision' or strategy == 'recall':
246
- precision_score, recall_score, f1_score = metrics(y_train_batch, model[get_preds()])
247
-
248
- if strategy == 'precision':
249
- target_pop.append(precision_score)
250
-
251
- if i == 0 and j == 0:
252
- best_precision = precision_score
253
-
254
- if strategy == 'recall':
255
- target_pop.append(recall_score)
256
-
257
- if i == 0 and j == 0:
258
- best_recall = recall_score
259
-
260
- if strategy == 'f1':
261
- target_pop.append(f1_score)
262
-
263
- if i == 0 and j == 0:
264
- best_f1 = f1_score
265
-
266
- if ((strategy == 'accuracy' and acc >= best_acc) or
267
- (strategy == 'f1' and f1_score >= best_f1) or
268
- (strategy == 'precision' and precision_score >= best_precision) or
269
- (strategy == 'recall' and recall_score >= best_recall)):
270
-
271
- best_acc = acc
272
- best_weights = cp.copy(weight_pop[j])
273
- final_activations = act_pop[j].copy() if isinstance(act_pop[j], list) else act_pop[j]
274
-
275
- best_model = model
276
-
277
- final_activations = [final_activations[0]] if len(set(final_activations)) == 1 else final_activations # removing if all same
278
-
279
- if batch_size == 1:
280
- postfix_dict[f"{data} Accuracy"] = cp.round(best_acc, 3)
281
- else:
282
- postfix_dict[f"{data} Batch Accuracy"] = cp.round(best_acc, 3)
283
- progress.set_postfix(postfix_dict)
284
-
285
- if show_current_activations:
286
- print(f", Current Activations={final_activations}", end='')
287
-
288
- if loss == 'categorical_crossentropy':
289
- train_loss = categorical_crossentropy(y_true_batch=transfer_to_gpu(y_train_batch, dtype=y_train_batch.dtype), y_pred_batch=model[get_preds_softmax()])
290
- else:
291
- train_loss = binary_crossentropy(y_true_batch=transfer_to_gpu(y_train_batch, dtype=y_train_batch.dtype), y_pred_batch=model[get_preds_softmax()])
292
-
293
- if batch_size == 1:
294
- postfix_dict[f"{data} Loss"] = cp.round(train_loss, 3)
295
- best_loss = train_loss
296
- else:
297
- postfix_dict[f"{data} Batch Loss"] = cp.round(train_loss, 3)
298
- progress.set_postfix(postfix_dict)
299
- best_loss = train_loss
300
-
301
- # Update visualizations during training
302
- if show_history:
303
- gen_list = range(1, len(best_acc_per_gen_list) + 2)
304
- update_history_plots_for_learner(viz_objects, gen_list, loss_list + [train_loss],
305
- best_acc_per_gen_list + [best_acc], x_train, final_activations)
306
-
307
- if neurons_history:
308
- viz_objects['neurons']['artists'] = (
309
- update_neuron_history_for_learner(cp.copy(best_weights), viz_objects['neurons']['ax'],
310
- viz_objects['neurons']['row'], viz_objects['neurons']['col'],
311
- y_train[0], viz_objects['neurons']['artists'],
312
- data=data, fig1=viz_objects['neurons']['fig'],
313
- acc=best_acc, loss=train_loss)
314
- )
315
-
316
- if neural_web_history:
317
- art5_1, art5_2, art5_3 = draw_neural_web(W=best_weights, ax=viz_objects['web']['ax'],
318
- G=viz_objects['web']['G'], return_objs=True)
319
- art5_list = [art5_1] + [art5_2] + list(art5_3.values())
320
- viz_objects['web']['artists'].append(art5_list)
321
-
322
- # Check target accuracy
323
- if target_acc is not None and best_acc >= target_acc:
324
- progress.close()
325
- train_model = evaluate(x_train, y_train, W=best_weights, loading_bar_status=False,
326
- activation_potentiation=final_activations)
327
-
328
- if loss == 'categorical_crossentropy':
329
- train_loss = categorical_crossentropy(y_true_batch=y_train,
330
- y_pred_batch=train_model[get_preds_softmax()])
331
- else:
332
- train_loss = binary_crossentropy(y_true_batch=y_train,
333
- y_pred_batch=train_model[get_preds_softmax()])
334
-
335
- print('\nActivations: ', final_activations)
336
- print(f'Train Accuracy:', train_model[get_acc()])
337
- print(f'Train Loss: ', train_loss, '\n')
338
-
339
- # Display final visualizations
340
- display_visualizations_for_learner(viz_objects, best_weights, data, best_acc,
341
- train_loss, y_train, interval)
342
- return best_weights, best_model[get_preds()], best_acc, final_activations
343
-
344
- # Check target loss
345
- if target_loss is not None and best_loss <= target_loss:
346
- progress.close()
347
- train_model = evaluate(x_train, y_train, W=best_weights,
348
- activation_potentiation=final_activations)
349
-
350
- if loss == 'categorical_crossentropy':
351
- train_loss = categorical_crossentropy(y_true_batch=y_train,
352
- y_pred_batch=train_model[get_preds_softmax()])
353
- else:
354
- train_loss = binary_crossentropy(y_true_batch=y_train,
355
- y_pred_batch=train_model[get_preds_softmax()])
356
-
357
- print('\nActivations: ', final_activations)
358
- print(f'Train Accuracy: ', train_model[get_acc()])
359
- print(f'Train Loss: ', train_loss, '\n')
360
-
361
- # Display final visualizations
362
- display_visualizations_for_learner(viz_objects, best_weights, data, best_acc,
363
- train_loss, y_train, interval)
364
- return best_weights, best_model[get_preds()], best_acc, final_activations
365
-
366
- progress.update(1)
367
-
368
- best_acc_per_gen_list.append(best_acc)
369
- loss_list.append(best_loss)
370
-
371
- 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)
372
- target_pop = []
373
-
374
- # Early stopping check
375
- if early_stop == True and i > 0:
376
- if best_acc_per_gen_list[i] == best_acc_per_gen_list[i-1]:
377
- progress.close()
378
- train_model = evaluate(x_train, y_train, W=best_weights,
379
- activation_potentiation=final_activations)
380
-
381
- if loss == 'categorical_crossentropy':
382
- train_loss = categorical_crossentropy(y_true_batch=y_train,
383
- y_pred_batch=train_model[get_preds_softmax()])
384
- else:
385
- train_loss = binary_crossentropy(y_true_batch=y_train,
386
- y_pred_batch=train_model[get_preds_softmax()])
387
-
388
- print('\nActivations: ', final_activations)
389
- print(f'Train Accuracy:', train_model[get_acc()])
390
- print(f'Train Loss: ', train_loss, '\n')
391
-
392
- # Display final visualizations
393
- display_visualizations_for_learner(viz_objects, best_weights, data, best_acc,
394
- train_loss, y_train, interval)
395
- return best_weights, best_model[get_preds()], best_acc, final_activations
396
-
397
- # Final evaluation
398
- progress.close()
399
- train_model = evaluate(x_train, y_train, W=best_weights,
400
- activation_potentiation=final_activations)
401
-
402
- if loss == 'categorical_crossentropy':
403
- train_loss = categorical_crossentropy(y_true_batch=y_train, y_pred_batch=train_model[get_preds_softmax()])
404
- else:
405
- train_loss = binary_crossentropy(y_true_batch=y_train, y_pred_batch=train_model[get_preds_softmax()])
406
-
407
- print('\nActivations: ', final_activations)
408
- print(f'Train Accuracy: ', train_model[get_acc()])
409
- print(f'Train Loss : ', train_loss, '\n')
410
-
411
- # Display final visualizations
412
- display_visualizations_for_learner(viz_objects, best_weights, data, best_acc, train_loss, y_train, interval)
413
- return best_weights, best_model[get_preds()], best_acc, final_activations
414
-
415
- def evaluate(
416
- x_test,
417
- y_test,
418
- W,
419
- activation_potentiation=['linear']
420
- ) -> tuple:
421
- """
422
- Evaluates the neural network model using the given test data.
423
-
424
- Args:
425
- x_test (cp.ndarray): Test data.
426
-
427
- y_test (cp.ndarray): Test labels (one-hot encoded).
428
-
429
- W (cp.ndarray): Neural net weight matrix.
430
-
431
- activation_potentiation (list): Activation list. Default = ['linear'].
432
-
433
- Returns:
434
- tuple: Model (list).
435
- """
436
-
437
- x_test = apply_activation(x_test, activation_potentiation)
438
- result = x_test @ W.T
439
- softmax_preds = cp.exp(result) / cp.sum(cp.exp(result), axis=1, keepdims=True); accuracy = (cp.argmax(result, axis=1) == cp.argmax(y_test, axis=1)).mean()
440
-
441
- return W, None, accuracy, None, None, softmax_preds