Il y a quelques semaines, une startup tech m'a invité à mener leurs entretiens ML.
J'ai interviewé 12 candidats et je leur ai posé principalement des questions pratiques de ML.
Mais il y avait aussi quelques questions conceptuelles, comme celle-ci, que j'ai posée intentionnellement à chaque candidat :
Comment fonctionne le Dropout ?
Plutôt simple, non ?
Et pourtant, chaque candidat m'a donné une réponse incomplète, que voici :
Réponse des candidats
En résumé, l'idée est de mettre à zéro des neurones de façon aléatoire dans un réseau de neurones. Ça sert à régulariser le réseau.

Le Dropout n'est appliqué que pendant l'entraînement, et le choix des activations de neurones à mettre à zéro (ou à "dropper") est déterminé à l'aide d'une loi de Bernoulli :

"p" est la probabilité de dropout spécifiée,
par exemple dans PyTorch → nn.Dropout(p).
Ma question de relance : Ok, parfait ! Est-ce qu'on fait autre chose dans le Dropout ?
Les candidats : Non, c'est tout. On met juste des neurones à zéro et on entraîne le réseau normalement.
Revenons maintenant à ce Shot Data.
Bien sûr, je ne dis pas que les détails ci-dessus sont faux.
Ils sont corrects.
Sauf que ça ne représente que 50% du fonctionnement du Dropout, et malheureusement, la plupart des ressources ne couvrent pas les 50% restants.
Si toi aussi tu ne connaissais que les 50% que je viens de mentionner, continue à lire, il y a du nouveau pour toi.
Comment fonctionne réellement le Dropout ?
Pour commencer, il faut noter que le Dropout n'est appliqué que pendant l'entraînement, pas pendant la phase d'inférence ou d'évaluation :

Maintenant, imagine qu'un neurone reçoive son entrée à partir de 100 neurones de la couche cachée précédente :

Pour simplifier, faisons deux hypothèses :
L'activation de chaque neurone jaune est de 1.
Le poids de chaque connexion entre les neurones jaunes et le neurone bleu est aussi de 1.

Résultat, l'entrée reçue par le neurone bleu sera de 100, comme illustré ci-dessous :

Jusque-là tout va bien ?
Maintenant, pendant l'entraînement, si on utilisait le Dropout avec, disons, un taux de 40%, alors environ 40% des activations des neurones jaunes seraient mises à zéro.
Résultat, l'entrée reçue par le neurone bleu serait d'environ 60, comme illustré ci-dessous :

Cela dit, ce dernier point n'est valable que pour la phase d'entraînement.
Si le même scénario se produisait pendant la phase d'inférence, l'entrée reçue par le neurone bleu serait de 100.
Donc, dans des conditions similaires :
Entrée reçue pendant l'entraînement → 60.
Entrée reçue pendant l'inférence → 100.
Tu vois le problème ?
Pendant l'entraînement, la moyenne des entrées des neurones est nettement plus faible que celle reçue pendant l'inférence.

Plus formellement, l'utilisation du Dropout affecte significativement l'échelle des activations.
Or, on veut que les neurones du modèle reçoivent, tout au long du réseau, à peu près la même moyenne (ou espérance) d'activations pendant l'entraînement et pendant l'inférence.
Pour corriger ça, le Dropout effectue une étape supplémentaire.
L'idée est de mettre à l'échelle les entrées restantes actives pendant l'entraînement.
La façon la plus simple de faire ça est de multiplier toutes les activations pendant l'entraînement par un facteur 1/(1-p), où p est le taux de dropout.
Par exemple, en appliquant cette technique à l'entrée de neurone de 60, on obtient ce qui suit (rappel, on avait fixé p=40%) :

Comme illustré ci-dessus, la mise à l'échelle de l'entrée du neurone la ramène dans la plage souhaitée, ce qui rend les phases d'entraînement et d'inférence cohérentes pour le réseau.
Vérification expérimentale
On peut d'ailleurs vérifier que les implémentations classiques du Dropout, celle de PyTorch par exemple, effectuent bien cette étape.
Définissons une couche de dropout comme suit :

Maintenant, prenons un tenseur aléatoire et appliquons cette couche de dropout dessus :

Comme illustré ci-dessus, les valeurs conservées ont augmenté.
La deuxième valeur passe de 0.13 → 0.16.
La troisième valeur passe de 0.93 → 1.16.
et ainsi de suite…
Mieux encore, les valeurs conservées sont exactement les mêmes que celles qu'on aurait obtenues en mettant explicitement le tenseur d'entrée à l'échelle avec 1/(1-p) :

Si on faisait la même chose en mode évaluation, on remarque qu'aucune valeur n'est supprimée et qu'aucune mise à l'échelle n'a lieu non plus, ce qui est logique puisque le Dropout n'est utilisé que pendant l'entraînement :

Voilà les 50% restants, que, d'après mon expérience, la plupart des ressources ne couvrent pas, et que la plupart des gens ignorent donc.
Mais c'est une étape vraiment importante dans le Dropout, qui maintient la cohérence numérique entre les phases d'entraînement et d'inférence.
Avec ça, tu connais maintenant 100% du fonctionnement du Dropout.
Envie d'aller plus loin ? DataXp t'attend : formations et parcours pour progresser en data science, machine learning et IA.
👉 À toi de jouer : quelles sont les autres façons de régulariser un réseau de neurones ?

