Programmation différenciable


Avec quatre paramètres, je peux demander à un éléphant, et avec cinq je peux lui faire bouger sa trompe.
- John Von Neumann

L'idée de " programmation différenciable " est très populaire dans le monde de l'apprentissage automatique. Pour beaucoup, il n'est pas clair si ce terme reflète un réel changement dans la façon dont les chercheurs comprennent l'apprentissage automatique, ou s'il s'agit simplement d'un (autre) changement de nom de «l'apprentissage en profondeur». Cet article explique les nouveautés de la programmation différenciée (ou ∂P) dans la table d'apprentissage automatique.


Plus important encore, la programmation différenciée est le changement opposé à la direction de l'apprentissage en profondeur; des modèles de plus en plus paramétrés aux modèles plus simples qui utilisent davantage la structure du problème.


Ensuite, nous parcourons une toile de texte sans intérêt, nous voulons découvrir ce qu'est l'auto-différenciation, et même la remplir à partir d'une catapulte!


Force brute avec avantages


La différenciation est une idée de base qui fait le succès de l'apprentissage en profondeur. Là où la recherche par force brute de plusieurs centaines de paramètres de modèle serait trop coûteuse, les gradients permettent une traversée pseudo-aléatoire de parties intéressantes de l'espace des paramètres et trouvent un bon ensemble. En réalisant un algorithme aussi naïf, nous obtenons une bonne généralité, mais il est loin d'être évident que nous devons différencier, par exemple, le travail avec des séquences en traduction de langue, mais tout se révèle simple, nous montrons un peu d'ingéniosité.


Qu'en est-il des neurones biologiques et y=σ(W foisx+b)? Il n'y a rien de spécial dans cette formule; Il s'agit d'un exemple simple et flexible d'une fonction non linéaire hautement paramétrique. En fait, c'est probablement la pire caractéristique dans la plupart des cas. Une couche du réseau neuronal, en principe, peut classer des images de chats, mais uniquement en utilisant une astuce relativement peu intéressante. Cela fonctionne parfaitement! - mais les petits caractères avertissent que vous pourriez avoir besoin de plus de paramètres que d'atomes dans l'univers. Pour que ce travail fonctionne, vous devez coder la structure problématique du modèle - c'est là qu'il commence à ressembler davantage à la programmation traditionnelle.


Par exemple, les ConvNets ont un énorme avantage sur le perceptron, car ils fonctionnent avec les noyaux d'images , qui sont connus pour utiliser l'invariance de traduction. Visage - c'est le visage, qu'il soit affiché dans le coin supérieur gauche de l'image ou au centre, mais là où le perceptron doit étudier ce cas dans chaque cas, le noyau peut immédiatement répondre à n'importe quelle partie de l'image. Il est difficile d'analyser les réseaux convolutionnels en termes statistiques, mais il est beaucoup plus facile de les considérer comme une version automatique de ce que les experts en traitement d'images ont écrit à la main. Le noyau de l'image est le premier programme différenciable le plus simple.


Structure d'encodage, Redux


Les boîtes à outils ML prennent de plus en plus en charge la différenciation algorithmique (AD), ce qui nous permet de différencier les modèles à l'aide de boucles, de branches et de récursivité - ou de tout programme basé sur un ensemble de primitives mathématiques différenciables. Cela a conduit à une architecture plus complexe: les modèles PNL sont de plus en plus comme des analyseurs de grammaire classiques avec des modèles à pile augmentée , et vous pouvez même différencier un analogue d'une machine de Turing ou un interpréteur de langage de programmation .


La dernière étape franchie par la programmation différenciée consiste à ne plus considérer la multiplication matricielle, la convolution et le RNN comme des éléments fondamentaux de l'apprentissage en profondeur, mais uniquement comme des cas particuliers. Nous pouvons appliquer des méthodes d'apprentissage approfondi à toute fonction différenciable paramétrée f(x). Des fonctions aussi complexes que les simulateurs physiques ou les traceurs de rayons peuvent également être différenciées et optimisées. Même l'informatique quantique peut s'intégrer dans cette structure.



Les scientifiques utilisent depuis longtemps des modèles mécanistes qui se situent entre la programmation explicite et l'apprentissage automatique. Les équations différentielles à paramètres libres utilisées en physique, épidémiologie ou pharmacodynamique sont équivalentes aux réseaux de neurones dans tout sauf la terminologie. Ils visent simplement à fournir des fonctionnalités beaucoup plus étroites, car c'est tellement plus simple.


Un progrès vraiment puissant est le suivant: la différenciation omniprésente signifie que toutes ces méthodes se connectent comme des briques lego .
Au lieu d'écrire toujours de nouveaux programmes pour ML, nous pouvons réutiliser des programmes existants en utilisant des moteurs physiques dans des modèles de robotique d' apprentissage profond. Là où les algorithmes d'apprentissage par renforcement modernes doivent construire un modèle détaillé du monde extérieur basé uniquement sur ce pour quoi ils seront récompensés (sons comme la force brute ), nous pouvons plutôt simplement appliquer une connaissance détaillée et précise des systèmes physiques avant même que l'apprentissage ne commence.


Même les domaines les plus matures de l'apprentissage en profondeur ne sont pas en reste; après le noyau de convolution, la prochaine étape naturelle pour les modèles d'images est un traceur de rayons différenciable . Le rendu 3D contient beaucoup de connaissances structurelles sur la façon dont les scènes sont affichées en pixels, qui continueront de jouer un rôle dans notre cuisine. Disons qu'un modèle prend des décisions dans un environnement simulé affiché en pixels, que le modèle utilise comme entrée. En principe, nous pouvons maintenant rendre l'ensemble du cycle différenciable, ce qui nous permettra de voir directement l'influence de l'environnement sur les décisions du modèle et vice versa. Cela peut augmenter considérablement la puissance d'un environnement simulé réaliste pour les modèles d'entraînement, tels que les voitures à conduite automatique.


Comme en science, les modèles hybrides peuvent être plus efficaces et résoudre certains des compromis entre l'apprentissage en profondeur et la programmation explicite. Par exemple, un planificateur de trajectoire de vol de drone peut avoir un composant de réseau neuronal qui ne peut apporter que des modifications légèrement correctives à un programme explicite fiable, faisant analyser son comportement général, tout en s'adaptant aux données empiriques. Cela est également bon pour l'interprétabilité: les paramètres des modèles mécanistes et des simulations ont généralement des interprétations physiques claires, donc si le modèle évalue les paramètres à l'intérieur, il fait une déclaration claire sur ce qui, à son avis, se passe à l'extérieur.


Si tout cela est si merveilleux, pourquoi tout le monde n'a-t-il pas abandonné et s'est-il précipité pour apprendre à se différencier? Malheureusement, les limites des cadres existants rendent difficile la construction de modèles d'une telle complexité et il est impossible de réutiliser la richesse des connaissances intégrées dans le code scientifique existant. La nécessité de réimplémenter les moteurs physiques à partir de zéro dans un langage de modélisation très limité transforme un script de dix lignes en un projet de recherche pluriannuel. Mais les progrès du langage et de la technologie de compilation , en particulier la différenciation automatique , nous rapprochent du Saint Graal: "différenciez simplement mon moteur de jeu, s'il vous plaît."


Qu'est-ce donc que la programmation différenciée?


La programmation différenciée vous permet d'appliquer des méthodes d'apprentissage approfondi à des programmes existants complexes, en réutilisant avec eux une énorme quantité de connaissances intégrées. Apprentissage en profondeur, statistiques, programmation et science - tout ce qui essaie de dire sa parole dans la modélisation du monde qui nous entoure - il est temps de tout combiner, de le rapprocher comme des particules dans un collisionneur de hadrons . Cela améliorera à la fois les modèles actuels et permettra d'appliquer le ML dans les domaines où ses limites actuelles - soit l'interprétabilité ou les exigences de calcul et de données - les rendent individuellement inapplicables.


Problèmes de gestion différenciables


Ensuite, nous montrons que la différentiabilité peut apporter des tâches de gestion simples mais classiques, dans lesquelles nous utilisons généralement le renforcement par apprentissage (RL) comme boîte noire. Les modèles différenciables (modèles ∂P) révèlent non seulement des stratégies de contrôle beaucoup plus efficaces, mais apprennent également plusieurs ordres de grandeur plus rapidement. Le code est disponible pour étude - dans la plupart des cas, il apprend en quelques secondes sur n'importe quel ordinateur portable.


Suivez le dégradé


La différenciation est ce qui est la force motrice à presque toutes les étapes de l'apprentissage en profondeur; pour cette fonction y=f(x)nous utilisons le gradient  fracdydxpour savoir comment un changement de x affectera y . Malgré la nature mathématique, les gradients sont en fait un concept très général et intuitif. Oubliez les formules que vous avez dû regarder à l'école; faisons quelque chose de plus amusant, comme jeter quelque chose le long d'un chemin parabolique.



Lorsque nous lançons des projectiles à l'aide d'un tir à trois coups, notre x (entrée) représente le réglage (par exemple, la taille du contrepoids ou l'angle d'éjection), et y est la distance que le projectile parcourt avant l'atterrissage. Si vous essayez de viser, le dégradé vous dit quelque chose de très utile - augmenter ou diminuer un certain paramètre. Pour maximiser la distance, suivez simplement le gradient.


OK, mais comment obtenir le bon paramètre? Mais à l'aide d'une chose délicate appelée différenciation algorithmique , qui vous permet de différencier non seulement les formules simples que vous avez apprises à l'école, mais également les programmes de toute complexité - par exemple, notre simulateur Trebuchet . En conséquence, nous pouvons prendre un simulateur simple écrit en Julia et un package diff diff DiffEq sans étude approfondie, et obtenir des gradients pour cela en un seul appel de fonction.


 # what you did in school gradient(x -> 3x^2 + 2x + 1, 5) # (32,) # something a little more advanced gradient((wind, angle, weight) -> Trebuchet.shoot(wind, angle, weight), -2, 45, 200) # (4.02, -0.99, 0.051) 

Lancer des trucs


Nous devons cibler le trébuchet sur la cible, en utilisant des gradients pour affiner l'angle d'éjection; C'est ce qu'on appelle l'estimation des paramètres, et nous avons déjà examiné des exemples similaires . Nous pouvons rendre la tâche plus intéressante en passant à la méta-méthode: au lieu de viser le trébuchet sur une cible, nous optimisons le réseau neuronal, qui peut le cibler sur n'importe quelle cible. Voici comment cela fonctionne: un réseau de neurones accepte deux entrées, une distance cible en mètres et une vitesse actuelle du vent. Dans le réseau, les paramètres du trébuchet sont définis (la masse du contrepoids et l'angle de déclenchement), qui sont transmis au simulateur, qui calcule la distance parcourue. Ensuite, nous comparons avec notre objectif et parcourons toute la chaîne pour ajuster le poids du réseau. Notre «ensemble de données» est un ensemble de cibles et de vitesses de vent sélectionnées au hasard.



Une bonne caractéristique de ce modèle simple est que l'apprentissage est rapide car nous avons exprimé exactement ce que nous voulons du modèle d'une manière complètement différentiable. Au départ, cela ressemble à ceci:



Après environ cinq minutes de formation (sur le même cœur de processeur de mon ordinateur portable), cela ressemble à ceci:



Si vous voulez influencer la trajectoire, augmentez la vitesse du vent:



Dévié de 16 cm, soit environ 0,3%. Que diriez-vous de viser directement le trébuchet? C'est facile à faire avec une descente de gradient, étant donné que nous avons des gradients. Cependant, il s'agit d'un processus itératif lent qui prend environ 100 ms à chaque fois. Au contraire, le fonctionnement d'un réseau de neurones prend 5 μs (vingt mille fois plus vite) avec une légère perte de précision. Cette astuce, appelée «inversion de fonction approximative par gradients», est très courante et peut être utilisée non seulement avec des systèmes dynamiques, mais aussi avec un algorithme de transfert de style rapide .


Il s'agit du problème de gestion le plus simple possible que nous utilisons principalement à des fins d'illustration. Mais nous pouvons appliquer les mêmes méthodes de manière plus avancée aux problèmes classiques de RL.


Chariot, rencontrer le pôle


Un défi de gestion plus reconnaissable est CartPole , le «Bonjour tout le monde» pour l'apprentissage par renforcement. Le défi est d'apprendre à équilibrer le pilier vertical en poussant sa base à gauche ou à droite. Notre configuration est généralement similaire à celle de Trebuchet: l' implémentation de Julia nous permet de considérer directement les récompenses reçues par l'environnement comme des pertes. ∂P nous permet de passer en toute transparence d'un modèle simple à un modèle RL.



Un lecteur astucieux peut remarquer un accroc. La zone d'action pour le plancher - un décalage vers la gauche ou la droite - est discrète et donc non différenciable. Nous résolvons ce problème en introduisant une discrétisation différenciable, définie comme suit :


f (x) = \ left \ {\ begin {matrix} \, 1, \, x \ geqslant0 \\ -1, \, x <0 \ end {matrix} \ right.


 fracdfdx=1


En d'autres termes, nous faisons en sorte que le dégradé se comporte comme si fétait une fonction identique. Étant donné à quel point l'idée mathématique de différentiabilité est déjà utilisée en ML, il n'est peut-être pas surprenant que nous puissions simplement tromper ici; pour l'entraînement, tout ce dont nous avons besoin est un signal pour informer notre marche pseudo-aléatoire autour de l'espace des paramètres, et le reste, ce sont les détails. Les résultats parlent d'eux-mêmes. Dans les cas où les méthodes RL doivent être formées sur des centaines d'épisodes avant de résoudre le problème, les modèles ∂P n'ont besoin que d'environ 5 épisodes pour finalement gagner.



Le pendule et le backprop à travers le temps


Un objectif important pour le RL (apprentissage par renforcement) est de gérer la rémunération différée lorsqu'une action ne nous aide pas à améliorer les résultats de plusieurs étapes consécutives. Lorsque l'environnement est différenciable, ∂P permet de former l'agent à la rétropropagation dans le temps, comme dans un réseau récursif! Dans ce cas, l'état de l'environnement devient un «état caché» qui change entre les pas de temps.



Pour démontrer cette technique, nous considérons un modèle de pendule , où la tâche consiste à faire pivoter le pendule jusqu'à ce qu'il soit debout et à le maintenir en équilibre instable. C'est difficile pour les modèles RL; après environ 20 épisodes d'entraînement, le problème est résolu, mais souvent le chemin vers la solution n'est clairement pas optimal. En revanche, BPTT peut battre le classement des leaders RL dans un épisode de formation. Il est instructif d'observer le déroulement de cet épisode; au début de l'enregistrement, la stratégie est aléatoire et le modèle s'améliore avec le temps. Le rythme d'apprentissage est presque alarmant.



Le modèle est bien adapté pour l'usinage de n'importe quel angle initial et a quelque chose de proche de la stratégie optimale. Au redémarrage, le modèle ressemble à ceci.



Ce n'est que le début; nous obtiendrons un réel succès en appliquant le DP aux environnements avec lesquels RL est généralement trop difficile à travailler, où des simulations et des modèles riches existent déjà (comme dans la plupart des sciences de l'ingénieur et des sciences naturelles), et où l'interprétabilité est un facteur important (comme en médecine).


La carte n'est pas le territoire


Une limitation de ces modèles de jouets est qu'ils assimilent l'environnement d'apprentissage simulé à l'environnement de test; Bien sûr, le monde réel n'est pas différenciable. Dans un modèle plus réaliste, la simulation nous donne un modèle de comportement brut qui est affiné avec des données. Ces données informent, par exemple, des effets simulés du vent, ce qui, à son tour, améliore la qualité des gradients que le simulateur transmet au contrôleur. Les modèles peuvent même faire partie de la passe directe du contrôleur, ce qui lui permet d'affiner ses prévisions sans avoir à étudier la dynamique du système à partir de zéro. L'apprentissage de ces nouvelles architectures rendra les travaux futurs passionnants.


Coda


L'idée de base est que la programmation différenciable, dans laquelle nous écrivons simplement un programme numérique arbitraire et l'optimisons à l'aide de gradients, est un moyen puissant de créer de meilleurs modèles et architectures similaires à l'apprentissage en profondeur, en particulier lorsque nous avons une grande bibliothèque de programmes différenciables à portée de main. . Les modèles décrits ne sont que des aperçus, mais nous espérons qu'ils donneront une idée de la façon dont ces idées peuvent être mises en œuvre de manière plus réaliste.


Tout comme la programmation fonctionnelle implique de raisonner et d'exprimer des algorithmes à l'aide de modèles fonctionnels, la programmation différenciable implique d'exprimer des algorithmes à l'aide de modèles différenciables. La communauté d'apprentissage en profondeur a déjà développé de nombreux modèles de conception de ce type, par exemple, pour gérer les problèmes de gestion ou une structure de données cohérente et arborescente. Au fur et à mesure que la zone se développe, beaucoup plus sera inventé, et à la suite de ces programmes, même les architectures d'apprentissage en profondeur les plus avancées auront l'air grossières et arriérées.


Les références



Source: https://habr.com/ru/post/fr459562/


All Articles