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.

Diagramme illustrant l'effet du Dropout sur un réseau de neurones : avant et après application, avec les activations supprimées en noir.

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 :

Schéma du processus de Bernoulli utilisé par le Dropout pour décider si une activation est conservée ou supprimée.

"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 :

Comparaison entre la phase d'entraînement, avec dropout actif, et la phase d'inférence, sans dropout, dans un réseau de neurones.

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

Illustration d'un neurone recevant les entrées de 100 neurones de la couche 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.

Schéma montrant que l'activation de chaque neurone jaune vaut 1 et que le poids de chaque connexion vaut aussi 1.

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

Calcul de l'entrée du neurone bleu : somme de 100 termes valant chacun 1×1.

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 :

Calcul de l'entrée du neurone bleu après dropout : environ 40 termes sont mis à zéro, ce qui donne une somme totale d'environ 60.

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.

Comparaison des entrées reçues par le neurone bleu : 100 en phase d'inférence, sans dropout, contre 60 en phase d'entraînement, avec dropout.

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%) :

Formule montrant comment la mise à l'échelle par 1/(1-p) ramène l'entrée du neurone de 60 à 100.

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 :

Extrait de code PyTorch définissant une couche de dropout avec un taux p=0.2.

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

Extrait de code PyTorch montrant qu'après application du dropout en mode entraînement, les valeurs conservées sont mises à l'échelle et augmentent.

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) :

Comparaison montrant que les valeurs obtenues avec le dropout correspondent exactement à celles obtenues en divisant manuellement par (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 :

Extrait de code PyTorch montrant qu'en mode évaluation, le dropout n'affecte plus les valeurs du tenseur.

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 ?


Commentaires

Avatar

ou participer

À lire ensuite

Des shots dans la même veine, à lire entre deux tâches.

Voir tous les shots
caret-right