PyTorch est un framework de deep learning très répandu : il permet de définir un réseau de neurones, de l'entraîner sur CPU (le processeur) ou sur GPU (la carte graphique), et de lui faire apprendre des motifs complexes en quelques lignes. Cette leçon, facultative, construit un réseau qui apprend une frontière non linéaire, l'entraîne sur CPU en une fraction de seconde, puis montre ce qu'il a appris.
Vous verrez comment définir un réseau avec torch.nn, la boucle
d'entraînement (passe avant, perte, rétropropagation, optimiseur), et pourquoi
un réseau réussit là où un modèle linéaire échoue. Elle prolonge la leçon
Deep learning. Tous les chiffres
viennent d'une exécution sur CPU avec PyTorch 2.14.1 ; la variante GPU est
présentée comme option, sans mesure.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Installer PyTorch 2.14.1 pour CPU dans un environnement isolé.
- Définir un réseau de neurones avec
torch.nn. - Écrire une boucle d'entraînement complète.
- Choisir le calcul sur CPU ou GPU avec
.to(device). - Lire la frontière de décision apprise par le réseau.
Quels sont les prérequis ?
Section intitulée « Quels sont les prérequis ? »Il faut savoir écrire un script Python (fonctions, boucles, modules) et lancer un environnement virtuel, comme dans la formation Python : les fondamentaux. Les notions de réseau de neurones, de perte et de rétropropagation viennent de la leçon Deep learning, et la comparaison avec un modèle linéaire de la leçon Régression linéaire. Aucune carte graphique n'est nécessaire.
Qu'est-ce que PyTorch ?
Section intitulée « Qu'est-ce que PyTorch ? »PyTorch est une bibliothèque Python qui manipule des tenseurs (des tableaux multidimensionnels) avec accélération GPU et différentiation automatique. Ces deux briques sont le coeur du deep learning : les tenseurs portent les données et les poids, l'autograd calcule automatiquement les gradients (de combien et dans quel sens modifier chaque poids) nécessaires à la rétropropagation.
Concrètement, vous décrivez le réseau et la perte à minimiser, et PyTorch se charge de calculer comment ajuster chaque poids. C'est ce qui rend possible l'entraînement de réseaux à des millions de paramètres.
Comment installer PyTorch sur CPU ?
Section intitulée « Comment installer PyTorch sur CPU ? »Pour une machine sans carte graphique, on installe la variante CPU de PyTorch
dans un environnement virtuel dédié. PyTorch est un paquet volumineux : un
venv Python le garde à l'écart de l'environnement conda data de la
formation, qui reste réservé à scikit-learn et à Jupyter. Les trois bibliothèques
sont épinglées aux versions utilisées pour cette leçon :
python3 -m venv venv && source venv/bin/activatepip install torch==2.14.1 --index-url https://download.pytorch.org/whl/cpupip install numpy==2.5.4 matplotlib==3.11.2L'option --index-url désigne l'index de paquets de PyTorch pour le CPU, à la
place de PyPI. Vérifiez l'installation et l'absence de GPU :
import torchprint(torch.__version__)print(torch.cuda.is_available())2.14.1+cpuFalseLe suffixe +cpu confirme la variante installée, et False signifie
qu'aucun GPU n'est disponible : le code de la leçon choisira donc le CPU
tout seul.
Comment exécuter les blocs de code de cette leçon ?
Section intitulée « Comment exécuter les blocs de code de cette leçon ? »Enregistrez les blocs Python des sections suivantes, dans l'ordre, dans un
seul fichier lunes.py, puis lancez python lunes.py dans le venv activé.
Chaque bloc réutilise les variables du précédent (model, Xtr, device), et
le dernier trace la figure. Deux autres façons de faire échouent, toutes deux
mesurées pour cette leçon :
- le notebook de l'environnement
datane convient pas, cartorchn'y est pas installé :import torchy lèveModuleNotFoundError: No module named 'torch'; - le collage dans l'interpréteur interactif ne convient pas non plus : la
boucle
forsuivie d'une instruction en colonne 0, sans ligne vide, lève unSyntaxError.
Le script écrit la figure frontiere.png dans le dossier courant.
Préparer des données non linéaires
Section intitulée « Préparer des données non linéaires »Pour montrer l'intérêt d'un réseau de neurones, on utilise un jeu de données qu'un modèle linéaire (une droite de séparation, comme dans la leçon Régression linéaire) ne peut pas séparer : deux lunes entrelacées, 800 points pour l'entraînement et 200 pour le test. On les génère avec NumPy, puis on les convertit en tenseurs placés sur le bon device : le GPU s'il existe, sinon le CPU, comme ici.
import torch, time, numpy as npfrom torch import nn
torch.manual_seed(42); np.random.seed(42)device = "cuda" if torch.cuda.is_available() else "cpu"
def make_moons(n=1000, noise=0.15): n2 = n // 2; t = np.linspace(0, np.pi, n2) x1 = np.stack([np.cos(t), np.sin(t)], 1) x2 = np.stack([1 - np.cos(t), 1 - np.sin(t) - 0.5], 1) X = np.vstack([x1, x2]); y = np.array([0] * n2 + [1] * n2) X += noise * np.random.randn(*X.shape) return X.astype("float32"), y.astype("int64")
X, y = make_moons(1000)idx = np.random.permutation(len(X)); tr, te = idx[:800], idx[800:]Xtr = torch.tensor(X[tr]).to(device); ytr = torch.tensor(y[tr]).to(device)Xte = torch.tensor(X[te]).to(device); yte = torch.tensor(y[te]).to(device)Définir le réseau de neurones
Section intitulée « Définir le réseau de neurones »Un réseau se décrit comme un empilement de couches. Ici, deux couches cachées de 16 neurones avec une activation ReLU, et une sortie à deux classes :
model = nn.Sequential( nn.Linear(2, 16), nn.ReLU(), nn.Linear(16, 16), nn.ReLU(), nn.Linear(16, 2),).to(device)
opt = torch.optim.Adam(model.parameters(), lr=0.01)loss_fn = nn.CrossEntropyLoss()nn.Linear est une couche entièrement connectée, nn.ReLU la fonction
d'activation, Adam l'optimiseur qui ajuste les poids, et
CrossEntropyLoss la perte adaptée à la classification.
La boucle d'entraînement
Section intitulée « La boucle d'entraînement »Chaque epoch (ici une passe sur les 800 points d'entraînement à la fois) répète le cycle du schéma : prédire (la passe avant, ou forward), mesurer l'erreur, rétropropager, mettre à jour les poids. Le code ci-dessous l'exécute 200 fois ; ses commentaires nomment l'étape de chaque ligne :
t0 = time.time()for epoch in range(200): model.train() opt.zero_grad() # réinitialiser les gradients loss = loss_fn(model(Xtr), ytr) # forward + perte loss.backward() # rétropropagation opt.step() # mise à jour des poids if (epoch + 1) % 50 == 0: model.eval() with torch.no_grad(): acc = (model(Xte).argmax(1) == yte).float().mean().item() print(f"Epoch {epoch+1} | loss {loss.item():.3f} | accuracy test {acc:.3f}")print(f"Entraînement en {time.time()-t0:.2f}s sur {device}")Ce bloc fait partie du même fichier lunes.py que les précédents (voir plus
haut comment l'exécuter). Sur CPU, l'entraînement complet donne :
Epoch 50 | loss 0.213 | accuracy test 0.900Epoch 100 | loss 0.045 | accuracy test 0.990Epoch 150 | loss 0.023 | accuracy test 0.985Epoch 200 | loss 0.018 | accuracy test 0.985Entraînement en 0.12s sur cpuLe réseau atteint 98,5 % de bonnes réponses (l'exactitude, accuracy en anglais) sur les 200 points de test, en une fraction de seconde sur CPU. La durée varie d'une machine à l'autre ; la perte et l'exactitude se reproduisent grâce aux graines fixées avec la même version de PyTorch sur CPU, mais PyTorch ne garantit pas des résultats identiques entre versions ou plateformes différentes. La perte passe de 0.213 à 0.018 : le réseau apprend.
Visualiser ce que le réseau a appris
Section intitulée « Visualiser ce que le réseau a appris »En colorant chaque zone du plan selon la classe prédite, on voit la
frontière de décision que le réseau a construite. Elle épouse la forme
courbe des deux lunes, ce qu'une droite ne pourrait jamais faire. Le
tracé prédit la classe de chaque point d'une grille de 300 par 300 points, puis
colore les zones avec matplotlib ; c'est le dernier bloc de lunes.py :
# ----- tracé de la frontière appriseimport matplotlib.pyplot as plt
xx, yy = np.meshgrid(np.linspace(-1.5, 2.5, 300), np.linspace(-1.2, 1.7, 300))grille = torch.tensor(np.c_[xx.ravel(), yy.ravel()], dtype=torch.float32).to(device)model.eval()with torch.no_grad(): zz = model(grille).argmax(1).cpu().numpy().reshape(xx.shape)
plt.contourf(xx, yy, zz, levels=[-0.5, 0.5, 1.5], alpha=0.3, cmap="coolwarm")plt.scatter(X[:, 0], X[:, 1], c=y, s=8, cmap="coolwarm")plt.title("Frontière apprise par le réseau")plt.savefig("frontiere.png", dpi=120)print("figure écrite : frontiere.png")Le paramètre levels donne les bornes des zones colorées : les classes
valent 0 et 1, et les bornes -0.5, 0.5 et 1.5 isolent chacune dans sa propre
bande. Sans ces niveaux explicites, matplotlib en choisit d'autres et la
figure est fausse. La sortie attendue est figure écrite : frontiere.png, et l'image
produite ressemble à ceci :

C'est toute la puissance d'un réseau de neurones : grâce à ses couches et à ses fonctions d'activation non linéaires, il modélise des relations que les modèles linéaires ne capturent pas.
Que faire quand le script échoue ?
Section intitulée « Que faire quand le script échoue ? »Les trois erreurs de cette leçon viennent presque toujours de l'endroit où le code s'exécute, pas du code. Le tableau donne le symptôme, sa cause et le geste qui le corrige.
| Symptôme | Cause | Solution |
|---|---|---|
ModuleNotFoundError: No module named 'torch' | L'interpréteur lancé n'est pas celui du venv (par exemple le notebook de l'environnement data) | Activez le venv avec source venv/bin/activate, puis relancez python lunes.py |
SyntaxError: invalid syntax | Les blocs ont été collés dans l'interpréteur : la boucle for suivie d'un print en colonne 0, sans ligne vide, n'est pas acceptée | Enregistrez les blocs dans lunes.py et exécutez le fichier |
ModuleNotFoundError: No module named 'matplotlib' | L'installation de numpy et matplotlib a été sautée | Relancez pip install numpy==2.5.4 matplotlib==3.11.2 dans le venv |
Après correction, la sortie doit afficher les quatre lignes Epoch, la durée,
puis figure écrite : frontiere.png.
À retenir
Section intitulée « À retenir »- PyTorch manipule des tenseurs avec CPU ou GPU et différentiation automatique.
- Un réseau se décrit comme un empilement de couches avec
torch.nn. - La boucle d'entraînement répète : forward, perte,
backward,step. .to(device)rend le code portable entre CPU et GPU sans le changer. Ici, 200 epochs ont pris une fraction de seconde sur CPU, sur la machine de test.- Les couches non linéaires permettent d'apprendre des frontières courbes, hors de portée d'un modèle linéaire.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
FAQ : questions fréquentes
Section intitulée « FAQ : questions fréquentes ».to(device).loss.backward() calcule automatiquement les gradients de la perte par rapport à chaque poids, et opt.step() ajuste les poids pour réduire l'erreur. C'est le coeur de l'apprentissage.