Lorsque l’on parle de réseaux de neurones avec le grand public, il est souvent difficile de bien faire comprendre ce qu’il se cache derrière. Pour cause : le besoin d’expérimenter, de les rendre tangibles pour voir quel impact a un changement de poids ou de biais.

En dépit de ce besoin grandissant, les outils à notre disposition restent assez limités et souvent difficiles de lecture ou peu pratiques…

Aujourd’hui nous allons donc parler de Nengo, le simulateur de neurones le plus abouti, réaliste et gratuit du marché ! Avec lui, vous verrez notamment qu’il est possible de simuler toutes les parties du cerveau intervenant dans la reconnaissance de chiffres écrits à la main.

Après vous l’avoir présenté, nous vous proposerons de le mettre en oeuvre très facilement sur votre ordinateur ! Enfin, on vous parlera d’un excellent livre sur un modèle d’architecture du cerveau (plus précisément de la cognition), que l’on recommande à tous ceux intéressés par le sujet (neuroscientifiques, chercheurs, ingénieurs en IA…)

I. Nengo, qu’est-ce que c’est ?

(crédit : Nengo)

Logiciel à l’origine développé pour Matlab en 2003, Nengo qui signifie Neural ENGineering Object est un outil graphique avec une composante de scripting pour simuler de larges systèmes neuronaux.

Les possibilités offertes par Nengo sont très nombreuses, puisque vous pourrez notamment :

  • Créer des neurones ou des groupes de neurones
  • Les connecter, les additionner, multiplier, transformer, combiner, etc…
  • Mettre en place des systèmes mémoriels
  • Simuler des équations différentielles, des oscillateurs, tester l’attracteur de Lorentz
  • Travailler avec des vecteurs, les appliquer à la sémantique
  • Reconnaître des symboles, transformer, lier, délier, contrôler des caractères
  • Et bien d’autres choses encore  (là ce ne sont que des exemples du tutoriel)
nengo exemple transformation
A gauche, on peut placer nos objets et les configurer. A droite, on peut définir le comportement via un script python (crédit : Lambert Rosique, screenshot de Nengo)

Spaun, « moteur » sémantique

Vous doutez de la puissance d’un tel programme ? Nengo est le premier à avoir proposé une simulation du cerveau, avec son projet intitulé Spaun (Semantic Pointer Architecture Unified Network).

A l’aide de 2.5 millions de neurones, Spaun peut simuler les régions du cerveau suivantes : cortex préfrontal, ganglions de la base et thalamus. Grâce à ça, il sait alors reconnaître/retenir des chiffres, comprendre des suites et les dessiner (à l’aide d’un bras robotisé) !

Le programme a d’ailleurs fait l’objet de nombreux articles depuis 2012 et n’a cessé de se perfectionner.

II. Installation de Nengo, le simulateur de cerveau

Habitués de Python, rassurez-vous, l’installation est très simple puisque Nengo tourne dans votre navigateur !

Commencez par installer Python 3 si ce n’est pas déjà fait.

Ensuite, il faut installer Nengo et Nengo GUI (pour avoir accès à l’interface graphique) via pip. Dans l’invite de commande Windows (remplacez pip par pip3 si vous utilisez Python sans Anaconda) :

pip install nengo nengo_gui

Il se peut que vous ayez besoin de Numpy, donc si besoin saisissez (avant !) la commande suivante :

pip install numpy

Et voilà, vous êtes prêts ! Pour lancer Nengo, saisissez dans l’invite de commande :

nengo

Votre navigateur (Firefox) devrait s’ouvrir à l’adresse suivante : http://localhost:8080/?filename=..\..\Program%20files\anaconda3\lib\site-packages\nengo_gui\examples\default.py

Premiers pas et exemples de réseaux de neurones

nengo default
(crédit : Lambert Rosique)

Si tout s’est bien passé, vous devriez arriver dans votre navigateur sur un projet par défaut. L’interface se découpe en deux parties : à gauche vous avez vos objets tangibles, et à droite vous avez la partie scripting.

En haut à gauche, vous pouvez cliquer sur le petit dossier puis sur built-in examples et choisir un fichier .py dans tutorial.

nengo tutoriels
(crédit : Lambert Rosique)

Ces derniers sont très bien faits, et je vous invite d’ailleurs à tous les suivre.

Si vous ouvrez le premier, 00-intro.py, vous verrez dans la partie scripting apparaître des commentaires qui vous expliqueront le fonctionnement !

Vous apprendrez notamment que le bouton Play en bas à droite permet de lancer la simulation et de voir les neurones interagir entre eux.

Notre propre réseau

L’objet premier de cet article était de découvrir ensemble à quoi ressemble, concrètement, trois neurones connectés dans un perceptron.

Commencez par ouvrir default.py (dans built-in examples) et enlevez le code de droite pour ne laisser que

import nengo

model = nengo.Network()

Toute l’interface graphique devrait disparaître de l’écran, puisqu’elle repose en intégralité sur le script.

On va tout d’abord mettre un « stim » qui représente une valeur d’entrée (un signal), et un groupe de neurones. On va ensuite les relier entre eux, le tout grâce au code suivant :

with model:
    stim_a = nengo.Node(0)
    a = nengo.Ensemble(n_neurons=50, dimensions=1)
    nengo.Connection(stim_a, a)
  • Stim est un noeud d’entrée
  • a est le groupe de neurones que l’on vient de créer (on en a mis 50 mais vous pouvez changer cette valeur)
  • On a relié les deux objets grâce à Connection

Ensuite, pour que ce soit plus intéressant, on va afficher le slider du stim_a en faisant un clic droit dessus (interface graphique) et slider.

nengo par la pratique 1
(crédit : Lambert Rosique)

On va aussi afficher les graphes de sortie de chaque objet en faisant clic droit dessus puis values.

Enfin, cliquez sur Play (flèche vers la droite) en bas à droite de l’écran et réduisez le speed en bas à gauche. Si vous déplacez le curseur, vous verrez le graphe de stim_a évoluer, suivi par le groupe de neurones !

A noter que le groupe est simulé dans son intégralité, chaque neurone ayant un potentiel d’action avec des pics d’émission (libération). Vous pouvez contrôler ces paramètres via Spikes, Voltages, Firing pattern ou Set synapse (sur le graphe du groupe).

Vous avez tout suivi jusque-là ? Parfait. Créons un autre ensemble de neurones, b, qui servira de deuxième point d’entrée à notre perceptron.

Ensuite, on en crée un troisième, c, qui servira à relier les deux précédents.

ATTENTION : c n’a pas besoin de stim ! En effet, il n’y a pas de signal d’entrée à ajouter (il va récupérer la sortie de a et de b). De plus, c est de dimensions=2 car il reçoit deux input. Enfin, un paramètre radius est à ajouter : il représente le signal « total » qui peut arriver dans le neurone (ici, 2).

Voici le code jusqu’à présent :

import nengo

model = nengo.Network()
with model:
    stim_a = nengo.Node(0)
    a = nengo.Ensemble(n_neurons=50, dimensions=1)
    nengo.Connection(stim_a, a)

    stim_b = nengo.Node(0)
    b = nengo.Ensemble(n_neurons=50, dimensions=1)
    nengo.Connection(stim_b, b)
    
    c = nengo.Ensemble(n_neurons=200, dimensions=2, radius=2)
    nengo.Connection(a, c[0])
    nengo.Connection(b, c[1])

Pour finir, on va ajouter un groupe de neurones, d, qui sera responsable des calculs à opérer sur la sortie de a et de b (regroupés dans c) :

    # si somme seule
    d = nengo.Ensemble(n_neurons=50, dimensions=1, radius=2)
    # si sigmoide aussi
    # d = nengo.Ensemble(n_neurons=50, dimensions=1)

La particularité de d est que la Connection à c ne s’écrit pas comme les précédentes, puisqu’il faut appliquer deux fonctions : d’abord la somme de a et de b, pondérée, puis la fonction sigmoïde au résultat.

    def somme(x, w):
        return x[0]*w[0] + x[1]*w[1]

Remarque : si vous voulez tester la somme seule, lorsque vous affichez le graphe de d, vous pouvez changer le range à -2,2 pour voir la courbe complète. Pensez à le remettre à -1,1 et à enlever le radius lorsque vous utiliserez la sigmoïde.

Pour déclarer la sigmoïde, il faut ajouter l’import de la librairie math en haut, et définir une troisième fonction

    def sigmoid(a):
        return 1/(1+math.exp(-a))
        
    def perceptron(x):
        return sigmoid(somme(x))
        
    nengo.Connection(c, d, function=perceptron)
nengo par la pratique 2
Simulation d’un perceptron 2 input 1 output 0 hidden (crédit : Lambert Rosique)

Pour conclure, vous pouvez afficher les graphes et lancer la simulation. En faisant varier les valeurs d’entrée stim_a et stim_b, vous pouvez voir concrètement ce qu’il se passe à la sortie du perceptron ! La simulation est complète, vous devriez donc retrouver les résultats du TP sur le perceptron.

perceptron 1 couche 2 neurones
(crédit : Lambert Rosique)

Pour aller plus loin : trouvez le moyen de contrôler les poids via des sliders dans l’interface graphique !

En attendant, voici un exemple de perceptron à 1 couche cachée avec 2 neurones. Vous pourrez retrouver l’ensemble du code sur notre Github, comme à l’accoutumée.

Architecture de la cognition

Pour certains, avoir un support papier pour en apprendre davantage sur cet outil incroyable et sur tout ce qui se cache derrière est un plus.

Dans Nengo, vous verrez qu’en cliquant sur le petit dossier en haut à gauche, dans built-in examples, vous avez accès au répertoire hbb_tutorials. Ce dernier contient de nombreux tutoriels qui sont tous issus du même livre, que je vous conseille vivement d’acheter.

How to Build a Brain – A Neural Architecture for Biological Cognition, de Chris Eliasmith, est un livre de quasiment 500 pages datant de 2013 et publié par Oxford. Entièrement en anglais (attention donc si vous le voulez), il explore tous les mécanismes sous-jacents à la pensée humaine et va jusqu’à proposer une architecture « Semantic Pointer » axée sur la cognition (lecture, écriture par exemple).

Ce livre est conseillé pour tous les neuroscientifiques, les psychologues, ou toute personne travaillant dans l’intelligence artificielle, car il pose des bases solides (qui sont le cœur de Nengo et Spaun) pour toute réflexion future sur la modélisation du cerveau.

Crédit de l’image de couverture : Lambert Rosique, screenshot du programme Nengo.