Skip to content
The loss curve

Chapitre 5 · 16 min

Un neurone qui apprend

Construis un neurone entraînable, dérive son gradient et ajoute la première étape d’apprentissage à ton code local.

Nous avons maintenant des , des et une mesure de similarité. Il nous manque encore quelque chose qui apprend. Le du chapitre 1 était entraîné par comptage ; ce n’est pas vraiment apprendre, c’est tenir une comptabilité. Pour aller plus loin, il faut une fonction dont les changent en réponse à ses erreurs.

Un est la plus petite fonction de ce genre. Il prend un vecteur, le pondère, somme, ajoute un biais, puis passe par une non-linéarité :

output=σ ⁣(iwixi+b)\text{output} = \sigma\!\left(\sum_i w_i x_i + b\right)

Cette ligne est l’histoire entière des réseaux feed-forward. Plusieurs en parallèle donnent une couche ; plusieurs couches donnent un réseau profond. Commençons par un seul.

1. La passe avant

Écris la fonction qui prend x = [x_0, x_1], des w = [w_0, w_1], un biais b, et retourne la sortie du . La est fournie.

Code · JavaScript

Les barres montrent la sortie du pour plusieurs entrées. Avec w = [1, 0.5] et b = 0, les points où w · x + b est positif doivent produire une sortie > 0.5. Le est juste une somme pondérée suivie d’un écrasement ; le reste du chapitre sert à ajuster w et b automatiquement.

2. La fonction de loss

Avec la sortie p du et la vraie étiquette y (0 ou 1), il nous faut un nombre qui dit “à quel point cette prédiction était mauvaise”. Le choix standard est la binary :

L=[ylogp+(1y)log(1p)]L = -\bigl[y \log p + (1 - y)\log(1 - p)\bigr]

Elle est proche de zéro quand p correspond à y, et grande quand le modèle est confiant dans le mauvais sens. Ajoute un petit epsilon avant les logs pour éviter log(0).

Code · JavaScript

Les barres montrent la pour plusieurs couples (prédiction, étiquette). Quand ça correspond, la est petite ; quand ça diverge, surtout avec confiance, elle explose.

3. Le gradient

La composition + binary a une propriété magnifique : le de la par rapport à (w · x + b) vaut simplement p - y. Autrement dit, l’erreur elle-même est le . Ensuite :

Lwi=(py)xi,Lb=(py)\frac{\partial L}{\partial w_i} = (p - y)\,x_i, \qquad \frac{\partial L}{\partial b} = (p - y)

Écris la fonction de . Le chapitre compare ta sortie à une référence.

Code · JavaScript

Si la comparaison affiche ✓, ton correspond à la forme fermée. C’est le petit lemme qui rend la régression logistique et les réseaux neuronaux pratiques.

4. Entraîner le neurone

On assemble tout. Utilise un dataset de deux clusters en 2D, itère la et regarde la frontière de décision se placer.

Code · JavaScript

Le scatter à gauche montre les données ; la ligne orange est la frontière w · x + b = 0, où la sortie du vaut 0.5. Après , la ligne doit passer entre les deux clusters. La courbe à droite est la au fil du temps : elle doit descendre puis se stabiliser.

5. Ajouter le premier pas d’apprentissage localement

Crée llm/nn.py :

"""Small neural-network pieces before the PyTorch rewrite."""
from __future__ import annotations
 
import math
 
 
# [1]
def sigmoid(x: float) -> float:
    return 1.0 / (1.0 + math.exp(-x))
 
 
# [2]
def neuron(x: list[float], w: list[float], b: float) -> float:
    return sigmoid(sum(xi * wi for xi, wi in zip(x, w)) + b)
 
 
# [3]
def bce(pred: float, target: float) -> float:
    eps = 1e-12
    pred = min(max(pred, eps), 1.0 - eps)
    return -(target * math.log(pred) + (1.0 - target) * math.log(1.0 - pred))
 
 
def neuron_step(
    x: list[float],
    target: float,
    w: list[float],
    b: float,
    lr: float,
) -> tuple[list[float], float, float]:
    pred = neuron(x, w, b)
    # [4]
    error = pred - target
    # [5]
    next_w = [wi - lr * error * xi for wi, xi in zip(w, x)]
    next_b = b - lr * error
    return next_w, next_b, bce(pred, target)

Lis le pas comme une boucle d’ minuscule :

  • [1] sigmoid ramène tout score entre 0 et 1.
  • [2] neuron calcule somme pondérée + biais, puis une sortie de type probabilité.
  • [3] bce punit fort les mauvaises réponses confiantes.
  • [4] error = pred - target est la simplification clé.
  • [5] met à jour et biais contre cette erreur.

C’est le premier fichier de ton projet qui modifie des à cause d’une erreur. Cette idée monte jusqu’au chapitre 13.

Ce que le neurone ne peut pas faire

Sur des données non linéairement séparables, le échoue. Aucune droite ne peut isoler un cercle intérieur d’un cercle extérieur. Un seul est fondamentalement un classifieur linéaire avec une en sortie.

C’est la limite que le chapitre 6 attaque : un fait une ligne ; une couche de fait plusieurs lignes et les combine.

Recap

  • Un est une somme pondérée suivie d’une non-linéarité. - La mesure l’erreur. Binary + est le couple standard. - Le vaut (p - y) * x pour les . - L’ est une répétée. - Ton projet local a maintenant llm/nn.py avec un entraînable. - Limite : un seul ne sait apprendre qu’une frontière linéaire.

Pour aller plus loin

Prochaine étape : empiler les couches — un fait une ligne ; plusieurs peuvent sculpter beaucoup plus.