Les ordinateurs sont vraiment loin d'être les seuls systèmes capables de traiter de l'information. Les ancêtres des calculettes, de simples automates mécaniques, furent les premiers à en être capables. Par la suite, ces automates furent remplacés par les circuits électroniques analogiques et numériques, d'abord non-programmables, puis programmables. Depuis, de nouveaux types de systèmes de traitement de l’information ont vu le jour, certains s'inspirant de la biologie. Par exemple, il existe des calculateurs non-programmables à base d'ADN, spécialisés pour des problèmes bien précis. Dans ce chapitre, nous allons nous intéresser aux architectures neuromorphiques, qui s'inspirent fortement du cerveau humain et du système nerveux. Elles se basent sur des réseaux de neurones matériels.
Les réseaux de neurones logiciels et matériels.
Les réseaux de neurones sont des systèmes capables d'apprendre presque seuls, à partir d'exemples. Les réseaux de neurones sont multiples, mais on peut distinguer ceux qui apprennent tout seuls de ceux qui ont besoin d'un enseignement humain. Les premiers sont appelés des "réseaux de neurones non-supervisés", alors que ceux qui ont besoin d'apprentissage sont appelés des "réseaux de neurones supervisés". Pour ces derniers, il faut donner des indications de catégorisation pour que le réseau de neurones arrive à faire son travail, voire corriger certaines de ses erreurs de départ. Pour les réseaux non-supervisés, le réseau de neurone peut apprendre tout seul à partir d'exemples et est capable de catégoriser de lui-même les entrées qu'on lui fournit. Ce genre d'apprentissage automatique (on dit aussi non-supervisé) est très efficace pour une grande classe d'applications : reconnaissance des visages, reconnaissance d'émotion, rétines artificielles, vidéo-surveillance intelligente, systèmes de contrôle de moteurs, etc.
Les réseaux de neurones logiciels.
En temps normal, les réseaux de neurones sont mis en œuvre par un logiciel, qui simule le fonctionnement d'un réseau de neurones. Au départ, les neurones simulés étaient simples, et cela suffisait. Mais par la suite, ces simulations ont vu apparaître des neurones de plus en plus sophistiqués, et des réseaux de neurones plus complexes. Mine de rien, la simulation logicielle d'un système nerveux, même simple, demande beaucoup de puissance de calcul. Par exemple, Markam, un des utilisateurs du supercalculateur Blue-gene a déclaré qu'il était capable de simuler seulement 50.000 neurones en temps réel biologique (à la même vitesse que ce qui se passe dans un vrai réseau de neurones). Pour simuler 1 millions de neurones, cela prendrait 8 à 10 fois plus de temps que le temps réel biologique, et serait réellement impraticable.
Les réseaux de neurones matériels.
Avec les technologies VLSI récentes, on peut créer des circuits électroniques capables de simuler des réseaux de neurones matériels. On peut ainsi créer des circuits électroniques qui fonctionnent comme un neurone, dans le sens où la tension et le courant à leurs bornes suit les mêmes équations que la tension de membrane d'un neurone. Même chose pour les synapses.
Divers projets de ce type avaient pour but avoué de simuler un ccerveau humain, ou du moins une portion de celui-ci, afin de faire avancer la biologie. On peut notamment citer les projets BrainScaleS, qui est à l'origine d'un circuit VLSI de 200000 neurones et 49 millions de synapses. On trouve aussi le projet Neurogrid du groupe de recherche "brain in silicon", de l'université de Stanford. Celui travaille sur la simulation du cortex, une région du cerveau qui contient des neurones spécialisés appelés neurones pyramidaux. Ce groupe de recherche a déjà crée une puce non-programmable : le câblage des synapses ne peut pas être modifié, mais les paramètres des synapses sont configurables. Enfin, certains chercheurs du MIT ont créé un simulateur matériel simulant quelques neurones, dans un but de recherche fondamentale sur le comportement des récepteurs endo-cannabinoide de la membrane des neurones. Plus connus, les projets Humain brain ou FACETS, financés par l'UE, sont des projets de simulation beaucoup plus récents, dont la presse a parlé.
Les accélérateurs d'applications d'intelligence artificielle.
D'autres puces ont été inventées pour servir non de simulateur biologique réaliste, mais d'accélérer les logiciels d'intelligence artificielle. Aussi, elles sont appelées accélérateur d'IA. Au niveau industriel, il y a quelques puces basées sur ce principe. Une entreprise du nom de CogniMem a déjà commercialisé un accélérateur neuromorphique comprenant trois couches de respectivement 256, 1024, et 16392 neurones. L'ensemble fonctionne à la fréquence de 27 Mhz. En 2014, IBM a sorti sa puce TrueNorth, utilisé dans le projet SyNAPSE du DARPA, ce dernier a permis de créer une carte accélératrice qui se connecte sur PC via un port US, qui contient 256 neurones, reliés entre eux par 262144 synapses. En 2017, Intel a sorti sa puce Loihi. Dans un autre registre, les cartes graphiques récentes incorporent des technologies pour accélérer les calculs d'IA. Par exemple, les cartes NVIDIA récentes incorporent des cœurs "Tensor Core" spécialisés dans les calculs matriciels, ces derniers étant fortement utilisés dans les réseaux de neurones logiciels.
Elles sont fortement différentes des précédentes, dans le sens où elles ne font pas les mêmes calculs. Là où les simulateurs de neurones implémentent des équations différentielle, les accélérateurs d'IA exécutent surtout un grande nombre de calculs arithmétiques en parallèle. Pour être plus précis, les accélérateurs d'IA font des calculs sur des matrices, essentiellement des additions et des multiplications matricielles, qui s'implémentent avec des additions et multiplications arithmétiques usuelles. Les accélérateurs l'IA sont spécialisés pour réaliser en parallèle un très grand nombre d'opérations MAD (une multiplication suivie d'une addition). Les processeurs récents ne sont pas capables de faire autant que calculs en parallèle que nécessaire, mais les cartes graphiques récentes le peuvent. Ce qui explique que les cartes graphiques récentes sont beaucoup utilisées comme accélérateurs d'IA. Mais quelques puces spécialisées ont aussi vu je jour, comme dit plus haut.
En soi, les circuits MAD ne sont pas compliqués, mais la difficulté tient à lire/écrire un grand nombre d'opérandes depuis la mémoire. La hiérarchie mémoire de ces accélérateurs est donc assez compliquée. On peut classer les accélérateurs en deux types : les architectures temporelles et spatiales. Les architectures temporelles lisent toutes les opérandes depuis une mémoire globale, avec éventuellement des caches ou des "local store" pour limiter la casse. Elles sont composées d'un grand nombre d'unités de calcul, de circuits de contrôle et d'une mémoire RAM de grande capacité. Les architectures spatiales sont composées d'un grand nombre de cœurs connectés entre eux et à la mémoire RAM. Chaque cœur a sa propre mémoire, ses propres circuits de contrôle et quelques unités de calcul.
Nous ne parlerons pas de ces accélérateurs dans ce chapitre. La raison est que ces architectures sont des architectures dites parallèles, qui effectuent un grand nombre d'opérations en même temps. Et nous verrons ces architectures à la fin du cours, dans les tous derniers chapitres. Nous n'avons pas, pour le moment, de quoi expliquer comment fonctionnent les accélérateurs d'IA.
L'implémentation matérielle d'un réseau de neurones.
Comme je l'ai dit, les architectures neuromorphiques simulent des neurones. Pour comprendre leur fonctionnement, nous sommes donc obligés de voir ce qu'est un neurone et une synapse. Préparez-vous : le cours de biologie arrive.
Rappels sur les neurones et synapses.
Les cellules du cerveau sont appelées des neurones. Il existe un grand nombre de neurones différents, qui se différencient par leur taille, leur forme, ou quelques autres paramètres. Mais tous ces neurones gardent malgré tout des points communs quant à leur forme. Par exemple, un neurone est composé de 4 parties :
Les neurones échangent des informations, codées par des influx nerveux, des sortes de "courants électriques" qui passent de neurones en neurones et se propagent à travers tout le système nerveux. Pour simplifier, les influx nerveux ne sont pas des courants électriques, mais des variations de la tension électrique de la membrane du neurone (la membrane d'une cellule est sa frontière entre intérieur et extérieur). Lorsque le neurone ne fait rien, une tension d'environ -70 millivolts est présente sur sa membrane. Lorsqu'un influx nerveux passe, cette tension augmente localement.
Les influx nerveux sont traités par les neurones, ce traitement étant particulièrement complexe. Pour simplifier drastiquement, le neurone fait la somme de tous les influx nerveux qui arrivent sur ses dendrites à un moment donné. Si cette somme dépasse un seuil fixé à l'avance, alors le neurone émet un influx nerveux sur son axone. Dans le cas contraire, il n'émet rien.
Le système nerveux est constitué d'un grand nombre de neurones, reliés entre eux par ce qu'on appelle des synapses. Une synapse connecte l'axone d'un neurone aux dendrites d'un autre. Les synapses ne sont pas fixes et peuvent se reconfigurer : de nouvelles synapses peuvent se créer, d'autres mourir, etc. De plus, l'efficacité d'une synapse à transmettre l'influx nerveux d'un neurone à un autre peut varier dans le temps. L'ensemble de ces phénomènes s'appelle la plasticité synaptique. Ce serait le mécanisme qui nous permettrait d'apprendre. Autant dire que simuler la plasticité est primordial pour obtenir des circuits qui apprennent tous seuls.
Pour faire simple, la majorité des phénomènes de plasticité synaptique sont des variantes de ce que l'on appelle la règle de Hebb : si deux neurones émettent des influx nerveux à peu près en même temps, la synapse qui les relie se renforce. D'autres formes de plasticité existent, et notamment la plasticité fonction du temps d'occurrence des impulsions, aussi appelée "plasticité par modulation temporelle" qui prend en compte le fait qu'un des deux neurones émet avant l'autre. Si l’émetteur émet avant le récepteur, la synapse se renforce. Si c'est le récepteur qui émet avant l'émetteur, la synapse s'affaiblit. Plus le temps entre les influx nerveux est long, moins l'effet renforçateur ou affaiblisseur sur la synapse est faible. Cette dernière forme est la plus utilisée dans les réseaux de neurone matériels. Avec des formes simples de plasticité à long terme, on pourrait aussi rajouter la potentialisation à long terme, la dépression à long terme, la facilitation, l'habituation, la sensibilisation, et quelques autres. Mais celles-ci ne sont pas encore implantées en matériel.
Implémentation d'un neurone sous la forme de circuits.
Simuler le véritable comportement d'un neurone ou d'une synapse coûterait vraiment beaucoup de circuits. À la place, les concepteurs de simulateurs logiciels et matériels utilisent des neurones simplifiés, dont la relation entre tension et courant (influx nerveux) est décrite par une équation relativement simple, et surtout approximative.
Le premier type de neurone se base sur un principe relativement simple : il modélise le principe qui est derrière la conduction de l'influx nerveux. Pour commencer, il faut savoir que l'influx nerveux n'est pas, comme on pourrait le croire, un courant électrique qui parcours l'axone et les dendrites. Les axones et les dendrites ne sont pas des câbles électriques. À la place, cet influx nerveux consiste en une onde de tension, qui se propage sur des segments d'axone, et éventuellement de dendrites (dans la suite, je ne parlerais que d'axone par simplicité).
Mais d'où sort cette onde de tension ? Simple : le neurone est une cellule comme une autre, dans laquelle l'intérieur et l'extérieur sont séparés par une membrane : la membrane plasmique. Des deux côtés de cette membrane, on trouve respectivement le milieu intra-cellulaire (dans la cellule), et extra-cellulaire (en-dehors de la cellule). Ces deux milieux sont composés d'une solution qui mélange de l'eau, diverses molécules, et surtout : quelques ions, des atomes de charge non-neutre. En conséquence, chacun de ces milieux est relativement conducteur. L'ensemble forme donc un ensemble formé de deux milieux conducteurs, séparés par une membrane isolante. Deux morceaux de conducteur séparés par un isolant, cela ressemble fortement à un composant électronique que l'on nomme le condensateur. Conséquence : la membrane se comporte comme un condensateur.
Des deux côtés de la membrane, les quantités d'ions ne sont pas les mêmes. Par exemple, les quantités de calcium, potassium, et sodium, changent suivant le côté de la membrane où l'on se place. Cela vient du fait que la membrane est percée par de nombreuses molécules qui servent de pompes. Ces pompes vont expulser les ions d'un côté de la membrane vers l'autre côté. Ces pompes vont fonctionner jusqu'à ce que la concentration en ions de l'autre côté de la membrane devienne trop forte. En conséquence, l'intérieur et l'extérieur sont chargés différemment, donnant naissance à une tension de repos, d'environ -70 millivolts. Ces pompes peuvent donc se modéliser comme une tension de repose fixe, de -70 millivolts à -30 millivolts (selon le neurone).
Lors de l'émission d'un influx nerveux, de petites portes moléculaires vont s'ouvrir dans la membrane, et vont laisser passer sélectivement certains ions, et pas les autres. Ainsi, on va trouver des portes pour le potassium, d'autres pour le sodium, etc. Ces portes, des canaux ioniques, vont donc plus ou moins laisser passer un courant d'ions. Conséquence : ceux-ci sont modélisés par des résistances variables, qui laisseront plus ou moins bien passer le courant. En supposant que seul un seul type d'ion puisse passer la membrane, on trouve alors un condensateur, et une seule résistance. Si on suppose que plusieurs types d'ions peuvent passer la membrane, alors on trouve un modèle plus complexe, composé de plusieurs condensateurs et résistances en parallèle. Si les ions choisis sont le potassium, le sodium, et le calcium, les résistances et condensateurs auront des conductances et capacités d'une certaine valeur : on trouve un modèle de type Hodgkin-Huxley.
Dans les deux cas, à partir de ces deux modèles de neurones, on peut obtenir une relation entre courant i et tension V qui a la forme d'une équation différentielle.
Simuler un neurone à partir de circuits analogiques usuels.
Les premières implémentations de neurones se basent sur des circuits analogiques. Cela vient du fait que dans les modèles de neurones, la tension évolue :
Or, simuler convenablement en matériel l'équation différentielle ne peut se faire convenablement avec des circuits numériques. Quoique, certains ont déjà essayés, avec parfois de bons résultats. Mais il est communément admis que l'analogique est roi pour ce genre de situations. Quoiqu'il en soit, on trouve grosso-modo trois morceaux de circuit dans la majorité des implémentations matérielles de neurones :
Il y a aussi quelques subtilités, mais on va simplement parler de l'essentiel. Le circuit qui simule le poids de la synapse peut se résumer dans le cas le plus simple à un simple multiplieur analogique. Mais la majorité des design créent un générateur d'impulsions, des fronts de tension dont la durée dépend de la tension d'entrée (l'influx nerveux).
Le circuit qui implémente l'équation différentielle de la membrane en dehors d'un potentiel d'action est conçu à base de résistances, de condensateurs, et éventuellement de bobines : n'importe quel électronicien vous dira que toute équation différentielle peut être modélisée par un circuit ne contenant que des sources de tension, des condensateurs, des bobines, et des résistances.
Quant au circuit de détection du dépassement de seuil et de génération du nouvel influx nerveux, un simple amplificateur opérationnel correctement configuré peut suffire. Mais il faut signaler que chaque influx nerveux doit remettre la tension du neurone à la valeur de repos, ce qui demande quelques modifications sur le circuit de l'équation différentielle (un simple interrupteur bien placé peut suffire avec certains designs).
Simuler un neurone à partir de memristors.
Une solution plus économique est en cours de développement : le memristor, un composant inventé récemment. Le memristor n'est pas un composant électronique bien précis, et divers modèles existent à ce jour, chacun d'entre eux ayant des comportements très différents. Ceux-ci peuvent être vus comme des résistances variables, avec quelques particularités. En conséquence, cette résistance a été renommée memristance, pour éviter les confusions. Si jamais du courant positif traverse un memristor, sa memristance augmente. Si le courant est négatif, elle diminue. En clair : ces composants ont une sorte de mémoire du courant qui les a traversés depuis leur initialisation. Pour rentrer dans les détails, la valeur de la memristance dépend de l'intégrale du courant qui est passé dans la memristance. Suivant les modèles de memristor, cette fonction varie énormément.
Les memristors permettent de modéliser fidèlement une synapse : il suffit de faire en sorte que les courants qui simulent un influx nerveux soient relativement courts. Grosso-modo, la memristance correspond au poids de la synapse.
Les architectures AER.
Les architectures neuromorphiques sont constituées d'un paquet de neurones et de synapses, mais elles ne sont pas toutes organisées de la même manière. On peut en distinguer deux types : les architectures totalement câblées, qu'on a vu précédemment, et les architectures AER où une seule synapse multiplexée pour tous les neurones. Évidemment, cela impose de traiter les influx nerveux simultanés un par un. Si la puce fonctionne à haute fréquence, le multiplexage ne se voit pas et l'architecture reste raisonnablement rapide. Cependant, qui dit simuler plusieurs synapses avec une seule pose un problème, vu que chaque synapse a son propre poids. Il faut donc ajouter de quoi retenir le poids des synapses individuelles que l'on simule avec la synapse unique. Cela demande d'ajouter une mémoire RAM, qui stocke des nombres entiers qui simulent les poids.
Ces architectures sont construites comme indiqué dans le schéma ci-dessous. Le fonctionnement est simple. Chaque neurone est numéroté avec une adresse. Quand un neurone décharge et émet un influx nerveux, l'encodeur détermine son adresse. Cette adresse sert à adresser la RAM, ce qui permet de récupérer le poids de la synapse. Le tout est traduit ensuite traduit en tension analogique par le convertisseur numérique-analogique. Ensuite, les neurones de destination sont adressés uns par uns, la tension précédemment convertie leur étant envoyée en entrée.
Pour gérer la plasticité par modulation temporelle, on peut ajouter des mémoires de type FIFO qui mémorisent les temps d'émission de chaque influx nerveux.
Reste qu'utiliser un seul gros plan de neurones bouffe du circuit, et qu'il faut tirer des fils à travers toute la puce. Et cela pose des problèmes, surtout pour un fonctionnement à haute fréquence. Pour limiter la casse, on peut casser le plan de neurones en sous-plans de neurones, reliés entre eux par des réseaux locaux.
Conclusion.
Si vous voulez un aperçu de l'état de l'art sur le sujet, voici des liens qui devraient vous intéresser :