Qu'est-ce qu'un neurone, vraiment?
Si tu as suivi la Phase 0, tu as déjà deviné une règle : « Si la longueur du pétale dépasse un certain seuil, c'est une Virginica ». C'était une règle dure — oui ou non, noir ou blanc.
Un neurone artificiel fait quelque chose de similaire, mais beaucoup plus nuancé.
Au lieu d'une règle dure, un neurone calcule une probabilité progressive : « Vu ces deux mesures, quelle est la confiance que c'est une Virginica? »
La recette d'un neurone :
- Prendre les entrées (longueur et largeur du pétale)
- Peser chacune - décider laquelle est plus importante (poids1, poids2)
- Additionner le tout - un biais (décalage initial)
- Appliquer une courbe - la sigmoïde, qui transforme n'importe quel nombre en probabilité entre 0 et 1
Aucune intelligence là-dedans. Juste des multiplications, une addition, et une courbe.
📖 Vocabulaire - français / anglais
- neurone ↔ *neuron* (une calculatrice avec des poids)
- poids ↔ *weight* (l'importance de chaque entrée)
- biais ↔ *bias* (un décalage initial)
- sigmoïde ↔ *sigmoid* (la courbe en S, 0 → 0.5 → 1)
- pré-activation ↔ *pre-activation* (avant la sigmoïde)
Exemple concret : la température
Avant le code, comprends la recette avec un exemple simple.
Imagine un neurone qui prédit si c'est un jour chaud, basé sur :
- Entrée 1 (x1): L'humidité, normalisée entre 0 et 1. Par ex., 0.6 = 60% d'humidité.
- Entrée 2 (x2): Le rayonnement solaire, normalisé. Par ex., 0.8 = 80% du maximum observé.
Le neurone a déjà des poids (ajustés par entraînement antérieur) :
- Poids 1 = 2.0 : l'humidité influence fortement la prédiction
- Poids 2 = 1.5 : le soleil aussi, mais un peu moins
- Biais = -1.0 : par défaut, « il fait plutôt froid »
Étape 1 : pré-activation (somme pondérée)
somme = x1*poids1 + x2*poids2 + biais
somme = 0.6*2.0 + 0.8*1.5 + (-1.0)
somme = 1.2 + 1.2 - 1.0
somme = 1.4
À ce stade, somme = 1.4. C'est un nombre brut, sans limites. Il pourrait être 100 ou -50.
Étape 2 : sigmoid (normalisation en probabilité)
La sigmoïde est une courbe lisse en S qui écrase n'importe quel nombre entre 0 et 1.
prediction = sigmoide(1.4)
= 1 / (1 + e^(-1.4))
≈ 0.80
Donc, le neurone dit : 80% de chance que c'est un jour chaud.
Pourquoi la sigmoïde?
En Phase 0, tu as utilisé une règle dure : « Si longueur > 3, c'est Virginica ». C'était un saut sec.
La sigmoïde, c'est le contraire. Au lieu d'un saut, tu obtiens une courbe douce :
- Quand
sommeest très négatif (-10),sigmoide→ 0.00001 (presque 0, mais pas exactement) - Quand
somme= 0,sigmoide→ 0.5 (parfaite incertitude) - Quand
sommeest très positif (+10),sigmoide→ 0.99999 (presque 1)
C'est ce qui permet au neurone de dire « 60% sûr, 80% sûr », au lieu de juste « oui ou non ».
Code Python
Maintenant, le code qui fait ces calculs :
import math
def sigmoide(x):
# La formule : 1 / (1 + e^(-x))
# Elle transforme n'importe quel nombre entre 0 et 1
return 1 / (1 + math.exp(-x))
def neurone(x1, x2, poids1, poids2, biais):
# Étape 1 : somme pondérée (pré-activation)
somme = x1 * poids1 + x2 * poids2 + biais
# Étape 2 : appliquer la sigmoïde (activation)
sortie = sigmoide(somme)
return sortie
# Test avec l'exemple ci-dessus
prediction = neurone(0.6, 0.8, 2.0, 1.5, -1.0)
print(f"Probabilité d'un jour chaud : {prediction:.2f}") # -> 0.80
# Teste avec des fleurs Iris
# (x1 = longueur pétale, x2 = largeur pétale)
prediction_virginica = neurone(5.1, 1.8, 0.1, 0.1, 0.0)
print(f"C'est une Virginica? {prediction_virginica:.2f} (50% = incertain, proche de 1 = sûr)")
Note sur Python :
math.exp(x)calcule e^x (la constante e ≈ 2.718, à la puissance x)- Le point
.dans0.1indique un nombre décimal (pas un entier) :2fdans la chaîne de caractèresf"{...:.2f}"veut dire « affiche 2 chiffres après la virgule »
Exercice 2.1 - Ajuster les poids à la main
Tu vas faire maintenant ce que l'apprentissage automatique fait à l'échelle des millions : ajuster les poids pour réduire l'erreur.
La tâche :
Une fleur Virginica a : longueur pétale = 5.1, largeur pétale = 1.8.
Idéalement, le neurone devrait répondre 1.0 (« j'en suis certain, c'est une Virginica »).
Actuellement, avec poids1=0.1, poids2=0.1, biais=0.0, il répond seulement ≈ 0.62.
Ce que tu vas faire :
- Copie le code du neurone.
- Teste avec les poids actuels :
neurone(5.1, 1.8, 0.1, 0.1, 0.0)→ Résultat: 0.62 - Change UN SEUL poids à la fois, teste, observe.
- Continue jusqu'à obtenir une réponse > 0.90.
✍️ À toi de jouer
Expérimente :
- Augmente
poids1tout seul de 0.1 à 0.5, teste après chaque changement. Que remarques-tu? - Ajoute un biais négatif, disons
-1.0. Que se passe-t-il? - Teste
poids2négatif. Que devient la prédiction?
Enregistre ce que tu observes pour chaque changement.
Besoin d'un indice ?
Pense logiquement :
- x1 (5.1) est un grand nombre. Quand tu le multiplies par un poids, l'effet dépend de ce poids.
- Si poids1 = 0.1, le contribution est 5.1 * 0.1 = 0.51 à la somme.
- Si poids1 = 1.0, la contribution est 5.1 * 1.0 = 5.1 — beaucoup plus.
- Le biais ajoute ou enlève un offset constant, indépendamment des entrées.
Essaie cet ordre :
- Augmente
poids1à 1.0, teste :neurone(5.1, 1.8, 1.0, 0.1, 0.0) - Ajoute un biais, essaie
-1.0:neurone(5.1, 1.8, 1.0, 0.1, -1.0) - Ajuste fino si besoin.
Voir la réponse
# Voici une solution possible (il y en a d'autres!)
p1, p2, b = 1.2, 0.3, -3.0
resultat = neurone(5.1, 1.8, p1, p2, b)
print(f"Prédiction: {resultat:.3f}") # -> environ 0.95
# Vérification détaillée (pour comprendre chaque étape)
somme = 5.1*p1 + 1.8*p2 + b
print(f"Somme pré-activation: {somme:.3f}") # -> environ 5.07
print(f"Après sigmoïde: {resultat:.3f}") # -> 0.95
Ce que tu as appris :
- Poids1 a le plus grand effet, car x1 (5.1) est le plus grand nombre. Un poids plus fort le rend plus influent.
- Le biais est un décalage qui s'applique toujours, indépendamment des entrées. Un biais négatif rend le neurone « sceptique par défaut ». Il faut des entrées fortes pour le convaincre. C'est comme un seuil : « prouves-moi que c'est une Virginica ».
- Poids2 reste faible car x2 (1.8) est petit. Un poids négatif réduirait l'influence de la largeur du pétale.
L'analogie : Tu viens de faire, à la main, ce que l'algorithme de rétropropagation (backpropagation) fait automatiquement lors de l'entraînement : observer l'erreur et ajuster les poids pour la réduire. C'est EXACTEMENT ça, l'apprentissage.
Exercice 2.2 - Le défi : classer 4 fleurs à la main
Voilà le vrai défi : trouve UN jeu de poids qui classe correctement toutes les 4 fleurs.
Les données :
| Fleur | Longueur (x1) | Largeur (x2) | Espèce | Sortie attendue |
|---|---|---|---|---|
| A | 1.4 | 0.2 | Setosa | 0 (non-Virginica) |
| B | 1.3 | 0.2 | Setosa | 0 (non-Virginica) |
| C | 5.1 | 1.8 | Virginica | 1 (oui, Virginica) |
| D | 5.9 | 2.1 | Virginica | 1 (oui, Virginica) |
Comment le faire :
- Prépare une boucle qui teste tes poids sur les 4 fleurs à la fois
- Pour chaque fleur, affiche la prédiction vs l'attendu
- Ajuste UN poids à la fois
- Re-teste les 4 fleurs
- Répète jusqu'à ce que toutes les 4 soient bonnes
Stratégie :
Observe les différences :
- Setosa : x1 ≈ 1.3-1.4 (très court)
- Virginica : x1 ≈ 5.1-5.9 (très long)
La longueur est très différente. La largeur (x2) aussi change, mais moins. Tu peux probablement te débrouiller avec juste poids1 sans poids2.
✍️ À toi de jouer
Fais cet exercice :
# Commence ici
p1, p2, b = 0.5, 0.0, -1.0 # Valeurs de départ
# Crée une boucle de test
for nom, x1, x2, attendu in [("A", 1.4, 0.2, 0),
("B", 1.3, 0.2, 0),
("C", 5.1, 1.8, 1),
("D", 5.9, 2.1, 1)]:
pred = neurone(x1, x2, p1, p2, b)
erreur = "✓" if (pred > 0.5 and attendu == 1) or (pred < 0.5 and attendu == 0) else "✗"
print(f"{nom}: x1={x1}, x2={x2} | prédiction={pred:.3f} | attendu={attendu} {erreur}")
# Après chaque ajustement, réexécute la boucle
Ajuste tes poids graduellement :
- D'abord, augmente
p1pour que C et D remontent - Puis, augmente
|b|(le biais en valeur absolue) pour que A et B redescendent - Si besoin, ajuste
p2pour la largeur
Quel ensemble de poids finit par fonctionner? Trace ton chemin.
Besoin d'un indice ?
Pense en termes de « confiance » :
- Quand x1 est petit (1.3), le neurone doit répondre proche de 0 = « c'est pas Virginica »
- Quand x1 est grand (5.1+), le neurone doit répondre proche de 1 = « c'est Virginica »
Un biais très négatif (disons -5.0) force le neurone à exiger des entrées fortes. Un poids1 très positif (disons 2.0) amplifie la longueur du pétale.
Essaie cet ordre de progression :
p1=1.0, p2=0.0, b=-1.0→ testep1=2.0, p2=0.0, b=-3.0→ teste- Affine si besoin
Voir la réponse
# Une solution qui marche
p1, p2, b = 2.0, 0.0, -3.0
print("TEST FINAL :")
for nom, x1, x2, attendu in [("A", 1.4, 0.2, 0),
("B", 1.3, 0.2, 0),
("C", 5.1, 1.8, 1),
("D", 5.9, 2.1, 1)]:
pred = neurone(x1, x2, p1, p2, b)
erreur = "✓" if (pred > 0.5 and attendu == 1) or (pred < 0.5 and attendu == 0) else "✗"
print(f"{nom}: prediction={pred:.3f}, attendu={attendu} {erreur}")
# Calculs détaillés pour fleur C (la plus proche du seuil)
print("\nDétail pour C:")
somme_c = 5.1*p1 + 1.8*p2 + b
print(f" Somme: 5.1*{p1} + 1.8*{p2} + {b} = {somme_c:.2f}")
pred_c = neurone(5.1, 1.8, p1, p2, b)
print(f" Sigmoïde({somme_c:.2f}) = {pred_c:.3f}")
Résultats attendus : A ≈ 0.02, B ≈ 0.01, C ≈ 0.95, D ≈ 0.98
Observations clés :
- La longueur suffit presque toujours. Remarque que
p2=0marche bien. La largeur n'aide pas beaucoup ici — la longueur seule sépare bien les deux espèces.
- Le biais rend le seuil « mobile ». Un biais très négatif (-3.0) force le neurone à être méfiant. Même une longueur = 1.4 donne une réponse proche de 0.
- C'est ça, ajuster un réseau : Tu viens de faire exactement ce que l'entraînement automatique fait, mais à la main. Une fois cette expérience terminée, tu comprends pourquoi les données d'entraînement sont cruciales : elles disent au réseau « voilà des cas réels; fais en sorte de bien les classer ». Le réseau ajuste alors les poids, un peu comme tu viens de le faire.
Le grand saut : Avec 2 entrées et 1 neurone, tu dois ajuster 3 nombres (2 poids + 1 biais). En Phase 3, tu en auras 10. En Phase 4, des milliers. NumPy fera ces ajustements pour toi. Mais la mécanique reste identique.