First commit
This commit is contained in:
commit
8e99dae59d
43
datasettransform.py
Normal file
43
datasettransform.py
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
# TRANSFORME LES FICHIERS .TXT EN MATRICE 8x512, CE SCRIPT EST UTILISE DANS TRAINDATA.PY
|
||||||
|
|
||||||
|
import torch
|
||||||
|
from torch.utils.data import DataLoader, TensorDataset
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
|
||||||
|
train_batch_size = 16
|
||||||
|
data_dir = "C:/DATA/M1/Stages/Fablab/Dataset"
|
||||||
|
|
||||||
|
LST2 = []
|
||||||
|
label = []
|
||||||
|
|
||||||
|
for ID, sub_dir in enumerate(os.listdir(data_dir)):
|
||||||
|
for file in os.listdir(os.path.join(data_dir, sub_dir)):
|
||||||
|
label.append(ID)
|
||||||
|
|
||||||
|
f = open(os.path.join(data_dir, sub_dir, file), 'r+')
|
||||||
|
lst_f = []
|
||||||
|
|
||||||
|
for i in f:
|
||||||
|
i = i.replace('\n', '')
|
||||||
|
lst_f.append(int(i))
|
||||||
|
|
||||||
|
# matrice = np.array(lst_f).reshape(8, 512)
|
||||||
|
# LST_2D.append(matrice)
|
||||||
|
|
||||||
|
matrice = np.array(lst_f[:4096]).reshape(8, 512)
|
||||||
|
LST2.append(matrice)
|
||||||
|
|
||||||
|
# X devient (nombre de fichiers, channel, listes, données), avec 1 pour le canal d'entrée requis par EEGNet
|
||||||
|
X = torch.Tensor(np.array(LST2)).unsqueeze(1)
|
||||||
|
Y = torch.LongTensor(label)
|
||||||
|
|
||||||
|
# créer le DataLoader
|
||||||
|
dataset = TensorDataset(X, Y)
|
||||||
|
data_loader = DataLoader(dataset, batch_size=train_batch_size, shuffle=True)
|
||||||
|
|
||||||
|
print(f' Longueur de la liste: {len(LST2)}')
|
||||||
|
print(f' Nombre de fichiers: {len(label)}')
|
||||||
|
print(f' Forme de la liste des tensor: {X.shape}')
|
||||||
|
print("train batch size:",data_loader.batch_size,
|
||||||
|
", num of batch:", len(data_loader))
|
||||||
3
graph.py
Normal file
3
graph.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
from traindata import loss_train_hist, acc_train_hist, loss_val_hist = []
|
||||||
|
acc_val_hist = []
|
||||||
|
|
||||||
124
inspi.py
Normal file
124
inspi.py
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
# CONTIENT UNE VERSION DU MODELE ET UN DATASET PERSONNALISE,
|
||||||
|
# JE PEUX M'EN INSPIRER POUR NETTOYER DATASETTRANSFORM.PY ET LIRE LES FICHIERS
|
||||||
|
|
||||||
|
import torch
|
||||||
|
import torch.nn as nn
|
||||||
|
import torch.optim as optim
|
||||||
|
from torch.utils.data import DataLoader
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from torchmetrics import Accuracy
|
||||||
|
import os
|
||||||
|
|
||||||
|
# --- Paramètres globaux ---
|
||||||
|
BATCH_SIZE = 8
|
||||||
|
EPOCHS = 50
|
||||||
|
fs = 173
|
||||||
|
channel = 1
|
||||||
|
num_input = 1
|
||||||
|
num_class = 5
|
||||||
|
signal_length = 4097
|
||||||
|
device = 'cpu'
|
||||||
|
|
||||||
|
# --- Architecture EEGNet (inchangée) ---
|
||||||
|
F1, D = 8, 3
|
||||||
|
F2 = D * F1
|
||||||
|
|
||||||
|
class EEGNet(nn.Module):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.conv2d = nn.Conv2d(num_input, F1, (1, round(fs/2)), padding=(0, round(fs/4)-1))
|
||||||
|
self.Batch_normalization_1 = nn.BatchNorm2d(F1)
|
||||||
|
self.Depthwise_conv2D = nn.Conv2d(F1, D*F1, (channel, 1), groups=F1)
|
||||||
|
self.Batch_normalization_2 = nn.BatchNorm2d(D*F1)
|
||||||
|
self.Elu = nn.ELU()
|
||||||
|
self.Average_pooling2D_1 = nn.AvgPool2d((1, 4))
|
||||||
|
self.Dropout = nn.Dropout2d(0.2)
|
||||||
|
self.Separable_conv2D_depth = nn.Conv2d(D*F1, D*F1, (1, round(fs/8)), padding=(0, round(fs/16)), groups=D*F1)
|
||||||
|
self.Separable_conv2D_point = nn.Conv2d(D*F1, F2, (1, 1))
|
||||||
|
self.Batch_normalization_3 = nn.BatchNorm2d(F2)
|
||||||
|
self.Average_pooling2D_2 = nn.AvgPool2d((1, 8))
|
||||||
|
self.Flatten = nn.Flatten()
|
||||||
|
# Calcul dynamique de la taille de sortie pour la couche Dense
|
||||||
|
self.Dense = nn.Linear(F2 * (signal_length // 32), num_class)
|
||||||
|
self.Softmax = nn.Softmax(dim=1)
|
||||||
|
|
||||||
|
def forward(self, x):
|
||||||
|
y = self.Batch_normalization_1(self.conv2d(x))
|
||||||
|
y = self.Batch_normalization_2(self.Depthwise_conv2D(y))
|
||||||
|
y = self.Elu(y)
|
||||||
|
y = self.Dropout(self.Average_pooling2D_1(y))
|
||||||
|
y = self.Separable_conv2D_depth(y)
|
||||||
|
y = self.Batch_normalization_3(self.Separable_conv2D_point(y))
|
||||||
|
y = self.Elu(y)
|
||||||
|
y = self.Dropout(self.Average_pooling2D_2(y))
|
||||||
|
y = self.Flatten(y)
|
||||||
|
return self.Softmax(self.Dense(y))
|
||||||
|
|
||||||
|
# --- Dataset adapté à ton architecture de dossiers ---
|
||||||
|
class EEGDataset(torch.utils.data.Dataset):
|
||||||
|
def __init__(self, root_path, signal_length=4097):
|
||||||
|
self.root_path = root_path
|
||||||
|
self.signal_length = signal_length
|
||||||
|
self.class_map = {'F': 0, 'N': 1, 'O': 2, 'S': 3, 'Z': 4}
|
||||||
|
self.samples = []
|
||||||
|
|
||||||
|
# Parcourt récursivement root_path (ex: data/train/) pour trouver les .txt dans F, N, O, S, Z
|
||||||
|
for class_name in self.class_map.keys():
|
||||||
|
class_folder = os.path.join(root_path, class_name)
|
||||||
|
if os.path.exists(class_folder):
|
||||||
|
for f in os.listdir(class_folder):
|
||||||
|
if f.lower().endswith('.txt'):
|
||||||
|
self.samples.append((os.path.join(class_folder, f), self.class_map[class_name]))
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.samples)
|
||||||
|
|
||||||
|
def __getitem__(self, idx):
|
||||||
|
file_path, label = self.samples[idx]
|
||||||
|
signal = []
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if line and not line.startswith('['):
|
||||||
|
try:
|
||||||
|
signal.append(float(line))
|
||||||
|
except ValueError: continue
|
||||||
|
|
||||||
|
# Padding ou troncature pour assurer signal_length
|
||||||
|
if len(signal) < self.signal_length:
|
||||||
|
signal.extend([0.0] * (self.signal_length - len(signal)))
|
||||||
|
else:
|
||||||
|
signal = signal[:self.signal_length]
|
||||||
|
|
||||||
|
x = torch.tensor(signal, dtype=torch.float32).view(1, 1, -1)
|
||||||
|
return x, torch.tensor(label, dtype=torch.long)
|
||||||
|
|
||||||
|
# --- Initialisation des données ---
|
||||||
|
data_root = "C:/DATA/M1/Stages/Fablab/data"
|
||||||
|
train_loader = DataLoader(EEGDataset(os.path.join(data_root, 'train')),
|
||||||
|
batch_size=BATCH_SIZE,
|
||||||
|
shuffle=True)
|
||||||
|
val_loader = DataLoader(EEGDataset(os.path.join(data_root, 'val')),
|
||||||
|
batch_size=BATCH_SIZE,
|
||||||
|
shuffle=False)
|
||||||
|
test_loader = DataLoader(EEGDataset(os.path.join(data_root, 'test')),
|
||||||
|
batch_size=BATCH_SIZE,
|
||||||
|
shuffle=False)
|
||||||
|
|
||||||
|
# --- Fonction de Visualisation ---
|
||||||
|
def plot_eeg_samples(loader, n_samples=3):
|
||||||
|
samples, labels = next(iter(loader))
|
||||||
|
classes_names = {0: 'F', 1: 'N', 2: 'O', 3: 'S', 4: 'Z'}
|
||||||
|
|
||||||
|
plt.figure(figsize=(12, 8))
|
||||||
|
for i in range(min(n_samples, len(samples))):
|
||||||
|
plt.subplot(n_samples, 1, i+1)
|
||||||
|
plt.plot(samples[i].view(-1).numpy())
|
||||||
|
plt.title(f"Classe: {classes_names[labels[i].item()]}")
|
||||||
|
plt.ylabel("Amplitude")
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
# Test de visualisation
|
||||||
|
plot_eeg_samples(train_loader)
|
||||||
99
model.py
Normal file
99
model.py
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
# ARCHITECTURE DU MODELE EEGNET
|
||||||
|
|
||||||
|
import torch
|
||||||
|
import torchvision
|
||||||
|
import torch.nn as nn
|
||||||
|
import torch.optim as optim
|
||||||
|
from torch.utils.data import DataLoader, TensorDataset
|
||||||
|
from torchmetrics import Accuracy
|
||||||
|
import torch.utils.data as data
|
||||||
|
|
||||||
|
#print(torch.cuda.is_available())
|
||||||
|
# torch.cuda.get_device_name(0)
|
||||||
|
|
||||||
|
# Not Installed:
|
||||||
|
# - Nsight for Visual Studio 2022
|
||||||
|
# Reason: VS2022 was not found
|
||||||
|
# - Nsight for Visual Studio 2026
|
||||||
|
# Reason: VS2026 was not found
|
||||||
|
|
||||||
|
|
||||||
|
### SET MODEL SPECIFICATIONS ###
|
||||||
|
train_batch_size = 8
|
||||||
|
EPOCHS = 50
|
||||||
|
|
||||||
|
fs= 173 #sampling frequency
|
||||||
|
channel= 8 #number of electrode
|
||||||
|
num_input= 1 #number of channel picture (for EEG signal is always : 1)
|
||||||
|
num_class= 5 #number of classes
|
||||||
|
signal_length = 512 #number of sample in each tarial
|
||||||
|
|
||||||
|
F1= 8 #number of temporal filters
|
||||||
|
D= 3 #depth multiplier (number of spatial filters)
|
||||||
|
F2= D*F1 #number of pointwise filters
|
||||||
|
|
||||||
|
device= 'cpu'
|
||||||
|
kernel_size_1= (1,round(fs/2))
|
||||||
|
kernel_size_2= (channel, 1)
|
||||||
|
kernel_size_3= (1, round(fs/8))
|
||||||
|
kernel_size_4= (1, 1)
|
||||||
|
|
||||||
|
kernel_avgpool_1= (1,4)
|
||||||
|
kernel_avgpool_2= (1,8)
|
||||||
|
dropout_rate= 0
|
||||||
|
|
||||||
|
ks0= int(round((kernel_size_1[0]-1)/2))
|
||||||
|
ks1= int(round((kernel_size_1[1]-1)/2))
|
||||||
|
kernel_padding_1= (ks0, ks1-1)
|
||||||
|
ks0= int(round((kernel_size_3[0]-1)/2))
|
||||||
|
ks1= int(round((kernel_size_3[1]-1)/2))
|
||||||
|
kernel_padding_3= (ks0, ks1)
|
||||||
|
|
||||||
|
|
||||||
|
### DESIGN MODEL ###
|
||||||
|
class EEGNet(nn.Module):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
# layer 1
|
||||||
|
self.conv2d = nn.Conv2d(num_input, F1, kernel_size_1, padding=kernel_padding_1)
|
||||||
|
self.Batch_normalization_1 = nn.BatchNorm2d(F1)
|
||||||
|
# layer 2
|
||||||
|
self.Depthwise_conv2D = nn.Conv2d(F1, D*F1, kernel_size_2, groups= F1)
|
||||||
|
self.Batch_normalization_2 = nn.BatchNorm2d(D*F1)
|
||||||
|
self.elu = nn.ELU()
|
||||||
|
self.Average_pooling2D_1 = nn.AvgPool2d(kernel_avgpool_1)
|
||||||
|
self.Dropout = nn.Dropout2d(dropout_rate)
|
||||||
|
# layer 3
|
||||||
|
self.Separable_conv2D_depth = nn.Conv2d( D*F1, D*F1, kernel_size_3,
|
||||||
|
padding=kernel_padding_3, groups= D*F1)
|
||||||
|
self.Separable_conv2D_point = nn.Conv2d(D*F1, F2, kernel_size_4)
|
||||||
|
self.Batch_normalization_3 = nn.BatchNorm2d(F2)
|
||||||
|
self.Average_pooling2D_2 = nn.AvgPool2d(kernel_avgpool_2)
|
||||||
|
# layer 4
|
||||||
|
self.Flatten = nn.Flatten()
|
||||||
|
self.Dense = nn.Linear(
|
||||||
|
F2*round(signal_length/34),
|
||||||
|
# 2880,
|
||||||
|
num_class)
|
||||||
|
self.Softmax = nn.Softmax(dim= 1)
|
||||||
|
|
||||||
|
def forward(self, x):
|
||||||
|
# layer 1
|
||||||
|
y = self.Batch_normalization_1(self.conv2d(x)) #.relu()
|
||||||
|
# layer 2
|
||||||
|
y = self.Batch_normalization_2(self.Depthwise_conv2D(y))
|
||||||
|
y = self.elu(y)
|
||||||
|
y = self.Dropout(self.Average_pooling2D_1(y))
|
||||||
|
# layer 3
|
||||||
|
y = self.Separable_conv2D_depth(y)
|
||||||
|
y = self.Batch_normalization_3(self.Separable_conv2D_point(y))
|
||||||
|
y = self.elu(y)
|
||||||
|
y = self.Dropout(self.Average_pooling2D_2(y))
|
||||||
|
# layer 4
|
||||||
|
y = self.Flatten(y)
|
||||||
|
y = self.Dense(y)
|
||||||
|
y = self.Softmax(y)
|
||||||
|
|
||||||
|
return y
|
||||||
|
|
||||||
|
model001 = EEGNet()
|
||||||
8
split.py
Normal file
8
split.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# PREPARE LES DOSSIERS EN SEPARANT LES DONNEES 4097
|
||||||
|
|
||||||
|
import splitfolders
|
||||||
|
import os
|
||||||
|
|
||||||
|
data_dir = "C:/DATA/M1/Stages/Fablab/Dataset"
|
||||||
|
|
||||||
|
split.ratio(data_dir, output="C:\DATA\M1\Stages\Fablab", seed =123, ratio=(0.8, 0.1, 0.1))
|
||||||
8
splitfoldersclean.py
Normal file
8
splitfoldersclean.py
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# PREPARE LES DOSSIERS EN SEPARANT LES DONNEES 4096
|
||||||
|
|
||||||
|
import splitfolders
|
||||||
|
import os
|
||||||
|
|
||||||
|
data_dir = r"C:/DATA/M1/Stages/Fablab/Dataset"
|
||||||
|
|
||||||
|
splitfolders.ratio(data_dir, output=r"C:/DATA/M1/Stages/Fablab/dataclean", seed =123, ratio=(0.8, 0.1, 0.1))
|
||||||
25
test.py
Normal file
25
test.py
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
from traindata import *
|
||||||
|
from model import *
|
||||||
|
|
||||||
|
# Function to test the model
|
||||||
|
def test():
|
||||||
|
# Load the model that we saved at the end of the training loop
|
||||||
|
model001 = EEGNet()
|
||||||
|
data_dir = "C:/DATA/M1/Stages/Fablab/dataclean"
|
||||||
|
|
||||||
|
# path = "NetModel.pth"
|
||||||
|
model001.load_state_dict(torch.load(data_dir))
|
||||||
|
|
||||||
|
running_accuracy = 0
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
with torch.no_grad():
|
||||||
|
for data in test_loader:
|
||||||
|
inputs, outputs = data
|
||||||
|
outputs = outputs.to(torch.float32)
|
||||||
|
predicted_outputs = model(inputs)
|
||||||
|
_, predicted = torch.max(predicted_outputs, 1)
|
||||||
|
total += outputs.size(0)
|
||||||
|
running_accuracy += (predicted == outputs).sum().item()
|
||||||
|
|
||||||
|
print('Accuracy of the model based on the test set of', test_split ,'inputs is: %d %%' % (100 * running_accuracy / total))
|
||||||
147
traindata.py
Normal file
147
traindata.py
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
### COPIE-COLLE DE TRAINDATA.PY SI LE CODE NE FONCTIONNE PAS
|
||||||
|
|
||||||
|
# LANCER L'ENTRAINEMENT, CALCULE LA LOSS ET L'ACC ET AFFICHE LES GRAPHIQUES ASSOCIES
|
||||||
|
|
||||||
|
from datasettransform import *
|
||||||
|
from model import *
|
||||||
|
|
||||||
|
from torchmetrics import Accuracy
|
||||||
|
import torch.nn as nn
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import torch.optim as optim
|
||||||
|
import pandas as pd
|
||||||
|
import os
|
||||||
|
|
||||||
|
device= 'cpu'
|
||||||
|
|
||||||
|
|
||||||
|
### TRAIN FUNCTION ###
|
||||||
|
def train_one_epoch(model, train_loader, loss_fn, optimizer):
|
||||||
|
model.train()
|
||||||
|
loss_train = AverageMeter()
|
||||||
|
acc_train = Accuracy(task="multiclass", num_classes= num_class).to(device)
|
||||||
|
|
||||||
|
for i, (inputs, targets) in enumerate(train_loader):
|
||||||
|
inputs = inputs.to(device)
|
||||||
|
targets = targets.to(device)
|
||||||
|
|
||||||
|
outputs = model(inputs)
|
||||||
|
loss = loss_fn(outputs, targets)
|
||||||
|
|
||||||
|
loss.backward()
|
||||||
|
nn.utils.clip_grad_norm_(model.parameters(), 1)
|
||||||
|
optimizer.step()
|
||||||
|
optimizer.zero_grad()
|
||||||
|
|
||||||
|
loss_train.update(loss.item())
|
||||||
|
acc_train(outputs, targets.int())
|
||||||
|
|
||||||
|
return model, loss_train.avg, acc_train.compute().item()
|
||||||
|
|
||||||
|
def validation(model, val_loader, loss_fn):
|
||||||
|
model.eval()
|
||||||
|
loss_val = AverageMeter()
|
||||||
|
acc_val = Accuracy(task="multiclass", num_classes= num_class).to(device)
|
||||||
|
|
||||||
|
for i, (inputs, targets) in enumerate(val_loader):
|
||||||
|
inputs = inputs.to(device)
|
||||||
|
targets = targets.to(device)
|
||||||
|
|
||||||
|
outputs = model(inputs)
|
||||||
|
loss = loss_fn(outputs, targets)
|
||||||
|
|
||||||
|
nn.utils.clip_grad_norm_(model.parameters(), 1)
|
||||||
|
|
||||||
|
loss_val.update(loss.item())
|
||||||
|
acc_val(outputs, targets.int())
|
||||||
|
|
||||||
|
return model, loss_val.avg, acc_val.compute().item()
|
||||||
|
|
||||||
|
# rajouter def test ici ?
|
||||||
|
|
||||||
|
|
||||||
|
### UTILS ###
|
||||||
|
class AverageMeter(object):
|
||||||
|
"""Computes and stores the average and current value"""
|
||||||
|
def __init__(self):
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.val = 0
|
||||||
|
self.avg = 0
|
||||||
|
self.sum = 0
|
||||||
|
self.count = 0
|
||||||
|
|
||||||
|
def update(self, val, n=1):
|
||||||
|
self.val = val
|
||||||
|
self.sum += val * n
|
||||||
|
self.count += n
|
||||||
|
self.avg = self.sum / self.count
|
||||||
|
|
||||||
|
|
||||||
|
### TRAINING ###
|
||||||
|
loss_fn= nn.CrossEntropyLoss().to(device)
|
||||||
|
optimizer= optim.NAdam(model001.parameters(), lr= 0.01)
|
||||||
|
|
||||||
|
loss_train_hist = []
|
||||||
|
acc_train_hist = []
|
||||||
|
loss_val_hist = []
|
||||||
|
acc_val_hist = []
|
||||||
|
|
||||||
|
for epoch in range(EPOCHS):
|
||||||
|
model, loss_train, acc_train = train_one_epoch(model001,
|
||||||
|
data_loader,
|
||||||
|
loss_fn,
|
||||||
|
optimizer)
|
||||||
|
model, loss_val, acc_val = validation(model001,
|
||||||
|
data_loader,
|
||||||
|
loss_fn)
|
||||||
|
|
||||||
|
loss_train_hist.append(loss_train)
|
||||||
|
acc_train_hist.append(acc_train)
|
||||||
|
loss_val_hist.append(loss_val)
|
||||||
|
acc_val_hist.append(acc_val)
|
||||||
|
|
||||||
|
if (epoch%10== 5)or(epoch%10== 0):
|
||||||
|
print(f'epoch {epoch}:')
|
||||||
|
print(f' train loss= {loss_train:.4}, val loss={loss_val:.4}, train acc= {int(acc_train*100)}%, val acc= {int(acc_val*100)}% \n')
|
||||||
|
|
||||||
|
|
||||||
|
# Sauvegarder des resultats en csv
|
||||||
|
dataframe = pd.DataFrame({"loss_train": loss_train_hist, "acc_train": acc_train_hist, "loss_val": loss_val_hist, "acc_val": acc_val_hist})
|
||||||
|
n = 0
|
||||||
|
dir_export = "./resultats"
|
||||||
|
for file in os.listdir(dir_export):
|
||||||
|
if file.endswith(".csv"):
|
||||||
|
n += 1
|
||||||
|
dataframe.to_csv(f"./resultats/model_perf_{n}.csv", sep = ',', index = False) # export du csv
|
||||||
|
|
||||||
|
### COURBE D'APPRENTISSAGE ###
|
||||||
|
# plt.plot(range(EPOCHS), acc_train_hist, 'b-', label='Train')
|
||||||
|
# plt.xlabel('Epoch')
|
||||||
|
# plt.ylabel('Acc')
|
||||||
|
# plt.grid(True)
|
||||||
|
# plt.legend()
|
||||||
|
# plt.title('Evolution de l entraînement (train)')
|
||||||
|
# plt.show()
|
||||||
|
# # print(len(acc_train_hist))
|
||||||
|
|
||||||
|
# ### COURBES LOSS ###
|
||||||
|
# plt.plot(loss_train_hist, label='Train loss')
|
||||||
|
# plt.plot(loss_val_hist, label='Val loss')
|
||||||
|
# plt.xlabel('Epoch')
|
||||||
|
# plt.ylabel('Loss')
|
||||||
|
# plt.grid(True)
|
||||||
|
# plt.legend()
|
||||||
|
# plt.title('Evolution de la perte (loss)')
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
# ### COURBES ACC ###
|
||||||
|
# plt.plot(acc_train_hist, label='Train acc')
|
||||||
|
# plt.plot(acc_val_hist, label='Val acc')
|
||||||
|
# plt.xlabel('Epoch')
|
||||||
|
# plt.ylabel('Acc')
|
||||||
|
# plt.grid(True)
|
||||||
|
# plt.legend()
|
||||||
|
# plt.title('Evolution de la précision (acc)')
|
||||||
|
# plt.show()
|
||||||
Loading…
Reference in a new issue