pyerualjetwork 2.4.8__py3-none-any.whl → 2.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
plan_bi/plan_bi.py DELETED
@@ -1,1555 +0,0 @@
1
- """
2
- Created on Thu May 30 22:12:49 2024
3
-
4
- @author: hasan can beydili
5
- """
6
- import numpy as np
7
- import time
8
- from colorama import Fore,Style
9
- from typing import List, Union
10
- import math
11
- from scipy.special import expit, softmax
12
- import matplotlib.pyplot as plt
13
- import seaborn as sns
14
-
15
- # BUILD -----
16
- def fit(
17
- x_train: List[Union[int, float]],
18
- y_train: List[Union[int, float, str]], # At least two.. and one hot encoded
19
- activation_potential: Union[float],
20
- show_training
21
- ) -> str:
22
-
23
- infoPLAN = """
24
- Creates and configures a PLAN model.
25
-
26
- Args:
27
- x_train (list[num]): List of input data.
28
- y_train (list[num]): List of y_train. (one hot encoded)
29
- activation_potential (float): Input activation potential
30
- show_training (bool, str): True, None or 'final'
31
-
32
- Returns:
33
- list([num]): (Weight matrices list, train_predictions list, Train_acc).
34
- error handled ?: Process status ('e')
35
- """
36
-
37
- if activation_potential < 0 or activation_potential > 1:
38
-
39
- print(Fore.RED + "ERROR101: ACTIVATION potential value must be in range 0-1. from: fit",infoPLAN)
40
- return 'e'
41
-
42
- if len(x_train) != len(y_train):
43
- print(Fore.RED + "ERROR301: x_train list and y_train list must be same length. from: fit",infoPLAN)
44
- return 'e'
45
-
46
- class_count = set()
47
- for sublist in y_train:
48
-
49
- class_count.add(tuple(sublist))
50
-
51
-
52
- class_count = list(class_count)
53
-
54
- y_train = [tuple(sublist) for sublist in y_train]
55
-
56
- neurons = [len(class_count),len(class_count)]
57
- layers = ['fex']
58
-
59
- x_train[0] = np.array(x_train[0])
60
- x_train[0] = x_train[0].ravel()
61
- x_train_size = len(x_train[0])
62
-
63
- W = weight_identification(len(layers) - 1,len(class_count),neurons,x_train_size)
64
- trained_W = [1] * len(W)
65
- print(Fore.GREEN + "Train Started with 0 ERROR" + Style.RESET_ALL,)
66
- y = decode_one_hot(y_train)
67
- start_time = time.time()
68
- for index, inp in enumerate(x_train):
69
- uni_start_time = time.time()
70
- inp = np.array(inp)
71
- inp = inp.ravel()
72
-
73
- if x_train_size != len(inp):
74
- print(Fore.RED +"ERROR304: All input matrices or vectors in x_train list, must be same size. from: fit",infoPLAN + Style.RESET_ALL)
75
- return 'e'
76
-
77
-
78
- neural_layer = inp
79
-
80
- for Lindex, Layer in enumerate(layers):
81
-
82
- neural_layer = normalization(neural_layer)
83
-
84
- if Layer == 'fex':
85
- W[Lindex] = fex(neural_layer, W[Lindex], activation_potential, True, y[index])
86
-
87
-
88
- for i, w in enumerate(W):
89
- trained_W[i] = trained_W[i] + w
90
-
91
- if show_training == True:
92
-
93
- fig, ax = plt.subplots(1, len(class_count), figsize=(18, 14))
94
-
95
- try:
96
- row = x_train[1].shape[0]
97
- col = x_train[1].shape[1]
98
- except:
99
-
100
- print(Fore.MAGENTA + 'WARNING: You try train showing but inputs is raveled. x_train inputs should be reshaped for training_show.', infoPLAN + Style.RESET_ALL)
101
-
102
- try:
103
- row, col = find_numbers(len(x_train[0]))
104
-
105
- except:
106
- print(Fore.RED + 'ERROR: Change show_training to None. Input length cannot be reshaped', infoPLAN + Style.RESET_ALL)
107
- return 'e'
108
-
109
- for j in range(len(class_count)):
110
-
111
- mat = trained_W[0][j,:].reshape(row, col)
112
-
113
- ax[j].imshow(mat, interpolation='sinc', cmap='viridis')
114
- ax[j].set_aspect('equal')
115
-
116
- ax[j].set_xticks([])
117
- ax[j].set_yticks([])
118
- ax[j].set_title(f'{j+1}. Neuron')
119
-
120
-
121
- plt.show()
122
-
123
-
124
- W = weight_identification(len(layers) - 1, len(class_count), neurons, x_train_size)
125
-
126
-
127
- uni_end_time = time.time()
128
-
129
- calculating_est = round((uni_end_time - uni_start_time) * (len(x_train) - index),3)
130
-
131
- if calculating_est < 60:
132
- print('\rest......(sec):',calculating_est,'\n',end= "")
133
-
134
- elif calculating_est > 60 and calculating_est < 3600:
135
- print('\rest......(min):',calculating_est/60,'\n',end= "")
136
-
137
- elif calculating_est > 3600:
138
- print('\rest......(h):',calculating_est/3600,'\n',end= "")
139
-
140
- print('\rTraining: ' , index, "/", len(x_train),"\n", end="")
141
-
142
-
143
- if show_training == 'final':
144
-
145
- fig, ax = plt.subplots(1, len(class_count), figsize=(18, 14))
146
-
147
- try:
148
- row = x_train[1].shape[0]
149
- col = x_train[1].shape[1]
150
- except:
151
-
152
- print(Fore.MAGENTA + 'WARNING: You try train showing but inputs is raveled. x_train inputs should be reshaped for training_show.', infoPLAN + Style.RESET_ALL)
153
-
154
- try:
155
- row, col = find_numbers(len(x_train[0]))
156
-
157
- except:
158
-
159
- print(Fore.RED + 'ERROR: Change show_training to None. Input length cannot be reshaped', infoPLAN + Style.RESET_ALL)
160
- return 'e'
161
-
162
- for j in range(len(class_count)):
163
-
164
- mat = trained_W[0][j,:].reshape(row, col)
165
-
166
- ax[j].imshow(mat, interpolation='sinc', cmap='viridis')
167
- ax[j].set_aspect('equal')
168
-
169
- ax[j].set_xticks([])
170
- ax[j].set_yticks([])
171
- ax[j].set_title(f'{j+1}. Neuron')
172
-
173
-
174
- plt.show()
175
-
176
- EndTime = time.time()
177
-
178
- calculating_est = round(EndTime - start_time,2)
179
-
180
- print(Fore.GREEN + " \nTrain Finished with 0 ERROR\n")
181
-
182
- if calculating_est < 60:
183
- print('Total training time(sec): ',calculating_est)
184
-
185
- elif calculating_est > 60 and calculating_est < 3600:
186
- print('Total training time(min): ',calculating_est/60)
187
-
188
- elif calculating_est > 3600:
189
- print('Total training time(h): ',calculating_est/3600)
190
-
191
-
192
- layers.append('cat')
193
- trained_W.append(np.eye(len(class_count)))
194
-
195
- return trained_W
196
-
197
- def weight_normalization(
198
- W,
199
- class_count
200
- ) -> str:
201
- """
202
- Row(Neuron) based normalization. For unbalanced models.
203
-
204
- Args:
205
- W (list(num)): Trained weight matrix list.
206
- class_count (int): Class count of model.
207
-
208
- Returns:
209
- list([numpy_arrays],[...]): posttrained weight matices of the model. .
210
- """
211
-
212
- for i in range(class_count):
213
-
214
- W[0][i,:] = normalization(W[0][i,:])
215
-
216
- return W
217
-
218
- # FUNCTIONS -----
219
-
220
- def find_numbers(n):
221
- if n <= 1:
222
- raise ValueError("Parameter 'n' must be greater than 1.")
223
-
224
- for i in range(2, int(n**0.5) + 1):
225
- if n % i == 0:
226
- factor1 = i
227
- factor2 = n // i
228
- if factor1 == factor2:
229
- return factor1, factor2
230
-
231
- return None
232
-
233
- def weight_identification(
234
- layer_count, # int: Number of layers in the neural network.
235
- class_count, # int: Number of classes in the classification task.
236
- neurons, # list[num]: List of neuron counts for each layer.
237
- x_train_size # int: Size of the input data.
238
- ) -> str:
239
- """
240
- Identifies the weights for a neural network model.
241
-
242
- Args:
243
- layer_count (int): Number of layers in the neural network.
244
- class_count (int): Number of classes in the classification task.
245
- neurons (list[num]): List of neuron counts for each layer.
246
- x_train_size (int): Size of the input data.
247
-
248
- Returns:
249
- list([numpy_arrays],[...]): Weight matices of the model. .
250
- """
251
-
252
-
253
- Wlen = layer_count + 1
254
- W = [None] * Wlen
255
- W[0] = np.ones((neurons[0],x_train_size))
256
- ws = layer_count - 1
257
- for w in range(ws):
258
- W[w + 1] = np.ones((neurons[w + 1],neurons[w]))
259
-
260
- return W
261
-
262
-
263
- def fex(
264
- Input, # list[num]: Input data.
265
- w, # list[num]: Weight matrix of the neural network.
266
- activation_potential, # float: Threshold value for comparison.
267
- is_training, # bool: Flag indicating if the function is called during training (True or False).
268
- Class # if is during training then which class(label) ? is isnt then put None.
269
- ) -> tuple:
270
- """
271
- Applies feature extraction process to the input data using synaptic pruning.
272
-
273
- Args:
274
- Input (list[num]): Input data.
275
- w (list[num]): Weight matrix of the neural network.
276
- activation_potential (float): Threshold value for comparison.
277
- piece (int): Which set of neurons will information be transferred to?
278
- is_training (bool): Flag indicating if the function is called during training (True or False).
279
- Class (int): if is during training then which class(label) ? is isnt then put None.
280
- Returns:
281
- tuple: A tuple (vector) containing the neural layer result and the updated weight matrix.
282
- """
283
-
284
- if is_training == True:
285
-
286
- Input[Input < activation_potential] = 0
287
- Input[Input > activation_potential] = 1
288
-
289
- w[Class,:] = Input
290
-
291
- return w
292
-
293
- else:
294
-
295
- Input[Input < activation_potential] = 0
296
- Input[Input > activation_potential] = 1
297
-
298
- neural_layer = np.dot(w, Input)
299
-
300
- return neural_layer
301
-
302
-
303
- def normalization(
304
- Input # num: Input data to be normalized.
305
- ):
306
- """
307
- Normalizes the input data using maximum absolute scaling.
308
-
309
- Args:
310
- Input num: Input data to be normalized.
311
-
312
- Returns:
313
- num: Scaled input data after normalization.
314
- """
315
-
316
-
317
- AbsVector = np.abs(Input)
318
-
319
- MaxAbs = np.max(AbsVector)
320
-
321
- ScaledInput = Input / MaxAbs
322
-
323
- return ScaledInput
324
-
325
-
326
- def Softmax(
327
- x # num: Input data to be transformed using softmax function.
328
- ):
329
- """
330
- Applies the softmax function to the input data.
331
-
332
- Args:
333
- num: Input data to be transformed using softmax function.
334
-
335
- Returns:
336
- num: Transformed data after applying softmax function.
337
- """
338
-
339
- return softmax(x)
340
-
341
-
342
- def Sigmoid(
343
- x # list[num]: Input data to be transformed using sigmoid function.
344
- ):
345
- """
346
- Applies the sigmoid function to the input data.
347
-
348
- Args:
349
- num: Input data to be transformed using sigmoid function.
350
-
351
- Returns:
352
- num: Transformed data after applying sigmoid function.
353
- """
354
- return expit(x)
355
-
356
-
357
- def Relu(
358
- x # list[num]: Input data to be transformed using ReLU function.
359
- ):
360
- """
361
- Applies the Rectified Linear Unit (ReLU) function to the input data.
362
-
363
- Args:
364
- num: Input data to be transformed using ReLU function.
365
-
366
- Returns:
367
- num: Transformed data after applying ReLU function.
368
- """
369
-
370
-
371
- return np.maximum(0, x)
372
-
373
-
374
-
375
-
376
- def evaluate(
377
- x_test, # list[num]: Test input data.
378
- y_test, # list[num]: Test labels.
379
- activation_potential, # float: Input activation potential
380
- show_metrices, # (bool): (True or False)
381
- W # list[num]: Weight matrix of the neural network.
382
- ) -> tuple:
383
- infoTestModel = """
384
- Tests the neural network model with the given test data.
385
-
386
- Args:
387
- x_test (list[num]): Test input data.
388
- y_test (list[num]): Test labels.
389
- activation_potential (float): Input activation potential
390
- show_metrices (bool): (True or False)
391
- W (list[num]): Weight matrix list of the neural network.
392
-
393
- Returns:
394
- tuple: A tuple containing the predicted labels and the accuracy of the model.
395
- """
396
-
397
- layers = ['fex','cat']
398
-
399
-
400
- try:
401
- Wc = [0] * len(W) # Wc = weight copy
402
- true = 0
403
- y_preds = [-1] * len(y_test)
404
- acc_list = []
405
- for i, w in enumerate(W):
406
- Wc[i] = np.copy(w)
407
- print('\rCopying weights.....',i+1,'/',len(W),end = "")
408
-
409
- print(Fore.GREEN + "\n\nTest Started with 0 ERROR\n" + Style.RESET_ALL)
410
- start_time = time.time()
411
- for inpIndex,Input in enumerate(x_test):
412
- Input = np.array(Input)
413
- Input = Input.ravel()
414
- uni_start_time = time.time()
415
- neural_layer = Input
416
-
417
- for index, Layer in enumerate(layers):
418
-
419
- neural_layer = normalization(neural_layer)
420
-
421
- if layers[index] == 'fex':
422
- neural_layer = fex(neural_layer, W[index], activation_potential, False, None)
423
- if layers[index] == 'cat':
424
- neural_layer = np.dot(W[index], neural_layer)
425
-
426
- for i, w in enumerate(Wc):
427
- W[i] = np.copy(w)
428
- RealOutput = np.argmax(y_test[inpIndex])
429
- PredictedOutput = np.argmax(neural_layer)
430
- if RealOutput == PredictedOutput:
431
- true += 1
432
- acc = true / len(y_test)
433
- if show_metrices == True:
434
- acc_list.append(acc)
435
- y_preds[inpIndex] = PredictedOutput
436
-
437
- uni_end_time = time.time()
438
-
439
- calculating_est = round((uni_end_time - uni_start_time) * (len(x_test) - inpIndex),3)
440
-
441
- if calculating_est < 60:
442
- print('\rest......(sec):',calculating_est,'\n',end= "")
443
- print('\rTest accuracy: ' ,acc ,"\n", end="")
444
-
445
- elif calculating_est > 60 and calculating_est < 3600:
446
- print('\rest......(min):',calculating_est/60,'\n',end= "")
447
- print('\rTest accuracy: ' ,acc ,"\n", end="")
448
-
449
- elif calculating_est > 3600:
450
- print('\rest......(h):',calculating_est/3600,'\n',end= "")
451
- print('\rTest accuracy: ' ,acc ,"\n", end="")
452
- if show_metrices == True:
453
- plot_evaluate(y_test, y_preds, acc_list)
454
-
455
- EndTime = time.time()
456
- for i, w in enumerate(Wc):
457
- W[i] = np.copy(w)
458
-
459
- calculating_est = round(EndTime - start_time,2)
460
-
461
- print(Fore.GREEN + "\nTest Finished with 0 ERROR\n")
462
-
463
- if calculating_est < 60:
464
- print('Total testing time(sec): ',calculating_est)
465
-
466
- elif calculating_est > 60 and calculating_est < 3600:
467
- print('Total testing time(min): ',calculating_est/60)
468
-
469
- elif calculating_est > 3600:
470
- print('Total testing time(h): ',calculating_est/3600)
471
-
472
- if acc >= 0.8:
473
- print(Fore.GREEN + '\nTotal Test accuracy: ' ,acc, '\n' + Style.RESET_ALL)
474
-
475
- elif acc < 0.8 and acc > 0.6:
476
- print(Fore.MAGENTA + '\nTotal Test accuracy: ' ,acc, '\n' + Style.RESET_ALL)
477
-
478
- elif acc <= 0.6:
479
- print(Fore.RED+ '\nTotal Test accuracy: ' ,acc, '\n' + Style.RESET_ALL)
480
-
481
-
482
-
483
- except:
484
-
485
- print(Fore.RED + "ERROR: Testing model parameters like 'activation_potential' must be same as trained model. Check parameters. Are you sure weights are loaded ? from: evaluate" + infoTestModel + Style.RESET_ALL)
486
- return 'e'
487
-
488
-
489
-
490
- return W,y_preds,acc
491
-
492
-
493
- def multiple_evaluate(
494
- x_test, # list[num]: Test input data.
495
- y_test, # list[num]: Test labels.
496
- activation_potentials, # float: Input activation potential
497
- show_metrices, # (bool): (True or False)
498
- MW # list[list[num]]: Weight matrix of the neural network.
499
- ) -> tuple:
500
- infoTestModel = """
501
- Tests the neural network model with the given test data.
502
-
503
- Args:
504
- x_test (list[num]): Test input data.
505
- y_test (list[num]): Test labels.
506
- activation_potential (float): Input activation potential
507
- show_metrices (bool): (True or False)
508
- MW (list(list[num])): Multiple Weight matrix list of the neural network. (Multiple model testing)
509
-
510
- Returns:
511
- tuple: A tuple containing the predicted labels and the accuracy of the model.
512
- """
513
-
514
- layers = ['fex','cat']
515
-
516
- try:
517
- acc_list = []
518
- print(Fore.GREEN + "\n\nTest Started with 0 ERROR\n" + Style.RESET_ALL)
519
- start_time = time.time()
520
- true = 0
521
- for inpIndex,Input in enumerate(x_test):
522
-
523
- output_layer = 0
524
-
525
- for m, Model in enumerate(MW):
526
-
527
- W = Model
528
-
529
- Wc = [0] * len(W) # Wc = weight copy
530
-
531
- y_preds = [None] * len(y_test)
532
- for i, w in enumerate(W):
533
- Wc[i] = np.copy(w)
534
-
535
- Input = np.array(Input)
536
- Input = Input.ravel()
537
- uni_start_time = time.time()
538
- neural_layer = Input
539
-
540
- for index, Layer in enumerate(layers):
541
-
542
- neural_layer = normalization(neural_layer)
543
-
544
- if layers[index] == 'fex':
545
- neural_layer = fex(neural_layer, W[index], activation_potentials[m], None, False, None)
546
- if layers[index] == 'cat':
547
- neural_layer = np.dot(W[index], neural_layer)
548
-
549
- output_layer += neural_layer
550
-
551
- for i, w in enumerate(Wc):
552
- W[i] = np.copy(w)
553
- for i, w in enumerate(Wc):
554
- W[i] = np.copy(w)
555
- RealOutput = np.argmax(y_test[inpIndex])
556
- PredictedOutput = np.argmax(output_layer)
557
- if RealOutput == PredictedOutput:
558
- true += 1
559
- acc = true / len(y_test)
560
- if show_metrices == True:
561
-
562
- acc_list.append(acc)
563
-
564
- y_preds[inpIndex] = PredictedOutput
565
-
566
- uni_end_time = time.time()
567
-
568
- calculating_est = round((uni_end_time - uni_start_time) * (len(x_test) - inpIndex),3)
569
-
570
- if calculating_est < 60:
571
- print('\rest......(sec):',calculating_est,'\n',end= "")
572
- print('\rTest accuracy: ' ,acc ,"\n", end="")
573
-
574
- elif calculating_est > 60 and calculating_est < 3600:
575
- print('\rest......(min):',calculating_est/60,'\n',end= "")
576
- print('\rTest accuracy: ' ,acc ,"\n", end="")
577
-
578
- elif calculating_est > 3600:
579
- print('\rest......(h):',calculating_est/3600,'\n',end= "")
580
- print('\rTest accuracy: ' ,acc ,"\n", end="")
581
-
582
- if show_metrices == True:
583
-
584
- plot_evaluate(y_test, y_preds, acc_list)
585
-
586
- EndTime = time.time()
587
- for i, w in enumerate(Wc):
588
- W[i] = np.copy(w)
589
-
590
- calculating_est = round(EndTime - start_time,2)
591
-
592
- print(Fore.GREEN + "\nTest Finished with 0 ERROR\n")
593
-
594
- if calculating_est < 60:
595
- print('Total testing time(sec): ',calculating_est)
596
-
597
- elif calculating_est > 60 and calculating_est < 3600:
598
- print('Total testing time(min): ',calculating_est/60)
599
-
600
- elif calculating_est > 3600:
601
- print('Total testing time(h): ',calculating_est/3600)
602
-
603
- if acc >= 0.8:
604
- print(Fore.GREEN + '\nTotal Test accuracy: ' ,acc, '\n' + Style.RESET_ALL)
605
-
606
- elif acc < 0.8 and acc > 0.6:
607
- print(Fore.MAGENTA + '\nTotal Test accuracy: ' ,acc, '\n' + Style.RESET_ALL)
608
-
609
- elif acc <= 0.6:
610
- print(Fore.RED+ '\nTotal Test accuracy: ' ,acc, '\n' + Style.RESET_ALL)
611
-
612
-
613
-
614
- except:
615
-
616
- print(Fore.RED + "ERROR: Testing model parameters like 'activation_potential' must be same as trained model. Check parameters. Are you sure weights are loaded ? from: evaluate" + infoTestModel + Style.RESET_ALL)
617
- return 'e'
618
-
619
-
620
-
621
- return W,y_preds,acc
622
-
623
- def save_model(model_name,
624
- model_type,
625
- class_count,
626
- activation_potential,
627
- test_acc,
628
- weights_type,
629
- weights_format,
630
- model_path,
631
- scaler_params,
632
- W
633
- ):
634
-
635
- infosave_model = """
636
- Function to save a pruning learning model.
637
-
638
- Arguments:
639
- model_name (str): Name of the model.
640
- model_type (str): Type of the model.(options: PLAN)
641
- class_count (int): Number of classes.
642
- activation_potential (float): Activation potential.
643
- test_acc (float): Test accuracy of the model.
644
- weights_type (str): Type of weights to save (options: 'txt', 'npy', 'mat').
645
- WeightFormat (str): Format of the weights (options: 'd', 'f', 'raw').
646
- model_path (str): Path where the model will be saved. For example: C:/Users/beydili/Desktop/denemePLAN/
647
- scaler_params (int, float): standard scaler params list: mean,std. If not used standard scaler then be: None.
648
- W: Weights list of the model.
649
-
650
- Returns:
651
- str: Message indicating if the model was saved successfully or encountered an error.
652
- """
653
-
654
- # Operations to be performed by the function will be written here
655
- pass
656
-
657
- layers = ['fex','cat']
658
-
659
- if weights_type != 'txt' and weights_type != 'npy' and weights_type != 'mat':
660
- print(Fore.RED + "ERROR110: Save Weight type (File Extension) Type must be 'txt' or 'npy' or 'mat' from: save_model" + infosave_model + Style.RESET_ALL)
661
- return 'e'
662
-
663
- if weights_format != 'd' and weights_format != 'f' and weights_format != 'raw':
664
- print(Fore.RED + "ERROR111: Weight Format Type must be 'd' or 'f' or 'raw' from: save_model" + infosave_model + Style.RESET_ALL)
665
- return 'e'
666
-
667
- NeuronCount = 0
668
- SynapseCount = 0
669
-
670
- try:
671
- for w in W:
672
- NeuronCount += np.shape(w)[0]
673
- SynapseCount += np.shape(w)[0] * np.shape(w)[1]
674
- except:
675
-
676
- print(Fore.RED + "ERROR: Weight matrices has a problem from: save_model" + infosave_model + Style.RESET_ALL)
677
- return 'e'
678
- import pandas as pd
679
- from datetime import datetime
680
- from scipy import io
681
-
682
- data = {'MODEL NAME': model_name,
683
- 'MODEL TYPE': model_type,
684
- 'LAYERS': layers,
685
- 'LAYER COUNT': len(layers),
686
- 'CLASS COUNT': class_count,
687
- 'ACTIVATION POTENTIAL': activation_potential,
688
- 'NEURON COUNT': NeuronCount,
689
- 'SYNAPSE COUNT': SynapseCount,
690
- 'TEST ACCURACY': test_acc,
691
- 'SAVE DATE': datetime.now(),
692
- 'WEIGHTS TYPE': weights_type,
693
- 'WEIGHTS FORMAT': weights_format,
694
- 'MODEL PATH': model_path,
695
- 'STANDARD SCALER': scaler_params
696
- }
697
- try:
698
-
699
- df = pd.DataFrame(data)
700
-
701
-
702
- df.to_csv(model_path + model_name + '.txt', sep='\t', index=False)
703
-
704
-
705
- except:
706
-
707
- print(Fore.RED + "ERROR: Model log not saved probably model_path incorrect. Check the log parameters from: save_model" + infosave_model + Style.RESET_ALL)
708
- return 'e'
709
- try:
710
-
711
- if weights_type == 'txt' and weights_format == 'd':
712
-
713
- for i, w in enumerate(W):
714
- np.savetxt(model_path + model_name + str(i+1) + 'w.txt' , w, fmt='%d')
715
-
716
- if weights_type == 'txt' and weights_format == 'f':
717
-
718
- for i, w in enumerate(W):
719
- np.savetxt(model_path + model_name + str(i+1) + 'w.txt' , w, fmt='%f')
720
-
721
- if weights_type == 'txt' and weights_format == 'raw':
722
-
723
- for i, w in enumerate(W):
724
- np.savetxt(model_path + model_name + str(i+1) + 'w.txt' , w)
725
-
726
-
727
- ###
728
-
729
-
730
- if weights_type == 'npy' and weights_format == 'd':
731
-
732
- for i, w in enumerate(W):
733
- np.save(model_path + model_name + str(i+1) + 'w.npy', w.astype(int))
734
-
735
- if weights_type == 'npy' and weights_format == 'f':
736
-
737
- for i, w in enumerate(W):
738
- np.save(model_path + model_name + str(i+1) + 'w.npy' , w, w.astype(float))
739
-
740
- if weights_type == 'npy' and weights_format == 'raw':
741
-
742
- for i, w in enumerate(W):
743
- np.save(model_path + model_name + str(i+1) + 'w.npy' , w)
744
-
745
-
746
- ###
747
-
748
-
749
- if weights_type == 'mat' and weights_format == 'd':
750
-
751
- for i, w in enumerate(W):
752
- w = {'w': w.astype(int)}
753
- io.savemat(model_path + model_name + str(i+1) + 'w.mat', w)
754
-
755
- if weights_type == 'mat' and weights_format == 'f':
756
-
757
- for i, w in enumerate(W):
758
- w = {'w': w.astype(float)}
759
- io.savemat(model_path + model_name + str(i+1) + 'w.mat', w)
760
-
761
- if weights_type == 'mat' and weights_format == 'raw':
762
-
763
- for i, w in enumerate(W):
764
- w = {'w': w}
765
- io.savemat(model_path + model_name + str(i+1) + 'w.mat', w)
766
-
767
- except:
768
-
769
- print(Fore.RED + "ERROR: Model Weights not saved. Check the Weight parameters. SaveFilePath expl: 'C:/Users/hasancanbeydili/Desktop/denemePLAN/' from: save_model" + infosave_model + Style.RESET_ALL)
770
- return 'e'
771
- print(df)
772
- message = (
773
- Fore.GREEN + "Model Saved Successfully\n" +
774
- Fore.MAGENTA + "Don't forget, if you want to load model: model log file and weight files must be in the same directory." +
775
- Style.RESET_ALL
776
- )
777
-
778
- return print(message)
779
-
780
-
781
- def load_model(model_name,
782
- model_path,
783
- ):
784
- infoload_model = """
785
- Function to load a pruning learning model.
786
-
787
- Arguments:
788
- model_name (str): Name of the model.
789
- model_path (str): Path where the model is saved.
790
-
791
- Returns:
792
- lists: W(list[num]), activation_potential, DataFrame of the model
793
- """
794
- pass
795
-
796
-
797
- import pandas as pd
798
- import scipy.io as sio
799
-
800
- try:
801
-
802
- df = pd.read_csv(model_path + model_name + '.' + 'txt', delimiter='\t')
803
-
804
- except:
805
-
806
- print(Fore.RED + "ERROR: Model Path error. accaptable form: 'C:/Users/hasancanbeydili/Desktop/denemePLAN/' from: load_model" + infoload_model + Style.RESET_ALL)
807
-
808
- model_name = str(df['MODEL NAME'].iloc[0])
809
- layer_count = int(df['LAYER COUNT'].iloc[0])
810
- activation_potential = int(df['ACTIVATION POTENTIAL'].iloc[0])
811
- WeightType = str(df['WEIGHTS TYPE'].iloc[0])
812
- model_path = str(df['MODEL PATH'].iloc[0])
813
-
814
-
815
- W = [0] * layer_count
816
-
817
- if WeightType == 'txt':
818
- for i in range(layer_count):
819
- W[i] = np.loadtxt(model_path + model_name + str(i+1) + 'w.txt')
820
- elif WeightType == 'npy':
821
- for i in range(layer_count):
822
- W[i] = np.load(model_path + model_name + str(i+1) + 'w.npy')
823
- elif WeightType == 'mat':
824
- for i in range(layer_count):
825
- W[i] = sio.loadmat(model_path + model_name + str(i+1) + 'w.mat')
826
- else:
827
- raise ValueError(Fore.RED + "Incorrect weight type value. Value must be 'txt', 'npy' or 'mat' from: load_model." + infoload_model + Style.RESET_ALL)
828
- print(Fore.GREEN + "Model loaded succesfully" + Style.RESET_ALL)
829
- return W, activation_potential, df
830
-
831
- def predict_model_ssd(Input, model_name, model_path):
832
-
833
- infopredict_model_ssd = """
834
- Function to make a prediction using a divided pruning learning artificial neural network (PLAN).
835
-
836
- Arguments:
837
- Input (num): Input data for the model (single vector or single matrix).
838
- model_name (str): Name of the model.
839
- model_path (str): Path where the model is saved.
840
- Returns:
841
- ndarray: Output from the model.
842
- """
843
- W, activation_potential, df = load_model(model_name,model_path)
844
-
845
- scaler_params = str(df['STANDARD SCALER'].iloc[0])
846
-
847
- if scaler_params != None:
848
-
849
- Input = standard_scaler(None, Input, scaler_params)
850
-
851
- layers = ['fex','cat']
852
-
853
- Wc = [0] * len(W)
854
- for i, w in enumerate(W):
855
- Wc[i] = np.copy(w)
856
- try:
857
- neural_layer = Input
858
- neural_layer = np.array(neural_layer)
859
- neural_layer = neural_layer.ravel()
860
- for index, Layer in enumerate(layers):
861
-
862
- neural_layer = normalization(neural_layer)
863
-
864
- if layers[index] == 'fex':
865
- neural_layer = fex(neural_layer, W[index], activation_potential, False, None)
866
- if layers[index] == 'cat':
867
- neural_layer = np.dot(W[index], neural_layer)
868
- except:
869
- print(Fore.RED + "ERROR: The input was probably entered incorrectly. from: predict_model_ssd" + infopredict_model_ssd + Style.RESET_ALL)
870
- return 'e'
871
- for i, w in enumerate(Wc):
872
- W[i] = np.copy(w)
873
- return neural_layer
874
-
875
-
876
- def predict_model_ram(Input, activation_potential, scaler_params, W):
877
-
878
- infopredict_model_ram = """
879
- Function to make a prediction using a divided pruning learning artificial neural network (PLAN).
880
- from weights and parameters stored in memory.
881
-
882
- Arguments:
883
- Input (list or ndarray): Input data for the model (single vector or single matrix).
884
- activation_potential (float): Activation potential.
885
- scaler_params (int, float): standard scaler params list: mean,std. If not used standard scaler then be: None.
886
- W (list of ndarrays): Weights of the model.
887
-
888
- Returns:
889
- ndarray: Output from the model.
890
- """
891
- if scaler_params != None:
892
-
893
- Input = standard_scaler(None, Input, scaler_params)
894
-
895
- layers = ['fex','cat']
896
-
897
- Wc = [0] * len(W)
898
- for i, w in enumerate(W):
899
- Wc[i] = np.copy(w)
900
- try:
901
- neural_layer = Input
902
- neural_layer = np.array(neural_layer)
903
- neural_layer = neural_layer.ravel()
904
- for index, Layer in enumerate(layers):
905
-
906
- neural_layer = normalization(neural_layer)
907
-
908
- if layers[index] == 'fex':
909
- neural_layer = fex(neural_layer, W[index], activation_potential, False, None)
910
- if layers[index] == 'cat':
911
- neural_layer = np.dot(W[index], neural_layer)
912
-
913
- except:
914
- print(Fore.RED + "ERROR: Unexpected input or wrong model parameters from: predict_model_ram." + infopredict_model_ram + Style.RESET_ALL)
915
- return 'e'
916
- for i, w in enumerate(Wc):
917
- W[i] = np.copy(w)
918
- return neural_layer
919
-
920
-
921
-
922
- def auto_balancer(x_train, y_train):
923
-
924
- infoauto_balancer = """
925
- Function to balance the training data across different classes.
926
-
927
- Arguments:
928
- x_train (list): Input data for training.
929
- y_train (list): Labels corresponding to the input data.
930
-
931
- Returns:
932
- tuple: A tuple containing balanced input data and labels.
933
- """
934
- classes = np.arange(y_train.shape[1])
935
- class_count = len(classes)
936
-
937
- try:
938
- ClassIndices = {i: np.where(np.array(y_train)[:, i] == 1)[
939
- 0] for i in range(class_count)}
940
- classes = [len(ClassIndices[i]) for i in range(class_count)]
941
-
942
- if len(set(classes)) == 1:
943
- print(Fore.WHITE + "INFO: All training data have already balanced. from: auto_balancer" + Style.RESET_ALL)
944
- return x_train, y_train
945
-
946
- MinCount = min(classes)
947
-
948
- BalancedIndices = []
949
- for i in range(class_count):
950
- if len(ClassIndices[i]) > MinCount:
951
- SelectedIndices = np.random.choice(
952
- ClassIndices[i], MinCount, replace=False)
953
- else:
954
- SelectedIndices = ClassIndices[i]
955
- BalancedIndices.extend(SelectedIndices)
956
-
957
- BalancedInputs = [x_train[idx] for idx in BalancedIndices]
958
- BalancedLabels = [y_train[idx] for idx in BalancedIndices]
959
-
960
- print(Fore.GREEN + "All Training Data Succesfully Balanced from: " + str(len(x_train)
961
- ) + " to: " + str(len(BalancedInputs)) + ". from: auto_balancer " + Style.RESET_ALL)
962
- except:
963
- print(Fore.RED + "ERROR: Inputs and labels must be same length check parameters" + infoauto_balancer)
964
- return 'e'
965
-
966
- return BalancedInputs, BalancedLabels
967
-
968
-
969
- def synthetic_augmentation(x_train, y_train):
970
- """
971
- Generates synthetic examples to balance classes with fewer examples.
972
-
973
- Arguments:
974
- x -- Input dataset (examples) - list format
975
- y -- Class labels (one-hot encoded) - list format
976
-
977
- Returns:
978
- x_balanced -- Balanced input dataset (list format)
979
- y_balanced -- Balanced class labels (one-hot encoded, list format)
980
- """
981
- x = x_train
982
- y = y_train
983
- classes = np.arange(y_train.shape[1])
984
- class_count = len(classes)
985
-
986
- # Calculate class distribution
987
- class_distribution = {i: 0 for i in range(class_count)}
988
- for label in y:
989
- class_distribution[np.argmax(label)] += 1
990
-
991
- max_class_count = max(class_distribution.values())
992
-
993
- x_balanced = list(x)
994
- y_balanced = list(y)
995
-
996
- for class_label in range(class_count):
997
- class_indices = [i for i, label in enumerate(
998
- y) if np.argmax(label) == class_label]
999
- num_samples = len(class_indices)
1000
-
1001
- if num_samples < max_class_count:
1002
- while num_samples < max_class_count:
1003
-
1004
- random_indices = np.random.choice(
1005
- class_indices, 2, replace=False)
1006
- sample1 = x[random_indices[0]]
1007
- sample2 = x[random_indices[1]]
1008
-
1009
- synthetic_sample = sample1 + \
1010
- (np.array(sample2) - np.array(sample1)) * np.random.rand()
1011
-
1012
- x_balanced.append(synthetic_sample.tolist())
1013
- y_balanced.append(y[class_indices[0]])
1014
-
1015
- num_samples += 1
1016
-
1017
- return np.array(x_balanced), np.array(y_balanced)
1018
-
1019
-
1020
- def standard_scaler(x_train, x_test, scaler_params=None):
1021
- info_standard_scaler = """
1022
- Standardizes training and test datasets. x_test may be None.
1023
-
1024
- Args:
1025
- train_data: numpy.ndarray
1026
- Training data
1027
- test_data: numpy.ndarray
1028
- Test data
1029
-
1030
- Returns:
1031
- list:
1032
- Scaler parameters: mean and std
1033
- tuple
1034
- Standardized training and test datasets
1035
- """
1036
- try:
1037
-
1038
- if scaler_params == None and x_test != None:
1039
-
1040
- mean = np.mean(x_train, axis=0)
1041
- std = np.std(x_train, axis=0)
1042
- train_data_scaled = (x_train - mean) / std
1043
- test_data_scaled = (x_test - mean) / std
1044
-
1045
- scaler_params = [mean, std]
1046
-
1047
- return scaler_params, train_data_scaled, test_data_scaled
1048
-
1049
- if scaler_params == None and x_test == None:
1050
-
1051
- mean = np.mean(x_train, axis=0)
1052
- std = np.std(x_train, axis=0)
1053
- train_data_scaled = (x_train - mean) / std
1054
-
1055
- scaler_params = [mean, std]
1056
-
1057
- return scaler_params, train_data_scaled
1058
-
1059
- if scaler_params != None:
1060
- test_data_scaled = (x_test - scaler_params[0]) / scaler_params[1]
1061
- return test_data_scaled
1062
-
1063
- except:
1064
- print(
1065
- Fore.RED + "ERROR: x_train and x_test must be list[numpyarray] from standard_scaler" + info_standard_scaler)
1066
-
1067
- def encode_one_hot(y_train, y_test):
1068
- info_one_hot_encode = """
1069
- Performs one-hot encoding on y_train and y_test data..
1070
-
1071
- Args:
1072
- y_train (numpy.ndarray): Eğitim etiketi verisi.
1073
- y_test (numpy.ndarray): Test etiketi verisi.
1074
-
1075
- Returns:
1076
- tuple: One-hot encoded y_train ve y_test verileri.
1077
- """
1078
- try:
1079
- classes = np.unique(y_train)
1080
- class_count = len(classes)
1081
-
1082
- class_to_index = {cls: idx for idx, cls in enumerate(classes)}
1083
-
1084
- y_train_encoded = np.zeros((y_train.shape[0], class_count))
1085
- for i, label in enumerate(y_train):
1086
- y_train_encoded[i, class_to_index[label]] = 1
1087
-
1088
- y_test_encoded = np.zeros((y_test.shape[0], class_count))
1089
- for i, label in enumerate(y_test):
1090
- y_test_encoded[i, class_to_index[label]] = 1
1091
- except:
1092
- print(Fore.RED + 'ERROR: y_train and y_test must be numpy array. from: one_hot_encode' + info_one_hot_encode)
1093
-
1094
- return y_train_encoded, y_test_encoded
1095
-
1096
-
1097
- def split(X, y, test_size, random_state):
1098
- """
1099
- Splits the given X (features) and y (labels) data into training and testing subsets.
1100
-
1101
- Args:
1102
- X (numpy.ndarray): Features data.
1103
- y (numpy.ndarray): Labels data.
1104
- test_size (float or int): Proportion or number of samples for the test subset.
1105
- random_state (int or None): Seed for random state.
1106
-
1107
- Returns:
1108
- tuple: x_train, x_test, y_train, y_test as ordered training and testing data subsets.
1109
- """
1110
-
1111
- num_samples = X.shape[0]
1112
-
1113
- if isinstance(test_size, float):
1114
- test_size = int(test_size * num_samples)
1115
- elif isinstance(test_size, int):
1116
- if test_size > num_samples:
1117
- raise ValueError(
1118
- "test_size cannot be larger than the number of samples.")
1119
- else:
1120
- raise ValueError("test_size should be float or int.")
1121
-
1122
- if random_state is not None:
1123
- np.random.seed(random_state)
1124
-
1125
- indices = np.arange(num_samples)
1126
- np.random.shuffle(indices)
1127
-
1128
- test_indices = indices[:test_size]
1129
- train_indices = indices[test_size:]
1130
-
1131
- x_train, x_test = X[train_indices], X[test_indices]
1132
- y_train, y_test = y[train_indices], y[test_indices]
1133
-
1134
- return x_train, x_test, y_train, y_test
1135
-
1136
-
1137
- def metrics(y_ts, test_preds, average='weighted'):
1138
- """
1139
- Calculates precision, recall and F1 score for a classification task.
1140
-
1141
- Args:
1142
- y_ts (list or numpy.ndarray): True labels.
1143
- test_preds (list or numpy.ndarray): Predicted labels.
1144
- average (str): Type of averaging ('micro', 'macro', 'weighted').
1145
-
1146
- Returns:
1147
- tuple: Precision, recall, F1 score.
1148
- """
1149
- y_test_d = decode_one_hot(y_ts)
1150
- y_test_d = np.array(y_test_d)
1151
- y_pred = np.array(test_preds)
1152
-
1153
- if y_test_d.ndim > 1:
1154
- y_test_d = y_test_d.reshape(-1)
1155
- if y_pred.ndim > 1:
1156
- y_pred = y_pred.reshape(-1)
1157
-
1158
- tp = {}
1159
- fp = {}
1160
- fn = {}
1161
-
1162
- classes = np.unique(np.concatenate((y_test_d, y_pred)))
1163
-
1164
- for c in classes:
1165
- tp[c] = 0
1166
- fp[c] = 0
1167
- fn[c] = 0
1168
-
1169
- for c in classes:
1170
- for true, pred in zip(y_test_d, y_pred):
1171
- if true == c and pred == c:
1172
- tp[c] += 1
1173
- elif true != c and pred == c:
1174
- fp[c] += 1
1175
- elif true == c and pred != c:
1176
- fn[c] += 1
1177
-
1178
- precision = {}
1179
- recall = {}
1180
- f1 = {}
1181
-
1182
- for c in classes:
1183
- precision[c] = tp[c] / (tp[c] + fp[c]) if (tp[c] + fp[c]) > 0 else 0
1184
- recall[c] = tp[c] / (tp[c] + fn[c]) if (tp[c] + fn[c]) > 0 else 0
1185
- f1[c] = 2 * (precision[c] * recall[c]) / (precision[c] + recall[c]) if (precision[c] + recall[c]) > 0 else 0
1186
-
1187
- if average == 'micro':
1188
- precision_val = np.sum(list(tp.values())) / (np.sum(list(tp.values())) + np.sum(list(fp.values()))) if (np.sum(list(tp.values())) + np.sum(list(fp.values()))) > 0 else 0
1189
- recall_val = np.sum(list(tp.values())) / (np.sum(list(tp.values())) + np.sum(list(fn.values()))) if (np.sum(list(tp.values())) + np.sum(list(fn.values()))) > 0 else 0
1190
- f1_val = 2 * (precision_val * recall_val) / (precision_val + recall_val) if (precision_val + recall_val) > 0 else 0
1191
-
1192
- elif average == 'macro':
1193
- precision_val = np.mean(list(precision.values()))
1194
- recall_val = np.mean(list(recall.values()))
1195
- f1_val = np.mean(list(f1.values()))
1196
-
1197
- elif average == 'weighted':
1198
- weights = np.array([np.sum(y_test_d == c) for c in classes])
1199
- weights = weights / np.sum(weights)
1200
- precision_val = np.sum([weights[i] * precision[classes[i]] for i in range(len(classes))])
1201
- recall_val = np.sum([weights[i] * recall[classes[i]] for i in range(len(classes))])
1202
- f1_val = np.sum([weights[i] * f1[classes[i]] for i in range(len(classes))])
1203
-
1204
- else:
1205
- raise ValueError("Invalid value for 'average'. Choose from 'micro', 'macro', 'weighted'.")
1206
-
1207
- return precision_val, recall_val, f1_val
1208
-
1209
-
1210
- def decode_one_hot(encoded_data):
1211
- """
1212
- Decodes one-hot encoded data to original categorical labels.
1213
-
1214
- Args:
1215
- encoded_data (numpy.ndarray): One-hot encoded data with shape (n_samples, n_classes).
1216
-
1217
- Returns:
1218
- numpy.ndarray: Decoded categorical labels with shape (n_samples,).
1219
- """
1220
-
1221
- decoded_labels = np.argmax(encoded_data, axis=1)
1222
-
1223
- return decoded_labels
1224
-
1225
-
1226
- def roc_curve(y_true, y_score):
1227
- """
1228
- Compute Receiver Operating Characteristic (ROC) curve.
1229
-
1230
- Parameters:
1231
- y_true : array, shape = [n_samples]
1232
- True binary labels in range {0, 1} or {-1, 1}.
1233
- y_score : array, shape = [n_samples]
1234
- Target scores, can either be probability estimates of the positive class,
1235
- confidence values, or non-thresholded measure of decisions (as returned
1236
- by decision_function on some classifiers).
1237
-
1238
- Returns:
1239
- fpr : array, shape = [n]
1240
- Increasing false positive rates such that element i is the false positive rate
1241
- of predictions with score >= thresholds[i].
1242
- tpr : array, shape = [n]
1243
- Increasing true positive rates such that element i is the true positive rate
1244
- of predictions with score >= thresholds[i].
1245
- thresholds : array, shape = [n]
1246
- Decreasing thresholds on the decision function used to compute fpr and tpr.
1247
- """
1248
-
1249
- y_true = np.asarray(y_true)
1250
- y_score = np.asarray(y_score)
1251
-
1252
- if len(np.unique(y_true)) != 2:
1253
- raise ValueError("Only binary classification is supported.")
1254
-
1255
-
1256
- desc_score_indices = np.argsort(y_score, kind="mergesort")[::-1]
1257
- y_score = y_score[desc_score_indices]
1258
- y_true = y_true[desc_score_indices]
1259
-
1260
-
1261
- fpr = []
1262
- tpr = []
1263
- thresholds = []
1264
- n_pos = np.sum(y_true)
1265
- n_neg = len(y_true) - n_pos
1266
-
1267
- tp = 0
1268
- fp = 0
1269
- prev_score = None
1270
-
1271
-
1272
- for i, score in enumerate(y_score):
1273
- if score != prev_score:
1274
- fpr.append(fp / n_neg)
1275
- tpr.append(tp / n_pos)
1276
- thresholds.append(score)
1277
- prev_score = score
1278
-
1279
- if y_true[i] == 1:
1280
- tp += 1
1281
- else:
1282
- fp += 1
1283
-
1284
- fpr.append(fp / n_neg)
1285
- tpr.append(tp / n_pos)
1286
- thresholds.append(score)
1287
-
1288
- return np.array(fpr), np.array(tpr), np.array(thresholds)
1289
-
1290
- def confusion_matrix(y_true, y_pred, class_count=None):
1291
- """
1292
- Computes confusion matrix.
1293
-
1294
- Args:
1295
- y_true (numpy.ndarray): True class labels (1D array).
1296
- y_pred (numpy.ndarray): Predicted class labels (1D array).
1297
- class_count (int, optional): Number of classes. If None, inferred from data.
1298
-
1299
- Returns:
1300
- numpy.ndarray: Confusion matrix of shape (num_classes, num_classes).
1301
- """
1302
- if class_count is None:
1303
- class_count = len(np.unique(np.concatenate((y_true, y_pred))))
1304
-
1305
- confusion = np.zeros((class_count, class_count), dtype=int)
1306
-
1307
- for i in range(len(y_true)):
1308
- true_label = y_true[i]
1309
- pred_label = y_pred[i]
1310
-
1311
-
1312
- if 0 <= true_label < class_count and 0 <= pred_label < class_count:
1313
- confusion[true_label, pred_label] += 1
1314
- else:
1315
- print(f"Warning: Ignoring out of range label - True: {true_label}, Predicted: {pred_label}")
1316
-
1317
- return confusion
1318
-
1319
-
1320
- def plot_evaluate(y_test, y_preds, acc_list):
1321
-
1322
- acc = acc_list[len(acc_list) - 1]
1323
- y_true = decode_one_hot(y_test)
1324
-
1325
- y_true = np.array(y_true)
1326
- y_preds = np.array(y_preds)
1327
- Class = np.unique(decode_one_hot(y_test))
1328
-
1329
- precision, recall, f1 = metrics(y_test, y_preds)
1330
-
1331
-
1332
- # Confusion matrix
1333
- cm = confusion_matrix(y_true, y_preds, len(Class))
1334
- # Subplot içinde düzenleme
1335
- fig, axs = plt.subplots(2, 2, figsize=(16, 12))
1336
-
1337
- # Confusion Matrix
1338
- sns.heatmap(cm, annot=True, fmt='d', ax=axs[0, 0])
1339
- axs[0, 0].set_title("Confusion Matrix")
1340
- axs[0, 0].set_xlabel("Predicted Class")
1341
- axs[0, 0].set_ylabel("Actual Class")
1342
-
1343
- if len(Class) == 2:
1344
- fpr, tpr, thresholds = roc_curve(y_true, y_preds)
1345
- # ROC Curve
1346
- roc_auc = np.trapz(tpr, fpr)
1347
- axs[1, 0].plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (area = {roc_auc:.2f})')
1348
- axs[1, 0].plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
1349
- axs[1, 0].set_xlim([0.0, 1.0])
1350
- axs[1, 0].set_ylim([0.0, 1.05])
1351
- axs[1, 0].set_xlabel('False Positive Rate')
1352
- axs[1, 0].set_ylabel('True Positive Rate')
1353
- axs[1, 0].set_title('Receiver Operating Characteristic (ROC) Curve')
1354
- axs[1, 0].legend(loc="lower right")
1355
- axs[1, 0].legend(loc="lower right")
1356
- else:
1357
-
1358
- for i in range(len(Class)):
1359
-
1360
- y_true_copy = np.copy(y_true)
1361
- y_preds_copy = np.copy(y_preds)
1362
-
1363
- y_true_copy[y_true_copy == i] = 0
1364
- y_true_copy[y_true_copy != 0] = 1
1365
-
1366
- y_preds_copy[y_preds_copy == i] = 0
1367
- y_preds_copy[y_preds_copy != 0] = 1
1368
-
1369
-
1370
- fpr, tpr, thresholds = roc_curve(y_true_copy, y_preds_copy)
1371
-
1372
- roc_auc = np.trapz(tpr, fpr)
1373
- axs[1, 0].plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (area = {roc_auc:.2f})')
1374
- axs[1, 0].plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
1375
- axs[1, 0].set_xlim([0.0, 1.0])
1376
- axs[1, 0].set_ylim([0.0, 1.05])
1377
- axs[1, 0].set_xlabel('False Positive Rate')
1378
- axs[1, 0].set_ylabel('True Positive Rate')
1379
- axs[1, 0].set_title('Receiver Operating Characteristic (ROC) Curve')
1380
- axs[1, 0].legend(loc="lower right")
1381
- axs[1, 0].legend(loc="lower right")
1382
-
1383
-
1384
- """
1385
- accuracy_per_class = []
1386
-
1387
- for cls in Class:
1388
- correct = np.sum((y_true == cls) & (y_preds == cls))
1389
- total = np.sum(y_true == cls)
1390
- accuracy_cls = correct / total if total > 0 else 0.0
1391
- accuracy_per_class.append(accuracy_cls)
1392
-
1393
- axs[2, 0].bar(Class, accuracy_per_class, color='b', alpha=0.7)
1394
- axs[2, 0].set_xlabel('Class')
1395
- axs[2, 0].set_ylabel('Accuracy')
1396
- axs[2, 0].set_title('Class-wise Accuracy')
1397
- axs[2, 0].set_xticks(Class)
1398
- axs[2, 0].grid(True)
1399
- """
1400
-
1401
-
1402
-
1403
-
1404
- # Precision, Recall, F1 Score, Accuracy
1405
- metric = ['Precision', 'Recall', 'F1 Score', 'Accuracy']
1406
- values = [precision, recall, f1, acc]
1407
- colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
1408
-
1409
- #
1410
- bars = axs[0, 1].bar(metric, values, color=colors)
1411
-
1412
-
1413
- for bar, value in zip(bars, values):
1414
- axs[0, 1].text(bar.get_x() + bar.get_width() / 2, bar.get_height() - 0.05, f'{value:.2f}',
1415
- ha='center', va='bottom', fontsize=12, color='white', weight='bold')
1416
-
1417
- axs[0, 1].set_ylim(0, 1) # Y eksenini 0 ile 1 arasında sınırla
1418
- axs[0, 1].set_xlabel('Metrics')
1419
- axs[0, 1].set_ylabel('Score')
1420
- axs[0, 1].set_title('Precision, Recall, F1 Score, and Accuracy (Weighted)')
1421
- axs[0, 1].grid(True, axis='y', linestyle='--', alpha=0.7)
1422
-
1423
- # Accuracy
1424
- plt.plot(acc_list, marker='o', linestyle='-',
1425
- color='r', label='Accuracy')
1426
-
1427
-
1428
- plt.axhline(y=1, color='g', linestyle='--', label='Maximum Accuracy')
1429
-
1430
-
1431
- plt.xlabel('Samples')
1432
- plt.ylabel('Accuracy')
1433
- plt.title('Accuracy History')
1434
- plt.legend()
1435
-
1436
-
1437
- plt.tight_layout()
1438
- plt.show()
1439
-
1440
-
1441
- def manuel_balancer(x_train, y_train, target_samples_per_class):
1442
- """
1443
- Generates synthetic examples to balance classes to the specified number of examples per class.
1444
-
1445
- Arguments:
1446
- x_train -- Input dataset (examples) - NumPy array format
1447
- y_train -- Class labels (one-hot encoded) - NumPy array format
1448
- target_samples_per_class -- Desired number of samples per class
1449
-
1450
- Returns:
1451
- x_balanced -- Balanced input dataset (NumPy array format)
1452
- y_balanced -- Balanced class labels (one-hot encoded, NumPy array format)
1453
- """
1454
- start_time = time.time()
1455
- x_train = np.array(x_train)
1456
- y_train = np.array(y_train)
1457
- classes = np.arange(y_train.shape[1])
1458
- class_count = len(classes)
1459
-
1460
- x_balanced = []
1461
- y_balanced = []
1462
-
1463
- for class_label in range(class_count):
1464
- class_indices = np.where(np.argmax(y_train, axis=1) == class_label)[0]
1465
- num_samples = len(class_indices)
1466
-
1467
- if num_samples > target_samples_per_class:
1468
-
1469
- selected_indices = np.random.choice(class_indices, target_samples_per_class, replace=False)
1470
- x_balanced.append(x_train[selected_indices])
1471
- y_balanced.append(y_train[selected_indices])
1472
-
1473
- else:
1474
-
1475
- x_balanced.append(x_train[class_indices])
1476
- y_balanced.append(y_train[class_indices])
1477
-
1478
- if num_samples < target_samples_per_class:
1479
-
1480
- samples_to_add = target_samples_per_class - num_samples
1481
- additional_samples = np.zeros((samples_to_add, x_train.shape[1]))
1482
- additional_labels = np.zeros((samples_to_add, y_train.shape[1]))
1483
-
1484
- for i in range(samples_to_add):
1485
- uni_start_time = time.time()
1486
-
1487
- random_indices = np.random.choice(class_indices, 2, replace=False)
1488
- sample1 = x_train[random_indices[0]]
1489
- sample2 = x_train[random_indices[1]]
1490
-
1491
-
1492
- synthetic_sample = sample1 + (sample2 - sample1) * np.random.rand()
1493
-
1494
- additional_samples[i] = synthetic_sample
1495
- additional_labels[i] = y_train[class_indices[0]]
1496
-
1497
- uni_end_time = time.time()
1498
- calculating_est = round(
1499
- (uni_end_time - uni_start_time) * (samples_to_add - i), 3)
1500
-
1501
- if calculating_est < 60:
1502
- print('\rest......(sec):', calculating_est, '\n', end="")
1503
-
1504
- elif calculating_est > 60 and calculating_est < 3600:
1505
- print('\rest......(min):', calculating_est/60, '\n', end="")
1506
-
1507
- elif calculating_est > 3600:
1508
- print('\rest......(h):', calculating_est/3600, '\n', end="")
1509
-
1510
- print('Augmenting: ', class_label, '/', class_count, '...', i, "/", samples_to_add, "\n", end="")
1511
-
1512
- x_balanced.append(additional_samples)
1513
- y_balanced.append(additional_labels)
1514
-
1515
-
1516
- EndTime = time.time()
1517
-
1518
- calculating_est = round(EndTime - start_time, 2)
1519
-
1520
- print(Fore.GREEN + " \nBalancing Finished with 0 ERROR\n" + Style.RESET_ALL)
1521
-
1522
- if calculating_est < 60:
1523
- print('Total balancing time(sec): ', calculating_est)
1524
-
1525
- elif calculating_est > 60 and calculating_est < 3600:
1526
- print('Total balancing time(min): ', calculating_est/60)
1527
-
1528
- elif calculating_est > 3600:
1529
- print('Total balancing time(h): ', calculating_est/3600)
1530
-
1531
- # Stack the balanced arrays
1532
- x_balanced = np.vstack(x_balanced)
1533
- y_balanced = np.vstack(y_balanced)
1534
-
1535
- return x_balanced, y_balanced
1536
-
1537
- def get_weights():
1538
-
1539
- return 0
1540
-
1541
- def get_df():
1542
-
1543
- return 2
1544
-
1545
- def get_preds():
1546
-
1547
- return 1
1548
-
1549
- def get_acc():
1550
-
1551
- return 2
1552
-
1553
- def get_pot():
1554
-
1555
- return 1