Mais qu'est-ce qu'un réseau de neurones ?
5 octobre 2017
Apprentissage Automatique
Introduction à la reconnaissance des chiffres
Ceci est un trois. Il est écrit de manière négligée et rendu à une résolution extrêmement basse de 28 par 28 pixels, mais votre cerveau n'a aucun mal à le reconnaître comme un trois. Je veux que vous preniez un moment pour apprécier à quel point il est fou que les cerveaux puissent faire cela si sans effort. Ceci, ceci et ceci sont également reconnaissables comme des trois, même si les valeurs spécifiques de chaque pixel sont très différentes d'une image à l'autre. Les cellules photosensibles particulières de votre œil qui s'activent lorsque vous voyez ce trois sont très différentes de celles qui s'activent lorsque vous voyez ce trois. Mais quelque chose dans votre cortex visuel incroyablement intelligent les analyse comme représentant la même idée, tout en reconnaissant en même temps d'autres images comme leurs propres idées distinctes. Si je vous demandais de vous asseoir et de m'écrire un programme qui prend en entrée une grille de 28 par 28 pixels comme celle-ci et qui sort un seul nombre entre zéro et dix, vous disant quel est le chiffre selon lui, la tâche passe de comiquement triviale à redoutablement difficile.
Objectif de la vidéo et importance du sujet
À moins que vous ne viviez dans une grotte, je n'ai guère besoin de justifier la pertinence et l'importance de l'apprentissage automatique et des réseaux de neurones pour le présent et pour l'avenir. Mais ce que je veux faire ici, c'est vous montrer ce qu'est réellement un réseau de neurones, en supposant que vous n'ayez aucune base, et vous aider à visualiser ce qu'il fait. Pas comme un mot à la mode, mais comme un morceau de mathématiques. Mon espoir est que vous repartiez en ayant le sentiment que la structure elle-même est justifiée, et en sachant ce que cela signifie lorsque vous lisez ou entendez parler de l'apprentissage d'un réseau de neurones. Cette vidéo sera consacrée à la composante structurelle, et la suivante abordera l'apprentissage. Ce que nous allons faire, c'est construire un réseau de neurones capable d'apprendre à reconnaître des chiffres manuscrits. C'est un exemple assez classique pour introduire le sujet. Je suis heureux de m'en tenir au statu quo ici, car à la fin des deux vidéos, je veux vous orienter vers quelques bonnes ressources où vous pourrez en apprendre davantage et où vous pourrez télécharger le code qui fait cela et jouer avec sur votre propre ordinateur.
Structure fondamentale : Neurones et Couches
Il existe de nombreuses variantes de réseaux de neurones, et ces dernières années, la recherche sur ces variantes a explosé. Mais dans ces deux vidéos d'introduction, vous et moi allons examiner la forme classique la plus simple, sans fioritures. C'est un prérequis nécessaire pour comprendre n'importe laquelle des variantes modernes plus puissantes, et croyez-moi, elle possède encore suffisamment de complexité pour nous faire réfléchir. Mais même dans cette forme la plus simple, il peut apprendre à reconnaître des chiffres manuscrits, ce qui est une chose cool pour un ordinateur. Et en même temps, vous verrez comment il ne répond pas à certains espoirs que nous pourrions avoir. Comme le nom l'indique, les réseaux de neurones sont inspirés par le cerveau. Mais décomposons cela. Que sont les neurones et dans quel sens sont-ils liés entre eux ? Pour l'instant, quand je dis neurone, tout ce que je veux que vous imaginiez, c'est une chose qui contient un nombre. Plus précisément, un nombre entre zéro et un. Ce n'est rien de plus. Par exemple, le réseau commence par un groupe de neurones correspondant à chacun des 28 par 28 pixels de l'image d'entrée, soit 784 neurones au total. Chacun d'eux contient un nombre qui représente la valeur en niveaux de gris du pixel correspondant, allant de zéro pour les pixels noirs jusqu'à un pour les pixels blancs. Ce nombre à l'intérieur du neurone est appelé son activation. Et l'image que vous pourriez avoir en tête ici est que chaque neurone s'allume lorsque son activation est un nombre élevé. Tous ces 784 neurones constituent la première couche de notre réseau. Passons maintenant à la dernière couche, qui compte dix neurones, chacun représentant l'un des chiffres. L'activation de ces neurones, là encore un nombre entre zéro et un, représente à quel point le système pense qu'une image donnée correspond à un chiffre donné. Il y a aussi quelques couches intermédiaires appelées couches cachées, qui pour le moment devraient rester un point d'interrogation géant quant à la manière dont ce processus de reconnaissance de chiffres va être géré.
Le flux d'information et l'analogie biologique
Dans ce réseau, j'ai choisi deux couches cachées, chacune avec 16 neurones. Et il faut l'admettre, c'est un choix arbitraire. Pour être honnête, j'ai choisi deux couches en fonction de la manière dont je veux justifier la structure dans un instant. Et 16 était juste un bon nombre pour tenir sur l'écran. En pratique, il y a beaucoup de place pour l'expérimentation avec la structure spécifique ici. La manière dont le réseau fonctionne est que les activations d'une couche déterminent les activations de la suivante. Bien sûr, le cœur du réseau en tant que mécanisme de traitement de l'information réside précisément dans la manière dont ces activations d'une couche entraînent des activations dans la couche suivante. C'est censé être vaguement analogue à la façon dont, dans les réseaux biologiques de neurones, certains groupes de neurones s'activant provoquent l'activation de certains autres. Maintenant, le réseau que je montre ici a déjà été entraîné à reconnaître des chiffres. Laissez-moi vous montrer ce que j'entends par là. Cela signifie que si vous introduisez une image, allumant les 784 neurones de la couche d'entrée selon la luminosité de chaque pixel de l'image, ce motif d'activation provoque un motif très spécifique dans la couche suivante, qui provoque un motif dans celle d'après, ce qui donne finalement un motif dans la couche de sortie. Et le neurone le plus brillant de cette couche de sortie est le choix du réseau, pour ainsi dire, pour le chiffre que cette image représente.
Abstraction et décomposition en sous-composants
Et avant de plonger dans les mathématiques sur la façon dont une couche influence la suivante ou comment l'entraînement fonctionne, parlons simplement de la raison pour laquelle il est raisonnable d'attendre d'une structure en couches comme celle-ci qu'elle se comporte intelligemment. À quoi nous attendons-nous ici ? Quel est le meilleur espoir pour ce que ces couches intermédiaires pourraient faire ? Eh bien, quand vous ou moi reconnaissons des chiffres, nous assemblons divers composants. Un neuf a une boucle en haut et une ligne à droite. Un huit a également une boucle en haut, mais elle est associée à une autre boucle en bas. Un quatre se décompose en trois lignes spécifiques. Maintenant, dans un monde parfait, nous pourrions espérer que chaque neurone de l'avant-dernière couche corresponde à l'un de ces sous-composants. Que chaque fois que vous introduisez une image avec, disons, une boucle en haut, comme un neuf ou un huit, il y ait un neurone spécifique dont l'activation sera proche de un. Et je ne parle pas de cette boucle de pixels spécifique, l'espoir serait que n'importe quel motif généralement bouclé vers le haut active ce neurone. De cette façon, passer de la troisième couche à la dernière nécessite simplement d'apprendre quelle combinaison de sous-composants correspond à quels chiffres. Bien sûr, cela ne fait que repousser le problème, car comment reconnaîtrait-on ces sous-composants ou même comment apprendrait-on quels devraient être les bons sous-composants ? Et je n'ai toujours pas parlé de la façon dont une couche influence la suivante. Mais suivez-moi là-dessus un instant. Reconnaître une boucle peut également se décomposer en sous-problèmes. Une manière raisonnable de le faire serait de reconnaître d'abord les divers petits bords qui la composent. De même, une longue ligne, comme celle que l'on voit dans les chiffres un, quatre ou sept, n'est en réalité qu'un long bord, ou peut-être voyez-vous cela comme un certain motif de plusieurs bords plus petits. Donc, peut-être que notre espoir est que chaque neurone de la deuxième couche du réseau corresponde aux divers petits bords pertinents. Peut-être que lorsqu'une image comme celle-ci arrive, elle allume tous les neurones associés à environ huit à dix petits bords spécifiques, ce qui allume à son tour les neurones associés à la boucle supérieure et à une longue ligne verticale, et ceux-ci allument le neurone associé à un neuf. Que ce soit ce que notre réseau final fait réellement est une autre question, sur laquelle je reviendrai une fois que nous aurons vu comment entraîner le réseau. Mais c'est un espoir que nous pourrions avoir, une sorte d'objectif avec une structure en couches comme celle-ci. De plus, vous pouvez imaginer à quel point être capable de détecter des bords et des motifs comme celui-ci serait vraiment utile pour d'autres tâches de reconnaissance d'images. Et même au-delà de la reconnaissance d'images, il y a toutes sortes de choses intelligentes que vous pourriez vouloir faire et qui se décomposent en couches d'abstraction. L'analyse de la parole, par exemple, implique de prendre l'audio brut et d'extraire des sons distincts, qui se combinent pour former certaines syllabes, qui se combinent pour former des mots, qui se combinent pour constituer des phrases et des pensées plus abstraites, etc.
Les paramètres : Poids et Biais
Mais pour en revenir à la façon dont tout cela fonctionne réellement, imaginez-vous en train de concevoir comment exactement les activations d'une couche pourraient déterminer les activations de la suivante. L'objectif est d'avoir un mécanisme qui pourrait vraisemblablement combiner des pixels en bords, ou des bords en motifs, ou des motifs en chiffres. Et pour zoomer sur un exemple très spécifique, disons que l'espoir est qu'un neurone particulier de la deuxième couche détecte si l'image a un bord dans cette région ici. La question qui se pose est quels paramètres le réseau devrait-il avoir ? Quels cadrans et boutons devriez-vous pouvoir ajuster pour qu'il soit assez expressif pour capturer potentiellement ce motif ou n'importe quel autre motif de pixels ou le motif selon lequel plusieurs bords peuvent former une boucle. Ce que nous allons faire, c'est attribuer un poids à chacune des connexions entre notre neurone et les neurones de la première couche. Ces poids sont simplement des nombres. Prenez ensuite toutes ces activations de la première couche et calculez leur somme pondérée selon ces poids. Je trouve utile de penser à ces poids comme étant organisés dans leur propre petite grille. Et je vais utiliser des pixels verts pour indiquer les poids positifs et des pixels rouges pour indiquer les poids négatifs, où la luminosité de ce pixel est une représentation vague de la valeur du poids. Maintenant, si nous mettions à zéro les poids associés à presque tous les pixels, sauf pour certains poids positifs dans cette région qui nous intéresse, alors faire la somme pondérée de toutes les valeurs de pixels revient vraiment à additionner les valeurs des pixels juste dans la région qui nous intéresse. Et si vous vouliez vraiment détecter s'il y a un bord ici, ce que vous pourriez faire, c'est avoir des poids négatifs associés aux pixels environnants. Alors la somme est la plus grande lorsque ces pixels du milieu sont brillants mais que les pixels environnants sont plus sombres. Lorsque vous calculez une somme pondérée comme celle-ci, vous pouvez obtenir n'importe quel nombre. Mais pour ce réseau, ce que nous voulons, c'est que les activations soient une valeur entre zéro et un. Une chose courante à faire est donc d'injecter cette somme pondérée dans une fonction qui écrase la droite des nombres réels dans l'intervalle entre zéro et un. Et une fonction courante qui fait cela s'appelle la fonction sigmoïde, également connue sous le nom de courbe logistique. Les entrées très négatives finissent proches de zéro, les entrées très positives finissent proches de un, et elle augmente régulièrement autour de l'entrée zéro. Ainsi, l'activation du neurone ici est une mesure de la positivité de la somme pondérée correspondante. Mais peut-être que vous ne voulez pas que le neurone s'allume lorsque la somme pondérée est supérieure à zéro. Peut-être que vous voulez seulement qu'il soit actif lorsque la somme est supérieure à, disons, dix. C'est-à-dire que vous voulez un certain biais pour qu'il soit inactif. Ce que nous ferons alors, c'est simplement ajouter un autre nombre, comme moins dix, à cette somme pondérée avant de la passer dans la fonction de compression sigmoïde. Ce nombre supplémentaire est appelé le biais. Ainsi, les poids vous indiquent quel motif de pixels ce neurone de la deuxième couche détecte, et le biais vous indique à quel point la somme pondérée doit être élevée avant que le neurone ne commence à devenir significativement actif. Et ce n'est qu'un seul neurone. Chaque autre neurone de cette couche va être connecté aux 784 neurones de pixels de la première couche, et chacune de ces 784 connexions a son propre poids associé. De plus, chacun a un certain biais, un autre nombre que vous ajoutez à la somme pondérée avant de la compresser avec la sigmoïde. Et cela fait beaucoup de choses à penser. Avec cette couche cachée de 16 neurones, cela fait un total de 784 fois 16 poids avec 16 biais. Et tout cela n'est que pour les connexions de la première couche à la deuxième. Les connexions entre les autres couches ont également un tas de poids et de biais qui leur sont associés. Au final, ce réseau possède presque exactement 13 000 poids et biais au total. 13 000 boutons et cadrans qui peuvent être ajustés et tournés pour que ce réseau se comporte de différentes manières.
Notation matricielle et Algèbre linéaire
Alors, quand nous parlons d'apprentissage, cela fait référence au fait de faire trouver par l'ordinateur un réglage valide pour tous ces nombreux nombres afin qu'il résolve réellement le problème en question. Une expérience de pensée qui est à la fois amusante et horrifiante consiste à imaginer s'asseoir et régler tous ces poids et biais à la hand, en ajustant délibérément les nombres pour que la deuxième couche détecte les bords, la troisième couche les motifs, etc. Personnellement, je trouve cela satisfaisant plutôt que de simplement traiter le réseau comme une boîte noire totale, car lorsque le réseau ne fonctionne pas comme vous l'aviez prévu, si vous avez établi un peu de relation avec ce que ces poids et biais signifient réellement, vous avez un point de départ pour expérimenter sur la façon de changer la structure pour l'améliorer. Ou quand le réseau fonctionne mais pas pour les raisons auxquelles vous pourriez vous attendre, creuser ce que font les poids et les biais est un bon moyen de remettre en question vos hypothèses et d'exposer réellement l'espace complet des solutions possibles. Au fait, la fonction réelle ici est un peu lourde à écrire, ne trouvez-vous pas ? Laissez-moi donc vous montrer une manière plus compacte en notation de représenter ces connexions. C'est ainsi que vous le verriez si vous choisissiez d'en lire davantage sur les réseaux de neurones. Organisez toutes les activations d'une couche en une colonne sous forme de vecteur. Organisez ensuite tous les poids sous forme de matrice, où chaque ligne de cette matrice correspond aux connexions entre une couche et un neurone particulier de la couche suivante. Ce que cela signifie, c'est que prendre la somme pondérée des activations de la première couche selon ces poids correspond à l'un des termes du produit matrice-vecteur de tout ce que nous avons sur la gauche ici. Au fait, une grande partie de l'apprentissage automatique revient simplement à avoir une bonne compréhension de l'algèbre linéaire. Donc pour ceux d'entre vous qui veulent une bonne compréhension visuelle des matrices et de ce que signifie la multiplication matrice-vecteur, jetez un œil à la série que j'ai faite sur l'algèbre linéaire, en particulier au chapitre trois. Pour en revenir à notre expression, au lieu de parler d'ajouter le biais à chacune de ces valeurs indépendamment, nous le représentons en organisant tous ces biais dans un vecteur et en ajoutant le vecteur entier au produit matrice-vecteur précédent. Puis, comme étape finale, j'envelopperai une sigmoïde autour de l'ensemble. Et ce que c'est censé représenter, c'est que vous allez appliquer la fonction sigmoïde à chaque composante spécifique du vecteur résultant à l'intérieur. Ainsi, une fois que vous écrivez cette matrice de poids et ces vecteurs comme leurs propres symboles, vous pouvez communiquer la transition complète des activations d'une couche à la suivante dans une petite expression extrêmement serrée et soignée. Et cela rend le code correspondant à la fois beaucoup plus simple et beaucoup plus rapide, puisque de nombreuses bibliothèques optimisent énormément la multiplication de matrices.
Le réseau comme fonction mathématique
Vous vous souvenez comment j'ai dit plus tôt que ces neurones sont simplement des choses qui contiennent des nombres ? Bien sûr, les nombres spécifiques qu'ils contiennent dépendent de l'image que vous fournissez. Il est donc plus précis de considérer chaque neurone comme une fonction, qui prend en entrée les sorties de tous les neurones de la couche précédente et recrache un nombre entre zéro et un. En réalité, le réseau entier n'est qu'une fonction, qui prend 784 nombres en entrée et recrache dix nombres en sortie. C'est une fonction absurdement compliquée, qui implique 13 000 paramètres sous forme de ces poids et biais qui détectent certains motifs et qui implique l'itération de nombreux produits matrice-vecteur et cette fonction de compression sigmoïde. Mais ce n'est qu'une fonction malgré tout. Et d'une certaine manière, il est rassurant qu'elle ait l'air compliquée. Je veux dire, si elle était plus simple, quel espoir aurions-nous qu'elle puisse relever le défi de reconnaître des chiffres ? Et comment relève-t-elle ce défi ? Comment ce réseau apprend-il les poids et les biais appropriés simplement en regardant des données ? C'est ce que je montrerai dans la prochaine vidéo. Et je creuserai aussi un peu plus ce que ce réseau particulier que nous voyons fait réellement. C'est maintenant le moment où je suppose que je devrais dire abonnez-vous pour rester informé de la sortie de cette vidéo ou de toute nouvelle vidéo. Mais en réalité, la plupart d'entre vous ne reçoivent pas vraiment de notifications de YouTube, n'est-ce pas ? Peut-être plus honnêtement, je devrais dire abonnez-vous pour que les réseaux de neurones qui sous-tendent l'algorithme de recommandation de YouTube soient préparés à croire que vous voulez voir du contenu de cette chaîne vous être recommandé. Quoi qu'il en soit, restez à l'écoute pour la suite.
Discussion sur les fonctions d'activation : Sigmoïde vs ReLU
Merci beaucoup à tous ceux qui soutiennent ces vidéos sur Patreon. J'ai été un peu lent à progresser dans la série sur les probabilités cet été, mais je m'y replonge après ce projet, donc donateurs, vous pouvez vous attendre à des mises à jour là-bas. Pour conclure ici, j'ai avec moi Lisha Li, qui a fait ses travaux de doctorat sur le côté théorique de l'apprentissage profond et qui travaille actuellement dans une société de capital-risque appelée Amplify Partners, qui a aimablement fourni une partie du financement de cette vidéo. Alors Lisha, une chose que je pense que nous devrions aborder rapidement est cette fonction sigmoïde. D'après ce que je comprends, les premiers réseaux utilisaient cela pour écraser la somme pondérée pertinente dans cet intervalle entre zéro et un, motivés par cette analogie biologique de neurones soit inactifs soit actifs.
Exactement.
Mais relativement peu de réseaux modernes utilisent encore la sigmoïde. C'est dépassé, n'est-ce pas ?
Le ReLU semble être beaucoup plus facile à entraîner.
Et ReLU signifie unité linéaire rectifiée.
Oui, c'est cette fonction où vous prenez le maximum entre zéro et a, où a est donné par ce que vous expliquiez dans la vidéo. C'était motivé par une analogie biologique avec la façon dont les neurones seraient soit activés soit non. S'il dépasse un certain seuil, ce serait la fonction identité, mais s'il ne le faisait pas, il ne serait pas activé, donc zéro. C'est une simplification. L'utilisation des sigmoïdes n'aidait pas l'entraînement, ou c'était très difficile à entraîner à un moment donné, et les gens ont simplement essayé le ReLU, et il se trouve que cela a très bien fonctionné pour ces réseaux de neurones incroyablement profonds.
D'accord, merci Lisha.