Transcription de la vidéo
Dans la dernière vidéo, j’ai exposé la structure d’un réseau de
neurones. Je vais faire un bref récapitulatif ici, juste pour que cela reste
frais dans nos esprits. Ensuite, j’ai deux objectifs principaux pour cette vidéo. Le premier consiste à introduire l’idée de descente de gradient,
qui sous-tend non seulement la manière dont les réseaux de
neurones apprennent, mais aussi comment de nombreux autres
apprentissages automatiques fonctionnent. Ensuite, nous verrons un peu plus en détail comment fonctionne ce
réseau et ce que ces couches cachées de neurones
recherchent.
Pour rappel, notre objectif ici est l’exemple classique de la
reconnaissance des chiffres écrits à la main : le Hello
World des réseaux de neurones. Ces chiffres sont affichés sur une grille de 28 fois 28 pixels,
chaque pixel ayant une valeur dans une échelle de gris
comprise entre zéro et un. C’est ce qui détermine les activations de 784 neurones dans la
couche d’entrée du réseau. Ensuite, l’activation de chaque neurone dans les couches suivantes
est basée sur la somme pondérée de toutes les activations de
la couche précédente, plus un nombre spécial appelé
biais. Ensuite, vous composez cette somme avec une autre fonction telle la
fonction sigmoïde ou un ReLu, en utilisant la façon que j’ai
expliqué la dernière vidéo.
Au total, étant donné le choix quelque peu arbitraire de deux
couches cachées avec 16 neurones chacune, le réseau contient
environ 13000 poids et biais que nous pouvons ajuster. Et ce sont ces valeurs qui déterminent ce que fait exactement le
réseau. Et ce que nous voulons dire quand nous disons que ce réseau classe
un chiffre donné, c’est que le plus lumineux des 10 neurones
de la dernière couche correspond à ce chiffre. Et rappelez-vous, la motivation à laquelle nous pensions ici pour
la structure en couches était que peut-être la deuxième
couche pourrait-elle s’accrocher sur les bords. La troisième couche pourrait comprendre des motifs tels que des
boucles et des lignes. Et la dernière pourrait simplement rassembler ces motifs pour
reconnaître les chiffres.
Nous apprenons donc ici comment le réseau apprend. Ce que nous voulons c’est un algorithme, à travers lequel vous
pouvez montrer à ce réseau toute une série de données de
formation, qui se présentent sous la forme de toute une
série de différentes images de chiffres écrits à la main,
accompagnés d’étiquettes indiquant ce qu’ils sont supposés
être. Et il va ajuster ces 13000 poids et biais afin d’améliorer ses
performances sur les données de formation. Espérons que cette structure en couches signifie que ce qu’il
apprend se généralise en images au-delà des données de
formation. Et la façon dont nous testons cela est qu’après avoir formé le
réseau, vous lui montrez des données plus étiquetées
qu’elles n’ont jamais vues avant. Et vous voyez avec quelle précision il classe ces nouvelles
images.
Heureusement pour nous, et ce qui fait de cet exemple un exemple si
typique pour commencer avec, c’est que les responsables de
la base de données MNIST ont rassemblé une collection de
dizaines de milliers d’images de chiffres écrits à la main,
chacune étiquetée avec les nombres qu’elles sont supposées
être. Et aussi provocant que cela puisse être, de décrire une machine en
tant qu’apprentissage, une fois que vous avez bien compris
comment cela fonctionne, vous vous sentez beaucoup moins en
un lieu de science-fiction loufoque, et plus en un exercice
d’analyse mathématique. Je veux dire, il s’agit en principe de trouver le minimum d’une
certaine fonction.
Rappelez-vous, conceptuellement, nous pensons que chaque neurone
est connecté à tous les neurones de la couche
précédente. Et les poids dans la somme pondérée définissant son activation
ressemblent un peu aux points forts de ces connexions. Et le biais est une indication de savoir si ce neurone a tendance à
être actif ou inactif. Et pour commencer, nous allons initialiser tous ces poids et biais
de manière totalement aléatoire. Inutile de dire que ce réseau fonctionnera assez horriblement pour
un exemple d’entraînement donné, car il s’agit juste de
faire quelque chose d’aléatoire.
Par exemple, vous introduisez cette image d’un trois et la couche
de sortie est un chaos. Vous définissez donc une fonction de coût, une manière de dire à
l’ordinateur : « Non ! Mauvais ordinateur ! Cette sortie devrait avoir des activations nulles pour la plupart
des neurones, mais une pour ce neurone. Ce que vous m’avez donné, c’est une bêtise absolue ! » Pour dire un peu plus mathématiquement, vous additionnez les
carrés des différences entre chacune de ces activations de
sortie et la valeur que vous souhaitez qu’elles aient. Et c’est ce que nous appellerons le coût d’un seul exemple de
formation. Notez que cette somme est petite lorsque le réseau classe
correctement l’image en toute confiance. Mais elle est grande quand le réseau semble ne pas savoir vraiment
ce qu’il fait.
Vous devez donc tenir compte du coût moyen sur l’ensemble des
dizaines de milliers d’exemples d’entraînement mis à votre
disposition. Ce coût moyen est notre mesure de la détérioration du réseau et de
la gravité de l’état de l’ordinateur. Et c’est une chose compliquée. Rappelez-vous que le réseau lui-même était essentiellement une
fonction, prenant 784 nombres en entrée, les valeurs en
pixels, et crachant 10 nombres en sortie. Et dans un sens, il est paramétré par tous ces poids et biais. En plus, la fonction de coût est une couche de complexité. Il prend en compte ces quelque 13000 poids et biais. Et il crache un nombre unique décrivant la gravité de ces poids et
biais. Et sa définition dépend du comportement du réseau sur les dizaines
de milliers de données de formation. Ça fait beaucoup à penser !
Mais dire à l’ordinateur qu’il fait un travail minable n’est pas
très utile. Vous voulez lui dire comment changer ces poids et biais pour que ça
aille mieux. Pour faciliter la tâche, au lieu de vous efforcer d’imaginer une
fonction avec 13000 entrées, imaginez simplement une
fonction simple qui a un nombre comme entrée et un nombre
comme sortie. Comment trouvez-vous une entrée qui minimise la valeur de cette
fonction ? Les étudiants en analyse sauront que vous pouvez parfois comprendre
ce minimum explicitement. Mais cela n’est pas toujours faisable pour des fonctions vraiment
compliquées, certainement pas dans la version à 13000
entrées de cette situation pour notre insensée et compliquée
fonction de coût du réseau neuronal. Une tactique plus souple consiste à commencer par n’importe quelle
entrée ancienne et à déterminer la direction à suivre pour
réduire cette sortie.
Plus précisément, si vous pouvez déterminer le coefficient
directeur de la fonction là où vous vous trouvez, ensuite
vous vous déplacez vers la gauche si ce coefficient
directeur est positif, et déplacez l’entrée vers la droite
si ce coefficient directeur est négatif. Si vous faites cela à plusieurs reprises, à chaque point, en
vérifiant le nouveau coefficient directeur et en prenant les
mesures appropriées, vous vous approcherez du minimum local
de la fonction. Et l’image que vous pourriez avoir ici à l’esprit est une balle qui
glisse sur une colline. Et remarquez, même pour cette fonction vraiment simplifiée ayant
une entrée unique, vous pouvez atterrir dans de nombreuses
vallées, en fonction de l’entrée aléatoire où vous
commencez. Et il n’est pas garanti que le minimum local dans lequel vous
atterrissez sera la plus petite valeur possible de la
fonction de coût. Cela va également s’appliquer à notre réseau de neurones. Et je veux aussi que vous remarquiez comment, si les tailles de vos
pas sont proportionnelles au coefficient directeur, vos pas
deviennent de plus en plus petits lorsque le coefficient
directeur s’aplatit au minimum. Et cela vous aide à éviter les dépassements.
En augmentant un peu la complexité, imaginez plutôt une fonction
avec deux entrées et une sortie. Vous pourriez penser que l’espace d’entrée est le plan 𝑥𝑦, et que
la fonction de coût est représentée graphiquement comme une
surface située au-dessus de celui-ci. Au lieu de vous renseigner sur le coefficient directeur de la
fonction, vous devez vous demander dans quelle direction
vous devez vous déplacer dans cet espace d’entrée de manière
à réduire plus rapidement la sortie de la fonction. En d’autres termes, quelle est la descente ? Et encore une fois, il est utile de penser à une balle qui roule
sur cette colline. Ceux d’entre vous qui connaissent bien l’analyse à plusieurs
variables sauront que le gradient d’une fonction vous donne
la direction de la plus forte ascension. En gros, dans quelle direction vous devez agir pour augmenter la
fonction le plus rapidement.
Naturellement, prendre le négatif de ce gradient vous donne la
direction à suivre pour diminuer la fonction le plus
rapidement. Et même plus, la longueur de ce vecteur de gradient est en fait une
indication de la raideur de la pente la plus raide. Maintenant, si vous n’êtes pas familier avec l’analyse à plusieurs
variables et que vous voulez en savoir plus, consultez le
travail que j’ai effectué pour Khan Academy sur le
sujet. Honnêtement, tout ce qui compte pour vous et moi, c’est qu’il
existe en principe un moyen de calculer ce vecteur. Ce vecteur qui vous indique quelle est la direction de la descente
et à quel point elle est raide. Tout ira bien si c’est tout ce que vous savez et que vous n’êtes
pas aussi solide dans les détails. Parce que si vous pouvez l’obtenir, l’algorithme de minimisation de
la fonction consiste à calculer cette direction de
gradient. Ensuite, faites un petit pas en descente et répétez-le encore et
encore.
C’est la même idée de base pour une fonction qui a 13000 entrées
au lieu de deux entrées. Imaginez organiser les 13000 poids et biais de notre réseau dans
un vecteur colonne géant. Le gradient négatif de la fonction de coût n’est qu’un vecteur. C’est une direction à l’intérieur de cet espace d’entrée
incroyablement énorme qui vous indique quels coups de pouce
à tous ces nombres entraîneront la diminution la plus rapide
de la fonction de coût. Et, bien sûr, avec notre fonction de coût spécialement conçue,
modifier les poids et les biais pour la diminuer signifie
faire que la sortie du réseau sur chaque donnée de formation
ressemble moins à un tableau aléatoire de 10 valeurs et
davantage à une vraie décision qu’on veut qu’il fasse. Il est important de se rappeler que cette fonction de coût implique
une moyenne sur toutes les données de formation. Donc si vous la minimisez, alors cela signifie que les performances
sont meilleures sur tous ces échantillons.
L’algorithme permettant de calculer efficacement ce gradient, qui
est effectivement le cœur de l’apprentissage d’un réseau de
neurones, est appelé la rétropropagation de gradient. Et c’est ce dont je vais parler dans la prochaine vidéo. Là, je veux vraiment prendre le temps d’expliquer exactement ce qui
arrive à chaque poids et à chaque biais pour une donnée de
formation donnée, en essayant de représenter une idée
intuitive de ce qui se passe au-delà de la pile de calculs
et de formules pertinents. Ici et maintenant, la principale chose que je veux que vous
sachiez, indépendamment des détails de la mise en œuvre, est
que ce que nous entendons par l’apprentissage du réseau
c’est qu’il s’agit simplement de minimiser une fonction de
coût.
Et notez que l’une des conséquences de cela est qu’il est important
pour cette fonction de coût de générer une bonne et facile
sortie afin que nous puissions trouver un minimum local en
prenant de petits pas en descente. C’est la raison pour laquelle, à propos, les neurones artificiels
ont des activations qui varient en permanence plutôt que
d’être simplement actifs ou inactifs de façon binaire, comme
le sont les neurones biologiques. Ce processus consistant à pousser de manière répétée une entrée
d’une fonction par un multiple du gradient négatif est
appelé descente de gradient. C’est un moyen de converger vers le minimum local d’une fonction de
coût, qui est en fait une vallée sur ce graphique. Je suis toujours en train de montrer l’image d’une fonction à deux
entrées, car il est un peu difficile pour vous de concevoir
des coups de pouce dans un espace d’entrée en 13000
dimensions. Mais il existe en fait une belle façon non spatiale de penser à
cela.
Chaque composante du gradient négatif nous dit deux choses. Le signe, bien sûr, nous indique si la composante correspondante du
vecteur d’entrée doit être poussée vers le haut ou vers le
bas. Mais surtout, les amplitudes relatives de toutes ces composantes
vous permettent de savoir quels changements importent le
plus. Vous voyez, dans un réseau, un ajustement à l’un des poids pourrait
avoir un impact beaucoup plus important sur la fonction de
coût qu’un ajustement à un autre poids. Certaines de ces connexions sont plus importantes pour nos données
d’entraînement. Vous pouvez donc penser à ce vecteur gradient de notre énorme
fonction de coût comme l’élément qui code l’importance
relative de chaque poids et biais. C’est-à-dire lequel de ces changements rapportera le plus pour
votre argent ?
C’est juste une autre façon de penser à la direction. Pour prendre un exemple plus simple, si vous avez une fonction avec
deux variables en entrée, et que vous calculez que son
gradient en un certain point sort comme trois, un. Alors d’une part, vous pouvez interpréter en disant que, lorsque
vous vous tenez à cette entrée, le fait de suivre cette
direction augmente la fonction le plus rapidement. Lorsque vous tracez la fonction au-dessus du plan des points
d’entrée, le vecteur est ce qui vous donne la direction
ascendante droite. Mais une autre façon de lire est de dire que les changements
apportés à cette première variable ont trois fois plus
d’importance que les changements apportés à la deuxième
variable. Au moins dans le voisinage de l’entrée correspondante, le fait de
donner un coup de pouce à la valeur 𝑥 en rapporte beaucoup
plus pour votre argent.
Bon, faisons un zoom arrière et résumons où nous en sommes. Le réseau lui-même est cette fonction avec 784 entrées et 10
sorties, définies en termes de toutes ces sommes
pondérées. La fonction de coût est une couche de complexité qui vient
s’ajouter à cela. Il prend en compte les 13000 poids et biais et en sort une seule
mesure minable en se basant sur les exemples de
formation. Et le gradient de la fonction de coût est encore une couche de
complexité. Il nous indique quels sont les coups de pouce de tous ces poids et
biais qui entraînent le changement le plus rapide de la
valeur de la fonction de coût, ce qui peut être interprété
comme indiquant quels changements appliqués à quels poids
importent le plus.
Ainsi, lorsque vous initialisez le réseau avec des poids et des
biais aléatoires et que vous les ajustez plusieurs fois en
fonction de ce processus de descente de gradient, à quel
point fonctionnera-t-il sur des images jamais vues avant
? Celui que j’ai décrit ici, avec les deux couches cachées de 16
neurones chacune, choisi principalement pour des raisons
esthétiques, ce n’est pas mal ! Il classe environ 96 pour cent des nouvelles images qu’il voit
correctement. Et honnêtement, si vous regardez quelques exemples où il gâche
tout. Vous vous sentez forcé à vous montrer un peu négligent.
Maintenant, si vous jouez avec la structure de couche cachée et
effectuez quelques ajustements, vous pouvez obtenir ceci
jusqu’à 98 pour cent. Et c’est très bien ! Ce n’est pas l’idéal. Vous pouvez certainement obtenir de meilleures performances en
devenant plus sophistiqué que ce réseau « plain
vanilla ». Mais sachant comme la tâche initiale est ardue, je pense qu’il y a
quelque chose d’incroyable autour de tout réseau faisant
cela correctement sur des images qu’il n’a jamais vues
avant, étant donné que nous ne lui avons jamais indiqué
quels motifs rechercher.
À l’origine, j’ai motivé cette structure en décrivant un espoir que
nous pourrions avoir. Que la deuxième couche puisse se poser sur de petits bords. Que la troisième couche rassemble ces bords pour reconnaître les
boucles et les lignes plus longues. Et que celles-ci pourraient être rassemblées pour reconnaître les
chiffres. Alors, est-ce ce que c’est ce que notre réseau est en train de
faire ? Eh bien, au moins pour celui-ci, pas du tout ! Rappelez-vous de la dernière vidéo où nous avions vu comment le
poids des connexions de tous les neurones de la première
couche vers un neurone donné de la deuxième couche est
visualisé en tant que motif de pixels donné, sur lequel le
neurone de la deuxième couche se raccroche ?
Eh bien, lorsque nous faisons cela pour les poids associés à ces
transitions de la première couche à la suivante, au lieu de
prendre des petits bords isolés ici et là, ils ont l’air
presque aléatoires, à peu près certains motifs très flous au
milieu là. Il semblerait que dans l’énorme espace infini en 13000 dimensions
de poids et de biais possibles, notre réseau se soit
retrouvé un joyeux minimum local qui, malgré le classement
réussi de la plupart des images, ne reflète pas exactement
les modèles que nous aurions pu espérer. Et pour approfondir cette idée, observez ce qui se passe lorsque
vous saisissez une image aléatoire. Si le système était intelligent, vous pouvez vous attendre à ce
qu’il se sente incertain, n’active peut-être aucun de ces 10
neurones de sortie, ou les active de manière égale. Mais au lieu de cela, il vous donne en toute confiance une réponse
absurde, comme s’il était aussi sûr que ce bruit aléatoire
était un cinq, alors qu’une image réelle d’un cinq était un
cinq.
Formulé différemment, même si ce réseau reconnaît assez bien les
chiffres, il ne sait pas comment les dessiner. Cela tient en grande partie au fait qu’il s’agit d’un système de
formation extrêmement contraint. Je veux dire, mets-toi à la place du réseau ici. De son point de vue, l’univers entier n’est constitué que de
chiffres immobiles clairement définis et centrés dans une
grille minuscule. Et sa fonction de coût ne lui a jamais donné la moindre motivation
pour être tout sauf confiant dans ses décisions. Donc, si telle est l’image de ce que font réellement les neurones
de la deuxième couche, vous vous demandez peut-être pourquoi
je voudrais introduire ce réseau avec la motivation de
détecter les bords et les modèles. Je veux dire, ce n’est pas du tout ce qu’il termine par faire.
Eh bien, ce n’est pas censé être notre objectif final, mais plutôt
un point de départ. Franchement, il s’agit d’une technologie ancienne, celle qui a fait
l’objet de recherches dans les années 80 et 90. Et vous devez la comprendre avant de pouvoir comprendre des
variantes modernes plus détaillées. Et elle est clairement capable de résoudre des problèmes
intéressants. Mais plus on s’intéresse à ce que font réellement ces couches
cachées, moins elle semble intelligente. Détournez l’attention pour un instant de la manière dont les
réseaux apprennent sur la manière dont vous apprenez, mais
cela ne se produira que si vous vous engagez activement avec
le contenu ici. Une chose assez simple que je voudrais que vous fassiez, c’est de
faire une pause maintenant et de réfléchir longuement aux
modifications que vous pourriez apporter à ce système et à
la façon dont il perçoit les images, si vous souhaitez qu’il
détecte mieux des éléments comme les bords et les
motifs.
Mais mieux que cela, pour bien vous engager avec le contenu, je
recommande fortement le livre de Michael Nielsen sur le deep
learning et les réseaux de neurones. Vous y trouverez le code et les données à télécharger et à utiliser
pour cet exemple précis. Et le livre vous expliquera, étape par étape, ce que fait le
code. Ce qui est génial, c’est que ce livre est gratuit et accessible au
public. Donc si vous en tirez quelque chose, pensez vous joindre à moi pour
faire un don pour les efforts de Nielsen. J’ai également lié quelques autres ressources que j’aime beaucoup
dans la description, y compris l’extraordinaire et superbe
billet de blog de Chris Ola et les articles de Distill.
Pour clore les choses ici et pour les quelques dernières minutes,
je veux revenir à un extrait de l’interview que j’ai eu avec
Lisha Li. Vous vous souvenez peut-être d’elle depuis la dernière vidéo. Elle a effectué son travail de doctorat en deep learning. Et dans ce petit extrait, elle parle de deux articles récents qui
expliquent comment certains des réseaux de reconnaissance
d’images les plus modernes apprennent vraiment. Juste pour mettre en place où nous étions dans la conversation, le
premier article porte sur l’un de ces réseaux de neurones
particulièrement profonds, très performants en
reconnaissance d’images. Et au lieu de l’entraîner sur un jeu de données correctement
étiqueté, toutes les étiquettes ont été mélangées avant
l’entraînement.
De toute évidence, la précision des tests n’aurait été
qu’aléatoire, puisque tout est étiqueté au hasard. Mais il était tout de même capable de réaliser la même précision
d’entraînement que sur une série de données correctement
étiquetées. En fait, les millions de poids pour ce réseau en question étaient
suffisants pour mémoriser les données aléatoires, ce qui
soulève la question de savoir si la minimisation de cette
fonction de coût correspond réellement à une sorte de
structure dans l’image. Ou est-ce juste, vous savez, la mémorisation ?
Lisha Li : ... mémoriser l’ensemble des données de ce qu’est la
classification correcte. Et après quelques, vous savez, six mois plus tard, à l’ICML cette
année, il n’y avait pas exactement un article de réfutation,
mais un article qui abordait certains aspects de - comme par
exemple. En fait, ces réseaux font quelque chose d’un peu plus intelligent
que cela. Si vous regardez cette courbe de précision, si vous vous entraîniez
uniquement sur un ensemble de données aléatoires, alors
cette courbe s’est en quelque sorte abaissée très lentement,
de manière presque linéaire. Donc, vous avez vraiment du mal à trouver le minimum local des bons
poids qui vous donneraient cette précision. Tandis que si vous vous entraînez sur une série de données
structurée ayant les bonnes étiquettes, vous savez, vous
tripoterez un peu au début.
Mais ensuite, vous faite une chute très rapide pour atteindre ce
niveau de précision. Et ainsi, dans un sens, il est plus facile de trouver ces maximums
locaux. Ce qui est également intéressant à ce sujet, c’est qu’il met en
lumière un autre article datant d’il y a quelques années,
qui propose beaucoup plus de simplifications concernant les
couches du réseau. Mais l’un des résultats indiquait que, si vous regardez le paysage
de l’optimisation, alors les minimums locaux que ces réseaux
ont tendance à apprendre sont en réalité de qualité
égale. Donc dans un certain sens, si votre ensemble de données est
structuré, alors vous devrez pouvoir le trouver beaucoup
plus facilement.