Aller au contenu principal

Réseau de neurones

· 4 minutes de lecture
Patrick Singcaster
Parachutiste & Programmeur

Introduction aux réseaux de neurones.

L'intelligence artificielle comporte une multitude de domaines, dont l'apprentissage machine (machine learning).

L'une des techniques de ce domaine est l'apprentissage profond (deep learning), et celle-ci utilise des réseaux neuronaux pour certains types d'apprentissages.

Neurone

Au départ, les chercheurs en informatique se sont inspirés du cerveau humain pour tenter de reproduire son fonctionnement artificiellement.

En 1943, McCulloch et Pitts ont établis les bases des premiers neurones artificiels.

Biologie

En simplifiant énormément, un neurone biologique comporte trois éléments principaux :

Neurone

Le somma (noyau) reçoit des impulsions électriques de ses dendrites (entrées). Selon l'intensité des impulsions reçues, le somma transmet, ou pas, une impulsion électrique par son axone (sortie). Les synapses, quant à elles, permettent de lier les axones aux dendrites afin de former un réseau.

Programmation

On peut aussi visualiser un neurone comme étant une fonction (soma), qui reçoit des paramètres (dendrites), et retourne un résultat (axone).

Réseau

En 1958, Frank Rosenblatt lie des neurones de façon à crée le plus ancien, et le plus simple, des réseaux neuronaux: le perceptron.

Rosenblatt va un peu plus loin que McCulloch et Pitt, en ajoutant une notion de poids aux calculs.

Perceptron

Un réseau neuronal de type perceptron contient (S) neurones, chacunes liées à (D) entrées, et produit (A) sorties. De plus, les synapses reliant les neurones possèdent maintenant un poids :

Perceptron

Couches

On nomme « couche cachée » les neurones entre les entrées et les sorties. Si le réseau perceptron est simpliste, il permet aussi de résoudre que des problèmes relativement simples. Pour résoudre des problèmes plus complexes, plusieurs couches cachées peuvent être ajoutées :

Couches

Propagation

On nomme « propagation avant (feedforward) » les calculs qui sont effectués entre les couches cachées.

Toute l'information se dirige dans le même sens: des noeuds d'entrés, par les noeuds cachés, jusqu'aux noeuds de sorties.

Calculs

Chaque neurone fera une somme pondérée des poids des synapses avec les données d’entrée afin d'estimer un rendement :

Pondération

Activation

Pour déterminer l'activation de chacun des neurones, il existe une multitude de fonctions telles Linéaire, Seuil, Sigmoïde, ReLU, etc., ayant chacune leurs spécificités :

Sigmoïde

Rétropropagation

En 1974, Paul Werbos est l'un des premiers à observer l'application de la rétropropagation (backpropagation) au sein des réseaux neuronaux.

C'est cette technique qui permettra au réseau neuronal de s'ajuster, en apprenant de ses erreurs.

Coût

On nomme « coût » la gravité de l'erreur commise. Ce coût est calculé à partir du résultat obtenu versus le résultat attendu.

Tout comme la fonction d'activation, il existe une multitude de fonctions de coûts selon les besoins.

Ajustement

Le coût permettra de calculer les ajustements, que l'on nomme « gradient », à apporter au poids de chaque synapse.

Exemple

Exemple simpliste d'un réseau neuronal, de type perceptron, afin d'apprendre un opérateur logique :

import numpy as np

def sigmoid(x):
return (1 / (1 + np.exp(-x)))

# Réseau de neurones
neuronesA = np.vstack(([0, 0], [0, 1], [1, 0], [1, 1]))
synapsesA = np.random.rand(2, 16)
neuronesB = []
synapsesB = np.random.rand(16, 1)
neuronesC = []

# Résultats attendus pour l'opérateur logique ET
resultats = np.vstack(([0], [0], [0], [1]))

# Apprentissage
for i in range(1000000):
# Propagation avant
neuronesB = sigmoid(np.dot(neuronesA, synapsesA))
neuronesC = sigmoid(np.dot(neuronesB, synapsesB))
# Gravité des erreurs
graviteErreurs = (neuronesC - resultats) * neuronesC * (1 - neuronesC)
# Propagation arrière
gradiantB = 2 * np.dot(neuronesC.T, graviteErreurs)
gradiantA = 2 * np.dot(neuronesA.T, np.dot(graviteErreurs, synapsesB.T) * neuronesB * (1 - neuronesB))
# Ajustement des poids
synapsesB = synapsesB - gradiantB
synapsesA = synapsesA - gradiantA

# Prédictions
for i in range(4):
print(neuronesA[i], round(neuronesC[i][0], 0))