# Fonctionnement d'un ordinateur/Les architectures neuromorphiques

La recherche n'hésite pas à s'inspirer de tout et n'importe quoi pour créer de nouvelles manières de faire des calculs. Par exemple, des systèmes de traitement de l’information s'inspirant de la biologie ont vu le jour. Il existe des calculateurs non-programmables à base d'ADN, spécialisés pour des problèmes bien précis. Et il y a aussi des ordinateurs plus ou moins inspirés du fonctionnement du cerveau humain. Dans ce chapitre, nous allons nous intéresser à deux choses : les réseaux de neurones matériels et les architectures neuromorphiques. Les deux s'inspirent fortement du cerveau humain et du système nerveux, surtout les architectures neuromorphiques.
Les réseaux de neurones sont des systèmes capables d'apprendre presque seuls, à partir d'exemples. L'intelligence artificielle moderne utilise ces réseaux de neurones. Les réseaux de neurones peuvent se classer en deux types : ceux qui apprennent tout seuls sont appelés des réseaux de neurones non-supervisés, alors que ceux qui ont besoin d'être aidés par un humain qui corrige leurs erreurs sont appelés des réseaux de neurones supervisés. 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.
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. Et il existe des accélérateurs d'IA capables d'accélérer les calculs des réseaux de neurones. De plus, dans ce chapitre, nous allons voir des exemples de réseaux de neurones implémentés en matériel. La différence entre accélérateurs d'IA et réseaux de neurones matérielles deviendra plus claire à la fin du chapitre. Mais pour le dire rapidement, l'IA a un but pratique où le résultat compte plus que le réalisme des réseaux de neurones implémentés. A l'opposé, les architectures neuromorphiques visent à se rapprocher du cerveau humain, elle vise à implémenter des réseaux de neurones proches des neurones réels, en espérant que cela permette d'obtenir de meilleurs résultats.
La différence se manifeste en pratique sur les neurones utilisés. L'intelligence artificielle actuelle et passée utilise surtout des neurones très simples, qui n'ont pas grand chose à voir avec les neurones biologiques. Il ne s'agit pas de simulations de neurones biologiquement réalistes. Pour faire la différence, nous parlerons de neurones artificiels. Les circuits pour simuler un neurone artificiel se résument à des circuits additionneurs/multiplieurs. Par contre, les neurones plus réalistes demandent des circuits beaucoup plus complexes, qu sont presque toujours analogiques.
Cette différence entre neurones très simples d'un côté et véritable simulation du tissu neuronal de l'autre, est une distinction qui va organiser ce chapitre. Nous allons d'abord voir des circuits basés sur des neurones simples, puis de véritables circuits neuromorphiques. Les deux seront séparés dans plusieurs sections différentes. Une première section va parler des anciens perceptrons matériels, suivi par une section sur les accélérateurs d'IA numériques, avant qu'une troisième section parle des véritables architectures neuromorphiques. En introduction de chaque section, on trouvera une introduction aux notions biologiques utiles.

## Les perceptrons et réseau de Hopfield : la théorie

Les premiers réseaux de neurone que nous allons aborder sont basés sur des neurones artificiels les plus simples qui puissent existe. Mais pour comprendre comment ils fonctionnent, il est intéressant de faire une analogie avec un vrai neurone. Même si les percetrons n'utilisent pas des neurones réalistes, ils s'inspirent de leur fonctionnement d'une manière superficielle. Et cette analogie se comprend bien à partir des vrais neurones.

### Rappels de base sur les neurones biologiques

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. Si on omet certaines classes de neurones un peu particulière, un neurone a une forme canonique en 4 parties. Les neurones de ce type, dit multipolaires, sont composés :
* d'une dendrite souvent en forme d'arbre, très touffue ;
* d'un soma, un corps cellulaire avec le noyau au milieu ;
* d'un axone avec un ensemble de boutons synaptiques à son extrémité.
Les neurones sont parcourus par des influx nerveux, des sortes de "courants électriques" qui passent de neurones en neurones et se propagent à travers tout le système nerveux. Le terme technique n'est pas '"influx nerveux", mais "potentiel d'action". Les potentiels d'action ne sont pas des courants électriques, comme on pourrait le croire. Ce sont des pics de tension qui parcourent le neurone sur ses dendrites, ou sur son axone.
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. La forme de ce pic de tension est illustrée ci-dessous. Il faut noter que les potentiels d'action sont tous les mêmes. L'amplitude de la tension est la même pour tous les potentiels d'action, elle ne varie pas, pas plus que la durée du potentiel d'action. On dit que ceux-ci sont en tout ou rien.
Un potentiel d'action se propage sur le neurone, que ce soit sur sa dendrite ou sur son axone, mais il peut aussi passer d'un neurone à l'autre. Pour cela, les neurones sont reliés entre eux par ce qu'on appelle des synapses. Une synapse connecte l'axone d'un neurone aux dendrites d'un autre. Le potentiel d'action est généré au milieu du neurone, dans la zone appelée le soma. Il se propage alors sur l'axone, qui sert en quelque sorte de câble de transmission du potentiel d'action. Là, l'axone entre dans la synapse et passer dans la dendrite d'un autre neurone. Il se propage alors sur la dendrite et arrive au soma. Au niveau du soma, il donne éventuellement naissance à un nouveau potentiel d'action sur l'axone.
Pour simplifier drastiquement, le soma fait la somme de tous les potentiels d'action qui arrivent sur ses dendrites à un moment donné. Si cette somme dépasse un seuil fixé à l'avance, alors le neurone émet un potentiel d'action sur son axone. Dans le cas contraire, il n'émet rien.
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 les potentiels d'action varie 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.

### Les neurones artificiels d'un perceptron

Un perceptron utilise des neurones simplifiés. Les neurones simplifiés sont appelés des neurones artificiels, aussi appelés des perceptrons. Leur fonctionnement copie le fonctionnement basique d'un neurone, mais appliqué au domaine numérique. Si les neurones sont fondamentalement analogiques, les neurones artificiels en sont une sorte d'équivalent numérique.
Le potentiel d'action est un pic de tension foncièrement analogique dans les détails, mais qui a un comportement en tout ou rien. Pour rappel, tous les potentiels d'action sont identiques, leur durée et leur tension est tout le temps la même. Ce comportement en tout ou rien du potentiel d'action est simulé en codant un potentiel d'action par un bit : 0 en absence de potentiel d'action à un instant t, 1 en cas de survenue d'un potentiel d'action. Cela permet d'utiliser un encodage non seulement numérique, mais aussi binaire, ce qui nous arrange bien.
Un neurone est donc simulé par un circuit qui prend en entrée un ou plusieurs bits, et fournit en sortie un ou plusieurs bits. Pour gérer son interface, les neurones artificiels s'inspirent de la forme d'un neurone avec des dendrites et un axone. Ils ont donc plusieurs entrées et une seule sortie : la sortie unique représente l'axone, il y a une entrée par dendrite. Pour simplifier, ils reçoivent des bits sur leur entrée et fournissent un bit en sortie. Les bits d'entrées représentent les potentiels d'action reçus par le neurone, le bit de sortie indique si le neurone a émis un nouveau potentiel d'action.
Le fonctionnement d'un neurone simplifié vu précédemment est assez simple. Il fait la somme de tous les potentiels d'actions qui arrivent sur ses dendrites, et émet un potentiel d'action si la somme dépasse un certain seuil. Ce comportement est directement reproduit par un neurone artificiel : il fait la somme de ses entrées et compare la somme à un seuil.
Le plus compliqué est de simuler la plasticité synaptique. Pour cela, on suppose que celle-ci vient d'une évolution de la sensibilité des synapses. Elles laissent plus ou moins bien passer les potentiels d'action. Pour simuler cela dans un neurone artificiel, les bits d'entrées sont multipliés par un coefficient multiplicateur, appelé le poids de la synapse, qui représente la sensibilité d'une synapse. Il y a un poids différent par synapse, donc un coefficient différent par entrée.
Pour résumer, les bits d'entrée sont multipliés par un coefficient multiplicateur, qui est un nombre à virgule flottante ou entière. Les résultats des multiplications sont additionnés entre eux, pour simuler l'action du soma du neurone, son corps cellulaire. Puis le résultat passe dans une fonction qui transforme la somme en un bit de sortie, qui représente le potentiel d'action produit par le neurone. La fonction est une simple comparaison entre la somme et un seuil configurable.
Pour résumer, un neurone artificiel effectue le calcul suivant :
    ${\text{Sortie}}=f\left[\sum ^{i}(a_{i}\times w_{i})\right]$, avec $w_{i}$ les poids de chaque synapse et f une fonction qui calcule le bit de sortie.
Une alternative ajoute un biais à la somme précédente :
    ${\text{Sortie}}=f\left[\sum ^{i}(a_{i}\times w_{i})+{\text{biais}}\right]$, le biais étant une sorte de seuil ajouté.
Implémenter un neurone artificiel est assez simple : il suffit de circuits multiplieurs pour les poids, d'un additionneur pour le soma et d'un comparateur pour la sortie. Et les trois peuvent s'implémenter de manière soit purement numérique, soit analogique. Les implémentations numériques sont généralement des circuits de calcul flottants basiques. Les implémentations analogiques utilisent souvent des circuits basés sur des amplificateurs opérationnels, ou quelque chose d'approchant.

### Les règles d'apprentissage : la Perceptron Learning Rule

L'apprentissage se fait en faisant évoluer les poids dans le temps. Les poids évoluent quand l'utilisateur indique que le réseau fournit une mauvaise réponse. Pour cela, il existe plusieurs règles d'apprentissage qui décrivent comment les poids doivent évoluer. Mais elles dépendent beaucoup du perceptron utilisé. La règle d'apprentissage est intégrée dans le neurone. Généralement, les poids des synapses sont mémorisés quelque part, dans un circuit spécialisé. Un circuit spécialisé lit ces poids et les modifie, ce qui permet de modifier les poids. Le calcul réalisé par ce circuit varie grandement selon la règle d'apprentissage utilisée.
Une règle d'apprentissage simple est la suivante, appelée la Perceptron Learning Rule (PLR). L'idée est que les poids sont adaptés en cas d'erreur, en fonction de l'entrée. En premier lieu, on compare la sortie attendue et celle fournie par le perceptron, on calcule la différence. La différence vaut 0, 1 ou -1. Elle vaut 0 si le perceptron a raison. Elle vaut 1 si le perceptron a sorti un 0 alors qu'on attendait un 1, elle vaut -1 dans le cas inverse. Cette différence dit s'il faut augmenter ou réduire les poids. Reste à savoir de quel montant.
Une idée serait d'additionner ou soustraire une valeur fixe, mais ce ne serait pas une bonne idée. Une méthode plus efficace additionne ou soustrait une valeur qui est proportionnelle à l'entrée. Ainsi, les synapses avec un bit d'entrée à 1 sont modifiées, pas celles où le bit d'entrée est à 0. Pour cela, les poids sont rassemblés dans un vecteur, les bits de l'entrée sont rassemblés dans un autre vecteur. L'idée est de multiplier le vecteur d'entrée par un coefficient multiplicateur et de l'ajouter/soustraire au vecteur des poids. Le coefficient multiplicateur est choisit assez petit pour faire converger le réseau lentement, afin que les résultats finaux soient assez précis.
Il y a trois cas, qui sont résumés dans les formules suivantes. On note $\eta$ le coefficient, $x_{i}$ le bit envoyé sur l'entrée i, $\Delta w_{i}$ ce qu'on ajoute/soustrait au poids de la synapse.
    $\Delta w_{i}=0$ : si le perceptron ne s'est pas trompé.
    $\Delta w_{i}=\left(\eta \times x_{i}\right)$ : si le perceptron sort un 1 au lieu d'un 0.
    $\Delta w_{i}=-\left(\eta \times x_{i}\right)$ : si le perceptron sort un 0 au lieu d'un 1.
Le tout cela est résumé avec la formule suivante, en notant D la différence calculée :
    $\Delta w_{i}=\left(\eta \times x_{i}\right)\times D$

### Les perceptrons et autres réseaux de neurones artificiels

Maintenant que l'on a un neurone artificiel, il faut les interconnecter entre eux pour obtenir un réseau de neurones. Pour cela, il y a plusieurs méthodes. La plus simple d'entre elle place plusieurs neurones les uns à côté des autres, sans les relier. On dit alors qu'il y avait une seule couche de neurones. Quelques machines fonctionnaient sur ce principe, comme l'ADALINE, qu'on verra plus bas.
Mais à part ces rares exceptions, les réseaux de neurones disposent de plusieurs couches de neurones, connectées entre elles. Les réseaux de neurones les plus simples sont ceux utilisées ci-contre. Un tel réseau est appelé un perceptron. Ils ont deux à trois couches, chaque couche est connectée uniquement à la suivante.
Les perceptrons implémentent des classifieurs binaires, terme barbare pourtant simple à comprendre. Un classifieur binaire prend en entrée un exemple et dit si celui-ci appartient ou non à une catégorie précise. Par exemple, si on lui présente une photographie d'animal, le réseau sera entrainé pour dire si la photo est celle d'un chat ou non. Le résultat est toujours une réponse de type oui/non, d'où le terme binaire. Le résultat peut être représenté sous la forme d'un bit : 0 si la réponse est "faux", 1 pour un "vrai".
Le réseau de neurone est entrainé en lui présentant des exemples divers, mais il n'apprend pas tout seul. Un utilisateur doit l'entrainer en précisant si ses réponses sont bonnes ou non. Le réseau fournit une réponse à chaque exemple, l'utilisateur lui dit si sa réponse est bonne ou non. En fonction de la réponse de l'utilisateur, le réseau de neurone s'adapte et se modifie, il apprend.
D'autres réseaux de neurones autorisent des boucles dans le réseau, à savoir que la sortie d'un neurone est bouclée sur l'entrée d'un neurone précédent, dans une couche précédente. Les plus simples sont les réseaux de Hopfield. Sans rentrer dans les détails mathématiques très complexes de ce genre de réseaux, ils sont composés d'une à deux couches, dont l'une est bouclée sur elle-même. Chaque neurone émet un axone en direction de tous les autres neurones de la même couche.

## Les implémentations matérielle de perceptrons

Maintenant que nous avons vu la théorie, nous allons voir comment de tels réseaux de neurones peuvent être implémentés physiquement, dans un ordinateur, avec des circuits matériels. Nous allons voir quelques exemples d'architectures ayant existé dans le passé, dont le but était de réellement implémenter des neurones en silicium. Nous laissons de côté les puces accélératrices d'IA récentes, car elles fonctionnent d'une manière totalement différente.

### L'ADALINE et le MADALINE

Une implémentation d'un perceptron était l'ADALINE (Adaptive Linear Neuron or later Adaptive Linear Element). Elle était un bel exemple de circuit analogique. Si les entrées du circuit sont des bits, donc des données numériques, tout est converti à l’intérieur du neurone en tensions analogiques. D'ailleurs, la tension de sortie était analogique, avec une valeur allant de -1 à 1 volt. Et les bits d'entrées étaient codés avec une tension valant soit 1 volt, soit -1 Volt. Le réseau de neurone n'avait qu'une seule couche de neurones indépendants, comme illustré ci-dessous.
Les multiplieurs pour les poids étaient initialement implémentés par de simples potentiomètres, réglés par l'utilisateur.. Vu que c'était des potentiomètres, on pouvait faire varier le poids en les tournant. Le perceptron n'avait donc pas de circuit d'entrainement proprement dit, on devait régler les potentiomètres à la main, la machine ne pouvait pas faire varier les poids d'elle-même. Un biais était ajouté via un potentiomètre séparé, relié à une de ces entrées (le a0 dans le schéma ci-dessous).
Sur la façade de la machine, on trouvait 16 interrupteurs qui servaient à configurer ce qu'on envoyait sur l'entrée du perceptron. On trouvait aussi 16 potentiomètres pour les poids, ainsi qu'un potentiomètre pour configurer le biais. Niveau sortie, il y avait un cadran de voltmètre qui permettait de mesurer la tension de sortie du circuit. Et n'oublions pas le bouton pour allumer la machine
La seconde version de l'ADALINE était appelé la MADALINE (Memistor Adaptive Linear Neuron or later Adaptive Linear Element). Elle utilisait quant à elle trois couches de neurones successives.
La différence majeure avec l'ADALINE est que les potentiomètres des poids étaient remplacés par un composant appelé un memistor, capable d'une capacité de mémorisation. Memisoter qui ne doit pas être confondu avec le memristor, qui est un autre composant. L'avantage est que cela rendait la puce capable d'apprendre d'elle-même. Un algorithme d'apprentissage était intégré dans la machine, sans avoir besoin de régler les potentiomètres eux-mêmes. D'ailleurs, sur la facade de la machine, on trouvait 16 interrupteurs qui servaient à configurer les bits d'entrée du perceptron, mais les potentiomètres avaient disparus.
Pour information, Bernard Widrow, un des concepteurs de l'ADALINE/MADALINE, a publié deux vidéos youtube pour présenter son travail. Dans la seconde vidéo, il présente l'ADALINE et la MADALINE, montre comment elles fonctionnent, les manipules, etc. La première vidéo explique l'algorithme d'apprentissage utilisé dans la MADALINE. Voici un lien vers ces deux vidéos :
* The LMS algorithm and ADALINE. Part II - ADALINE and memistor ADALINE
* The LMS algorithm and ADALINE. Part I - The LMS algorithm

### La Mark I Perceptron machine

La première implémentation d'un perceptron était la Mark I Perceptron machine. Il s'agissait d'un projet de recherche datant de 1958, dirigé par Rosenblatt . Il s'agissait d'un réseau de neurones à trois couches, donc quelque chose de plus complexe que l'ADALINE.
La première couche n'appartenait pas au réseau de neurones proprement dit, mais convertissait les tensions provenant de 400 photodétecteurs en bits d'entrée. Les photodétecteurs étaient organisés en un carré de 20 capteurs de côté. La seconde couche avait 512 neurones artificiels, la troisième avait seulement 8 neurones artificiels. Les deux couches de neurones étaient appelées la couche d'association et la couche de réponse, abréviées A et R. Elles sont interconnectées via des potentiomètres, qui permettaient de configurer le poids de chaque connexion, de chaque synapse.
Rosenblatt, le directeur du projet, voulait simuler le cerveau humain. Dans ce perceptron, la rétine était l'équivalent de la couche de photorécepteur, les couches de neurone étaient l'équivalent du cortex visuel (la portion du cerveau qui s'occupe de la vision). Les deux couches étaient peu, comparé aux nombreuses couches du cortex visuel. Les connexions entre la couche de photorécepteurs et la suivante étaient aléatoires, car Rosenblatt était persuadé que la rétine était connectée aléatoirement au cortex visuel.

### L'ETANN d'Intel

L'ETANN (Electronically Trainable Analog Neural Network) était un des tout premiers processeurs neuronal, une des toutes première architecture neuromorphique à avoir existé. Elle a été annoncé en 1989 et a été commercialisée la même année. Elle gérait deux couches de 64 neurones chacune, interconnectés par 10240 synapses (80 synapses par neurone). Elle permettait 'implémenter un perceptron basique, avec cependant une option pour créer un réseau de Hopfield. La différence entre les deux étant que les sorties des neurones sont bouclées sur les entrées.
Les neurones restent implémentés avec des circuits analogiques, à savoir des amplificateurs analogiques configurés en montage sommateur, couplés à un circuit multiplieur (la rumeur dit que c'était un multiplieur différentiel de Gilbert à 4 quadrant). Le tout était suivi par 64 circuits pour générer les potentiels d'action (une fonction sigmoïde matérielle).
L'ETANN incorporait beaucoup de synapses, donc beaucoup de poids. Pour tous les gérer, Intel a du recourir à une solution assez élégante : mémoriser les poids dans une mémoire, séparée des autres circuits. Intuitivement, le choix aurait du porter sur une mémoire RAM, mais ils étaient en réalité mémorisés dans une mémoire EEPROM non-volatile. Les poids des synapses étaient des entiers en virgule fixe codés sur 8 bits, donc en binaire, pas en analogique. Avant d'être envoyés au neurone, les poids devaient être convertis en tensions analogiques, avec un convertisseur numérique-analogique dédié.
Le fait que les poids étaient mémorisés dans une EEPROM avait autant de défauts que de désavantages. Des avantages car il n'y avait pas besoin de circuits de rafraichissement, nécessaires pour les DRAM. Par contre, les changements de poids étaient lents, ce qui fait que la puce n'était pas très rapide. Et la quantité de reprogrammation était limitée à quelques dizaines ou centaines de millions de réécritures, au-delà lesquelles la EEPROM s'abimait. Mais une fois que le circuit avait été entrainé, il n'y avait plus besoin de changer les poids.
L'architecture de l'ETANN a été décrite dans deux articles, qui ne sont malheureusement plus facilement accesibles librement sur le net. Voici les noms de ces deux articles :
* "An electrically trainable artificial neural network (ETANN) with 10240 floating gate synapses."
* "Implementation and performance of an analog nonvolatile neural network."

## Les accélérateurs d'applications d'intelligence artificielle

Les architectures précédentes utilisaient toutes des neurones analogiques, au moins partiellement. La raison est qu'un circuit binaire équivalent aurait utilisé beaucoup de portes logiques. Imaginez : une dizaine/centaine de circuits multiplieurs, suivis par un circuit additionneur multiopérande. L'implémentation binaire aurait été très gourmande en portes logiques. Et ce même en utilisant des poids entiers, alors que les poids flottants codés sur 16/32 bits donnent de meilleurs résultats.
Cependant, ce n'est plus vraiment un problème de nos jours. La loi de Moore et la miniaturisation qui en découle ont changé la donne. Autant les ordinateurs des années 50-90 devaient faire avec un budget en transistor limité, autant les puces modernes peuvent parfaitement implémenter des neurones artificiels avec des circuits binaires. Et elles ne s'en privent pas, il existe de nombreuses puces dites accélératrices d'IA qui effectuent des calculs entiers/flottants pour émuler un neurone artificiel. Cependant, n'allez pas croire qu'elles implémentent des neurones directement en matériel, elles font autrement.

### La représentation matricielle d'un réseau de neurone

Les perceptrons sont des réseaux très simples, surtout comparé aux réseaux de neurones modernes. Ces derniers sont beaucoup plus complexes, avec plusieurs centaines de couches et des interconnexions très complexes entre elles. La majorité des applications d'intelligence artificielle utilise des réseaux de neurones de ce genre. Pour de telles applications, le réseau de neurone est implémenté en logiciel, avec une implémentation particulière.
Le réseau de neurone est représenté par une matrice. Les interconnexions entre neurones sont mémorisées dans des matrices, qui mémorisent le poids de chaque synapse. Les bits de sortie de chaque couche de neurone forment un vecteur, ce qui fait que les calculs se résument à multiplier des vecteurs d'entrée par une matrice de poids, pour obtenir le vecteur de sortie. Les accélérateurs d'IA sont conçus pour faire de tels calculs matriciels.
    Une telle représentation est liée au fait qu'un graphe peut être encodé par une matrice. Ici, le graphe formé par les neurones et leurs interconnexions est représenté par une matrice de connectivité, améliorée pour tenir compte des poids des synapses.

### Les accélérateurs d'intelligence artificielle

Des puces ont été inventées pour accélérer ces calculs matriciels, pour accélérer en priorité les logiciels d'intelligence artificielle. Aussi, elles sont appelées accélérateur d'IA. Elles sont fortement différentes des précédentes, dans le sens où elles n'implémentent pas des neurones en matériel, mais effectuent simplement des calculs matriciels. Là où les simulateurs de neurones implémentent des perceptrons, voire des équations différentielles, les accélérateurs d'IA font des calculs sur des matrices, qui contiennent des nombres flottants. Pour accélérer les calculs, elles utilisent souvent des flottants spécialisés, avec une faible précision, qui sont codés sur 16 bits, rarement 32.
Les accélérateurs d'IA exécutent quasi-exclusivement 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). 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.
Les accélérateurs l'IA sont spécialisés pour exécuter un très grand nombre d'opérations arithmétiques en parallèle. 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 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.
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, qui disposent chacun de sa propre mémoire associée. Les coeurs sont reliés entre eux par un réseau d'interconnexion complexe.

## Les architectures neuromorphiques

Passons aux architectures neuromorphiques. Avant toute chose, précisons que nous allons faire une séparation totalement arbitraire entre perceptrons matériels et architectures neuromorphiques. La séparation est liée à l'implémentation du neurone. Les architectures précédentes se contentent de neurones simples, très simples, qu'on peut émuler avec des multiplieurs-additionneurs. Mais les architectures neuromorphiques utilisent des neurones plus réalistes, plus complexes. Elles cherchent à simuler le cerveau humain, à être réaliste au point de vue cellulaire.
Les architectures neuromorphiques mélangent circuits numériques et circuits analogiques. Les poids des synapses sont mémorisés dans une mémoire RAM, alors que les neurones sont implémentés en analogique. Pour faire l'interface entre les deux, le circuit intègre des circuits de conversion analogique-numérique, ainsi que des circuits de conversion inverse, entre la mémoire et les neurones/synapses. Il n'y a pas le choix, les modèles réalistes des neurones se basent sur des équations différentielles dont l'implémentation est beaucoup plus simple en analogique. Surtout que l'on a pas besoin d'une précision importante et que l'imprécision des circuits analogiques n'est alors pas un problème. Les architectures neuromorphiques sont donc des circuits hybrides analogiques-numériques.
Si vous voulez un aperçu de l'état de l'art sur le sujet, voici des liens qui devraient vous intéresser :
* Neuromorphic silicon neuron circuits
* A Survey of Accelerator Architectures for Deep Neural Networks

### Historique partiel des architectures neuromorphiques

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.
Mais 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 qu'un neurone. Ce n'est pas la première fois que des chips matériels sont créés pour accélérer des simulations très spécifiques. Il existe par exemple des systèmes matériels spécialement conçus pour les simulations physiques de champ électriques ou gravitationnels, comme le projet GRAPE.
Quelques puces neuromorphiques ont vu le jour. 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ée 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. La puce TrueNorth contient 4096 coeurs, chacun contient 256 neurones, reliés entre eux par 262144 (256*256) synapses.
* En 2017, Intel a sorti sa puce Loihi.
D'autres projets d'architectures neuromorphiques avaient pour but avoué de simuler un cerveau humain, ou du moins une portion de celui-ci, afin de faire avancer la biologie. Le projet BrainScaleS est à l'origine d'un circuit VLSI de 200000 neurones et 49 millions de synapses. 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éé 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.

### La modélisation théorique d'un neurone et d'une synapse

Comme dit plus haut, les architectures neuromorphiques utilisent des neurones artificiels assez réalistes. Aussi, vous ne serez pas étonnés d'être obligés de voir ce qu'est un neurone et une synapse en détail avant de poursuivre. Préparez-vous : le cours de biologie arrive.
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 :
* soit via une équation différentielle ;
* soit, un potentiel d'action a lieu, faisant passer celle-ci à son maximum.
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 :
* un circuit qui simule "le poids de la synapse", sa sensibilité aux influx nerveux entrants ;
* un circuit "mémoire", qui stocke l'état actuel de la tension, en faisant varier celle-ci par l'équation différentielle du modèle.
* et un circuit qui détecte le dépassement du seuil, et émet un influx nerveux.
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).
Une solution plus silmple conceptuellement utilise des memristor, un composant en cours de développement. Le memristor n'est pas un composant électronique bien précis, et divers modèles théoriques 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.