Modèle de régression
Objectif
Appprendre la relation linéaire \(y = 2x\).
Architecture
Réseau neuronal à une couche cachée avec un seul neurone.
Fonction de coût
Erreur quadratique moyenne :
\[MSE = \frac{1}{2}(\hat{y} - y)^2\] ### Algorithme
Descente de gradient standard, minimisant l'erreur sur l'ensemble des données à chaque époque.
Propagation avant
\[ \begin{align*} \alpha &= v \cdot x \\ b &= \sigma(\alpha) \\ \beta &= w \cdot b \\ \hat{y} &= \beta \\ E &= \frac{1}{2}(\hat{y} - y)^2 \end{align*} \] ### Rétropropagation
Mise à jour des paramètres :
\[ \begin{align*} \Delta w &= -\eta \cdot (\hat{y} - y) \cdot b \\ \Delta v &= -\eta \cdot (\hat{y} - y) \cdot w \cdot \sigma'(\alpha) \cdot x \\ \sigma'(\alpha) &= \sigma(\alpha) \cdot (1 - \sigma(\alpha)) \end{align*} \] ### Implémentation en C++
#include <iostream>
#include <cmath>
class Reseau {
private:
double tauxApprentissage;
double poidsV = 0.5, poidsW = 0.5;
double activation(double x) {
return 1.0 / (1.0 + exp(-x));
}
public:
Reseau(double eta) : tauxApprentissage(eta) {}
double prediction(double entree) {
double signalCache = poidsV * entree;
double activationCachee = activation(signalCache);
return poidsW * activationCachee;
}
void miseAJour(double entree, double prediction, double etiquette) {
double signalCache = poidsV * entree;
double derivee = activation(signalCache) * (1 - activation(signalCache));
double delta = prediction - etiquette;
poidsW -= tauxApprentissage * delta * activation(signalCache);
poidsV -= tauxApprentissage * delta * poidsW * derivee * entree;
}
};
int main() {
Reseau modele(0.01);
std::cout << "Prédiction initiale (x=3): " << modele.prediction(3) << std::endl;
for (int epoch = 0; epoch < 500; epoch++) {
double erreur = 0.0;
for (int i = 0; i < 10; i++) {
double pred = modele.prediction(i);
double cible = 2 * i;
erreur += 0.5 * pow(pred - cible, 2);
modele.miseAJour(i, pred, cible);
}
std::cout << "Époque " << epoch << ": Erreur = " << erreur/10 << std::endl;
}
std::cout << "Prédiction finale (x=3): " << modele.prediction(3) << std::endl;
return 0;
}
Implémentation PyTorch
import torch
import torch.nn as nn
class ModeleSimple(nn.Module):
def __init__(self):
super(ModeleSimple, self).__init__()
self.couche = nn.Linear(1, 1)
self.activation = nn.Sigmoid()
def forward(self, x):
return self.activation(self.couche(x))
entrees = torch.tensor([[i] for i in range(10)], dtype=torch.float32)
cibles = torch.tensor([[2*i] for i in range(10)], dtype=torch.float32)
modele = ModeleSimple()
optimiseur = torch.optim.SGD(modele.parameters(), lr=0.01)
fonction_perte = nn.MSELoss()
for epoch in range(500):
optimiseur.zero_grad()
predictions = modele(entrees)
perte = fonction_perte(predictions, cibles)
perte.backward()
optimiseur.step()
Modèle de classification
Architecture
Réseau à deux entrées et deux neurones de sortie pour classification binaire.
Fonction de coût
Entropie croisée :
\[ H(y, \hat{y}) = -\sum_{i=1}^{2} y_i \log(\hat{y}_i) \] ### Propagation avant
\[ \begin{align*} a_j &= \sum_{i} w_{ij} x_i \\ b_j &= \sigma(a_j) \\ \hat{y}_k &= \frac{e^{b_k}}{\sum_{m} e^{b_m}} \end{align*} \] ### Rétropropagation
Dérivées des poids :
\[ \frac{\partial H}{\partial w_{ij}} = (\hat{y}_j - y_j) \cdot \sigma'(a_j) \cdot x_i \] ### Implémentation Python
import numpy as np
class Classifieur:
def __init__(self):
self.poids = np.array([[0.5, 0.5], [0.5, 0.5]])
self.taux = 0.5
def sigmoide(self, z):
return 1 / (1 + np.exp(-z))
def propagation(self, x):
a = self.poids.T.dot(x)
b = self.sigmoide(a)
exp_b = np.exp(b)
return exp_b / np.sum(exp_b)
def entrainement(self, x, y):
a = self.poids.T.dot(x)
b = self.sigmoide(a)
exp_b = np.exp(b)
predictions = exp_b / np.sum(exp_b)
gradient = np.outer(x, (predictions - y) * b * (1 - b))
self.poids -= self.taux * gradient