Deep Learning – Master 2 Travaux Pratiques
Travaux Pratiques de Deep Learning
Niveau Master 2
Ces travaux pratiques sont conçus pour un niveau Master 2, avec une exigence élevée sur
les plans théorique, algorithmique et analytique. Les étudiants sont supposés maîtriser Python,
l’algèbre linéaire et les bases du machine learning.
Les TP couvrent exclusivement les notions abordées dans le cours : neurone artificiel, fonc-
tions d’activation, réseaux de neurones, rétropropagation, descente de gradient et gradient sto-
chastique.
TP 1 Analyse avancée d’un neurone artificiel
Objectifs pédagogiques
— Comprendre le modèle mathématique d’un neurone artificiel
— Étudier le rôle du biais et des fonctions d’activation
Formulation mathématique
Un neurone artificiel est défini par :
n
X
z= wi x i + b
i=1
y = f (z)
où xi sont les entrées, wi les poids, b le biais et f (·) la fonction d’activation.
Fonctions d’activation usuelles :
1
fsig (z) = , ftanh (z) = tanh(z), fReLU (z) = max(0, z)
1 + e−z
Travail demandé
1. Implémenter un neurone artificiel en Python (sans framework).
2. Tester différentes fonctions d’activation.
3. Analyser l’impact du biais sur la frontière de décision.
TP 2 Régression logistique et analyse de convergence
Modèle mathématique
ŷ = σ(z), z = wT x + b
1
σ(z) =
1 + e−z
Fonction de perte
L(y, ŷ) = −y log(ŷ) − (1 − y) log(1 − ŷ)
1
Deep Learning – Master 2 Travaux Pratiques
Descente de gradient
∂L ∂L
w := w − η , b := b − η
∂w ∂b
Travail demandé
1. Implémenter la régression logistique à partir de zéro.
2. Étudier l’effet du taux d’apprentissage η.
3. Analyser la convergence.
TP 3 Réseau de neurones multi-couches
Propagation avant
Pour une couche l :
z (l) = W (l) a(l−1) + b(l)
a(l) = f (z (l) )
Rétropropagation
δ (l) = (W (l+1) )T δ (l+1) ⊙ f ′ (z (l) )
Mise à jour
∂L
W (l) := W (l) − η
∂W (l)
Travail demandé
1. Implémenter un MLP avec au moins une couche cachée.
2. Implémenter la rétropropagation du gradient.
3. Étudier la disparition du gradient.
TP 4 Étude des fonctions d’activation
Dérivées
σ ′ (z) = σ(z)(1 − σ(z))
tanh′ (z) = 1 − tanh2 (z)
(
′ 1 z>0
ReLU (z) =
0 z≤0
Travail demandé
Comparer expérimentalement la vitesse de convergence et la stabilité des différentes fonctions.
2
Deep Learning – Master 2 Travaux Pratiques
TP 5 Algorithmes d’optimisation
Gradient classique
θ := θ − η∇J(θ)
Gradient stochastique
θ := θ − η∇Ji (θ)
Mini-batch
1 X
θ := θ − η ∇Ji (θ)
|B|
i∈B
TP 6 Projet intégrateur Master 2
Cadre mathématique
ŷ = f (x; θ), θ := θ − η∇J(θ)
Attendus
— Justification théorique rigoureuse
— Analyse critique des résultats
— Discussion des limites
Dr DIAKO JEROME -Enseignant-Chercheur à
l’ESATIC :[Link]@[Link]
3
Deep Learning – Master 2 Corrigé complet des TP
Corrigé - Travaux Pratiques Deep Learning
Dr DIAKO JEROME
Niveau Master 2
Principe : les solutions ci-dessous sont indicatives. Toute variante correcte (maths + algo +
expérimental) doit être acceptée.
TP 1 – Analyse avancée d’un neurone artificiel
1) Modèle mathématique
Un neurone calcule :
n
X
z= wi xi + b = w⊤ x + b, y = f (z).
i=1
2) Fonctions d’activation (rappel)
1 ez − e−z
Seuil : f (z) = 1z≥0 , σ(z) = , tanh(z) = , ReLU(z) = max(0, z).
1 + e−z ez + e−z
Note enseignant
Points M2 à expliciter : (i) sans activation, composition de transformations linéaires ⇒
modèle linéaire ; (ii) rôle du biais : translation de l’hyperplan de décision ; (iii) saturation
sigmoïde/tanh ⇒ gradients faibles pour |z| grand.
3) Implémentation Python (NumPy)
import numpy as np
def step(z): return (z >= 0).astype(float)
def sigmoid(z): return 1.0 / (1.0 + [Link](-z))
def tanh(z): return [Link](z)
def relu(z): return [Link](0.0, z)
def neuron(x, w, b, activation):
z = float([Link](w, x) + b)
return activation(z), z
# Exemple de test
x = [Link]([1.0, -2.0, 0.5])
w = [Link]([0.2, -0.7, 1.3])
b = -0.1
for act in [step, sigmoid, tanh, relu]:
y, z = neuron(x, w, b, act)
print(act.__name__, "z=", z, "y=", y)
1
Deep Learning – Master 2 Corrigé complet des TP
4) Analyse attendue
Résultat clé
Conclusion typique :
— Le biais b décale la sortie même quand x = 0.
— La ReLU évite la saturation positive mais peut produire des neurones morts si z ≤ 0
trop souvent.
— Sigmoïde/Tanh : utiles en sortie probabiliste / centrage, mais peuvent saturer.
TP 2 – Régression logistique optimisée et analyse de convergence
1) Modèle et loss
ŷ = σ(z), z = w⊤ x + b.
Pour un dataset (xi , yi )N
i=1 avec yi ∈ {0, 1} :
N
1 X
J(w, b) = − yi log ŷi − (1 − yi ) log(1 − ŷi ) .
N
i=1
2) Gradients
En notant ŷ = σ(Xw + b1) :
1 ⊤ ∂J 1
∇w J = X (ŷ − y), = 1⊤ (ŷ − y).
N ∂b N
3) Implémentation from scratch
import numpy as np
def sigmoid(z):
return 1.0 / (1.0 + [Link](-z))
def logloss(y, yhat, eps=1e-12):
yhat = [Link](yhat, eps, 1-eps)
return [Link](-y*[Link](yhat) - (1-y)*[Link](1-yhat))
def fit_logreg(X, y, lr=0.1, epochs=2000):
N, d = [Link]
w = [Link](d)
b = 0.0
history = []
for t in range(epochs):
z = X @ w + b
yhat = sigmoid(z)
# gradients
dw = (X.T @ (yhat - y)) / N
db = [Link](yhat - y)
# update
w -= lr * dw
b -= lr * db
if t % 50 == 0:
2
Deep Learning – Master 2 Corrigé complet des TP
[Link](logloss(y, yhat))
return w, b, history
def predict_proba(X, w, b):
return sigmoid(X @ w + b)
def predict(X, w, b, thr=0.5):
return (predict_proba(X, w, b) >= thr).astype(int)
4) Analyse de convergence (attendue M2)
— La log-loss est convexe en (w, b) (pour données fixées) ⇒ minimum global.
— η trop grand ⇒ oscillations / divergence ; η trop petit ⇒ convergence lente.
— Bonne pratique : suivi de J et éventuellement learning rate schedule.
TP 3 – MLP : propagation avant + rétropropagation
1) Architecture (exemple)
MLP 1 couche cachée :
a(0) = x, z (1) = W (1) a(0) + b(1) , a(1) = f (z (1) ),
z (2) = w(2)⊤ a(1) + b(2) , ŷ = σ(z (2) ).
2) Rétropropagation (binaire, log-loss)
Pour sortie sigmoïde + log-loss, le gradient simplifie :
δ (2) = ŷ − y.
Puis :
∇w(2) = δ (2) a(1) , ∇b(2) = δ (2) .
Pour la couche cachée :
δ (1) = w(2) δ (2) ⊙ f ′ (z (1) ),
∇W (1) = δ (1) a(0)⊤ , ∇b(1) = δ (1) .
3) Implémentation NumPy (mini-MLP binaire)
import numpy as np
def sigmoid(z): return 1.0 / (1.0 + [Link](-z))
def relu(z): return [Link](0.0, z)
def drelu(z): return (z > 0).astype(float)
def logloss(y, yhat, eps=1e-12):
yhat = [Link](yhat, eps, 1-eps)
return [Link](-y*[Link](yhat) - (1-y)*[Link](1-yhat))
class MLPBinary:
def __init__(self, d_in, h, seed=0):
rng = [Link].default_rng(seed)
self.W1 = [Link](0, 0.1, size=(h, d_in))
3
Deep Learning – Master 2 Corrigé complet des TP
self.b1 = [Link](h)
self.w2 = [Link](0, 0.1, size=(h,))
self.b2 = 0.0
def forward(self, X):
Z1 = X @ self.W1.T + self.b1 # (N,h)
A1 = relu(Z1)
Z2 = A1 @ self.w2 + self.b2 # (N,)
Yh = sigmoid(Z2)
cache = (X, Z1, A1, Z2, Yh)
return Yh, cache
def step(self, X, y, lr=0.1):
N = [Link][0]
Yh, (X, Z1, A1, Z2, Yh) = [Link](X)
# delta sortie
d2 = (Yh - y) # (N,)
# grads couche 2
dw2 = (A1.T @ d2) / N # (h,)
db2 = [Link](d2)
# delta couche 1
d1 = (d2[:, None] * self.w2[None, :]) * drelu(Z1) # (N,h)
dW1 = (d1.T @ X) / N # (h,d)
db1 = [Link](d1, axis=0) # (h,)
# update
self.W1 -= lr * dW1
self.b1 -= lr * db1
self.w2 -= lr * dw2
self.b2 -= lr * db2
return logloss(y, Yh)
def fit(self, X, y, lr=0.1, epochs=2000):
hist = []
for t in range(epochs):
L = [Link](X, y, lr=lr)
if t % 50 == 0:
[Link](L)
return hist
4) Analyse : disparition du gradient
— Sigmoïde/tanh : f ′ (z) petit quand |z| grand ⇒ gradients qui s’éteignent en profondeur.
— ReLU : dérivée = 1 si z > 0 (meilleure propagation), mais = 0 si z ≤ 0 (neurones morts
possibles).
TP 4 – Étude activation : théorie + expérimentation
1) Dérivées
(
′ ′ 2 ′ 1 z>0
σ (z) = σ(z)(1 − σ(z)), tanh (z) = 1 − tanh (z), ReLU (z) =
0 z ≤ 0.
4
Deep Learning – Master 2 Corrigé complet des TP
2) Protocole expérimental recommandé
1. Fixer dataset, architecture, initialisation, η, batch-size.
2. Remplacer uniquement l’activation cachée (sigmoïde, tanh, ReLU).
3. Mesurer : courbe J vs itérations, accuracy, stabilité (variance entre seeds).
3) Conclusion typique (attendue)
Résultat clé
Sur réseaux profonds, ReLU (ou variantes) est généralement préférable (convergence plus
rapide). Tanh peut être compétitive en faible profondeur grâce au centrage en 0. Sigmoïde
en couches cachées est souvent défavorable à cause de la saturation.
4) Tableau de synthèse (exemple)
Activation Convergence Risque Usage conseillé
Sigmoïde lente saturation sortie binaire
Tanh moyenne saturation modérée cachée peu profonde
ReLU rapide neurones morts cachée profonde
TP 5 – GD vs SGD vs Mini-batch
1) Formules
1 PN
Pour un objectif J(θ) = N i=1 Ji (θ) :
GD : θ ← θ − η∇J(θ),
SGD : θ ← θ − η∇Ji (θ),
1 X
Mini-batch : θ ← θ − η ∇Ji (θ).
|B|
i∈B
2) Implémentation générique (sur logreg)
def fit_logreg_sgd(X, y, lr=0.1, epochs=10, batch_size=1, seed=0):
rng = [Link].default_rng(seed)
N, d = [Link]
w = [Link](d); b = 0.0
for ep in range(epochs):
idx = [Link](N)
for start in range(0, N, batch_size):
batch = idx[start:start+batch_size]
Xb, yb = X[batch], y[batch]
yhat = sigmoid(Xb @ w + b)
dw = (Xb.T @ (yhat - yb)) / len(yb)
db = [Link](yhat - yb)
w -= lr * dw
b -= lr * db
return w, b
5
Deep Learning – Master 2 Corrigé complet des TP
3) Analyse attendue
— GD : gradient exact, stable, mais coûteux sur grands N .
— SGD : mises à jour fréquentes, rapide, mais trajectoire bruitée.
— Mini-batch : compromis pratique (GPU-friendly).
— Le bruit du SGD peut aider à sortir de certains minima/selles (régularisation implicite).
TP 6 – Projet intégrateur (solution-type / canevas M2)
1) Structure minimale d’un projet M2
1. Problème : définition claire (classification/régression), métriques, hypothèses.
2. Modèle : ŷ = f (x; θ), architecture (MLP), choix activations.
3. Loss : J(θ) (log-loss / MSE).
4. Optimisation : GD/SGD/mini-batch, choix η, critères d’arrêt.
5. Évaluation : train/val/test, courbes de loss, overfitting, ablations.
6. Discussion : limites, biais, généralisations, perspectives.
2) Exemple de formulation
N
1 X
θ⋆ ∈ argminθ J(θ) =
ℓ yi , f (xi ; θ) , θ ← θ − η∇J(θ).
N
i=1
Note enseignant
Attendu M2 : ablations (activation, profondeur, batch-size), analyse des échecs, inter-
prétation des gradients et discussion sur la généralisation.