1. 09/12/2023 13:55 TP_Réseaux_de_neurones.ipynb - Colaboratory
https://colab.research.google.com/github/RMoulla/Machine-learning/blob/main/TP_Réseaux_de_neurones.ipynb#scrollTo=XvCU0yrMnbJA&print… 1/6
Safae EL OMARI
Double-cliquez (ou appuyez sur Entrée) pour modifier
Dans ce TP, nous allons entraîner un réseau de neurones from scratch sur le dataset MNIST, qui
contient des images de chiffres manuscrits, pour une tâche de classification.
Le réseau de neurones utilisé est de type feedforward (sans récurrence). Il s'agit de l'architecture
la plus basique pour les réseaux de neurones.
Architecture du réseau de neurones
Le réseau de neurones utilisé est structuré de la manière suivante :
Couche d'Entrée : La couche d'entrée est composée de 784 neurones. Cette taille
correspond au nombre de pixels dans chaque image du dataset MNIST (28x28 pixels).
Chaque neurone de cette couche représente l'intensité d'un pixel de l'image en entrée.
Couche Cachée : Le réseau comprend une seule couche cachée. Dans cet exemple, elle est
composée de 100 neurones. Ce nombre n'est pas fixe et peut être ajusté en fonction des
besoins de complexité du modèle. La couche cachée permet au réseau d'apprendre des
représentations plus profondes et des motifs complexes dans les données.
Couche de Sortie : La couche de sortie contient 10 neurones, correspondant aux 10
classes possibles des chiffres (0 à 9) dans le dataset MNIST. Chaque neurone produit une
sortie qui représente la probabilité que l'image en entrée appartienne à l'une des 10
classes.
Fonction d'activation
La fonction d'activation utilisée dans ce réseau est la fonction sigmoid. Elle est appliquée à
chaque neurone de la couche cachée et de la couche de sortie. Cette fonction transforme les
valeurs d'entrée en une sortie comprise entre 0 et 1, ce qui est utile pour des problèmes de
classification binaire. Dans le cas de MNIST, bien que la classification soit multi-classes, la
fonction sigmoid est toujours applicable pour déterminer la probabilité d'appartenance à chaque
classe.
Propagation avant
Entrainement d'un réseau de neurones sur les données
MNIST
keyboard_arrow_down
2. 09/12/2023 13:55 TP_Réseaux_de_neurones.ipynb - Colaboratory
https://colab.research.google.com/github/RMoulla/Machine-learning/blob/main/TP_Réseaux_de_neurones.ipynb#scrollTo=XvCU0yrMnbJA&print… 2/6
Le processus de propagation avant (feedforward) dans un réseau de neurones est une séquence
d'opérations linéaires et non-linéaires. Pour notre réseau avec une couche cachée, le processus
peut être décrit comme suit :
1. Entrée à la couche cachée :
Chaque neurone dans la couche cachée reçoit une combinaison linéaire des entrées :
où est le vecteur d'entrée (les pixels de l'image), est la
matrice des poids entre la couche d'entrée et la couche cachée, et est le vecteur
de biais de la couche cachée.
2. Activation de la couche cachée :
Ensuite, une fonction d'activation non-linéaire est appliquée à chaque élément du
vecteur résultant. Dans notre cas, nous utilisons la fonction sigmoid, définie par :
Ainsi, l'activation de la couche cachée est donnée par :
3. Entrée à la couche de sortie :
De manière similaire, les neurones de la couche de sortie reçoivent une combinaison
linéaire des activations de la couche cachée : où est la
matrice des poids entre la couche cachée et la couche de sortie, et est le vecteur
de biais de la couche de sortie.
4. Activation de la couche de sortie :
Finalement, la fonction sigmoid est appliquée à la sortie pour obtenir la prédiction
finale du réseau :
Ce processus transforme l'entrée brute (les pixels de l'image) en une prédiction de sortie, qui
dans le cas du dataset MNIST, est la probabilité que l'image corresponde à chacun des 10
chiffres (0 à 9).
Rétropropagation
Le processus de rétropropagation (backpropagation) dans un réseau de neurones est utilisé
pour mettre à jour les poids et biais du réseau en fonction de l'erreur de prédiction. Ce processus
peut être décrit mathématiquement comme suit :
1. Calcul de l'erreur de sortie :
L'erreur de sortie est la différence entre la sortie prédite du réseau et la sortie réelle
(valeur attendue). où est la sortie réelle et est la
sortie prédite par le réseau.
2. Gradient de l'erreur par rapport à la sortie :
h = x +
W
(1)
b
(1)
x W
(1)
b
(1)
σ
σ(z) =
1
1 + e
−z
= σ(h)
a
(1)
o = +
W
(2)
a
(1)
b
(2)
W
(2)
b
(2)
= σ(o)
ypred
= −
δ
(o)
yréel
ypred yréel
ypred
3. 09/12/2023 13:55 TP_Réseaux_de_neurones.ipynb - Colaboratory
https://colab.research.google.com/github/RMoulla/Machine-learning/blob/main/TP_Réseaux_de_neurones.ipynb#scrollTo=XvCU0yrMnbJA&print… 3/6
Le gradient de l'erreur par rapport à la sortie est calculé en prenant en compte la
dérivée de la fonction d'activation (sigmoid dans notre cas). Ce gradient est utilisé
pour mettre à jour les poids de la couche de sortie. où est
la dérivée de la fonction sigmoid.
3. Erreur de la couche cachée :
L'erreur pour chaque neurone de la couche cachée est calculée en propageant l'erreur
de la couche de sortie en arrière à travers les poids. où
est la transposée de la matrice des poids entre la couche cachée et la couche de
sortie.
4. Gradient de l'erreur par eapport à la couche cachée :
De même, le gradient pour la couche cachée est calculé en utilisant la dérivée de la
fonction d'activation.
5. Mise à jour des poids et des biais :
Les poids et biais sont ensuite mis à jour en fonction des gradients calculés, en
utilisant un taux d'apprentissage .
où représente la somme sur tous échantillons.
Ce processus de rétropropagation est répété pour chaque exemple dans l'ensemble
d'entraînement, permettant ainsi au réseau de neurones d'apprendre et d'ajuster ses paramètres
pour minimiser l'erreur de prédiction.
Δo = ⋅ (o)
δ
(o)
σ
′
(o)
σ
′
= Δo ⋅
δ
(h)
W
(2)T
W
(2)T
Δh = ⋅ (h)
δ
(h)
σ
′
α = + α ⋅ ⋅ Δo
W
(2)
W
(2)
a
(1)T
= + α ⋅ ⋅ Δh
W
(1)
W
(1)
x
T
= + α ⋅ ∑ Δo
b
(2)
b
(2)
= + α ⋅ ∑ Δh
b
(1)
b
(1)
∑
4. 09/12/2023 13:55 TP_Réseaux_de_neurones.ipynb - Colaboratory
https://colab.research.google.com/github/RMoulla/Machine-learning/blob/main/TP_Réseaux_de_neurones.ipynb#scrollTo=XvCU0yrMnbJA&print… 4/6
import numpy as np
import torch
from torchvision import datasets, transforms
# Définition des fonctions pour le réseau de neurones
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
def forward_propagate(X, weights, bias):
hidden_layer_input = np.dot(X, weights[0]) + bias[0]
hidden_layer_activation = sigmoid(hidden_layer_input)
output_layer_input = np.dot(hidden_layer_activation, weights[1]) + bias[1]
output = sigmoid(output_layer_input)
return hidden_layer_activation, output
def backward_propagate(X, Y, hidden_layer_activation, output, weights):
########### Compléter le code ##############
output_error = Y - output
output_delta = output_error * sigmoid_derivative(output)
hidden_error = np.dot(output_delta, weights[1].T)
hidden_delta = hidden_error *sigmoid_derivative(hidden_layer_activation)
############################################
return hidden_delta, output_delta
def update_weights(X, hidden_layer_activation, hidden_delta, output_delta, weights, bias,
X = X.reshape(1, -1) # Redimensionner X en une matrice à une ligne
########### Compléter le code ###############
weights[0] += learning_rate * np.dot(X.T, hidden_delta)
weights[1] += learning_rate * np.dot(hidden_layer_activation.T,output_delta)
bias[0] += learning_rate * np.sum(hidden_delta)
bias[1] += learning_rate * np.sum(output_delta)
############################################
return weights, bias
# Chargement et préparation des données MNIST avec PyTorch
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transf
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transf
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=len(train_da
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=len(test_datas
train_images, train_labels = next(iter(train_loader))
test_images, test_labels = next(iter(test_loader))
x_train = train_images.numpy().reshape(-1, 28*28)
y_train = np.eye(10)[train_labels.numpy()]
x_test = test_images.numpy().reshape(-1, 28*28)
y_test = np.eye(10)[test_labels.numpy()]
5. 09/12/2023 13:55 TP_Réseaux_de_neurones.ipynb - Colaboratory
https://colab.research.google.com/github/RMoulla/Machine-learning/blob/main/TP_Réseaux_de_neurones.ipynb#scrollTo=XvCU0yrMnbJA&print… 5/6
# Paramètres du réseau
input_size = 784 # Images de 28x28 pixels
hidden_size = 100 # Taille de la couche cachée
output_size = 10 # 10 classes pour MNIST (0 à 9)
learning_rate = 0.1
epochs = 10
# Initialisation des poids et des biais
weights = [
np.random.randn(input_size, hidden_size) * np.sqrt(1. / input_size),
np.random.randn(hidden_size, output_size) * np.sqrt(1. / hidden_size)
]
bias = [np.zeros((1, hidden_size)), np.zeros((1, output_size))]
# Boucle d'entraînement
for epoch in range(epochs):
for i in range(len(x_train)):
X = x_train[i]
Y = y_train[i]
hidden_layer_activation, output = forward_propagate(X, weights, bias)
hidden_delta, output_delta = backward_propagate(X, Y, hidden_layer_activation, ou
weights, bias = update_weights(X, hidden_layer_activation, hidden_delta, output_d
print(f'Epoch {epoch+1}/{epochs} completed')
# Test du modèle (évaluation sommaire)
loss = 0
correct = 0
for i in range(len(x_test)):
_, output = forward_propagate(x_test[i], weights, bias)
loss += np.sum((y_test[i] - output) ** 2)
correct += int(np.argmax(output) == np.argmax(y_test[i]))
loss /= len(x_test)
accuracy = correct / len(x_test)
print(f'Test Loss: {loss:.4f}')
print(f'Test Accuracy: {accuracy:.4f}')
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to ./data/MNI
100%|██████████| 9912422/9912422 [00:00<00:00, 20220262.74it/s]
Extracting ./data/MNIST/raw/train-images-idx3-ubyte.gz to ./data/MNIST/raw
Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to ./data/MNI
100%|██████████| 28881/28881 [00:00<00:00, 67598043.43it/s]
Extracting ./data/MNIST/raw/train-labels-idx1-ubyte.gz to ./data/MNIST/raw
Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to ./data/MNIS
100%|██████████| 1648877/1648877 [00:00<00:00, 28161230.86it/s]
Extracting ./data/MNIST/raw/t10k-images-idx3-ubyte.gz to ./data/MNIST/raw