- Pour comprendre les rĂ©seaux de neurones, il n’est pas indispensable, contrairement aux idĂ©es reçues, de disposer d’un background mathĂ©matique très Ă©levĂ©. Le niveau du LycĂ©e suffit. Si vous avez compris l’Ă©quation de la droite et la rĂ©gression linĂ©aire, alors vous comprendrez les rĂ©seaux de neurones.
C’est ce que cet article tente de dĂ©montrer.
Cet article s’appuie sur le cours (GCP) de Jeremy Howard @jeremyphoward, sur celui de Rachel Thomas @math_rachel et celui de la Khan Academy.
L’Ă©quation d’une droite est : y = ax + b
a est la pente de la droite (ou son coefficient directeur) et b est l’ordonnĂ©e Ă l’origine.
On va dans cet exercice, après avoir créé un nuage de points ayant approximativement la forme d’une droite, chercher les paramètres de la droite (a, b) qui approchent au mieux ce nuage de points par une droite des moindres carrĂ©s.
y = ax + b, on remplace a par a1 et b par a2 (a2=b), donc on obtient y = a1x + a2 (on sait que a2 = a2*1) donc si X est une matrice dont la 2ème colonne est à 1 (pour b) alors on peut écrire : y = a_{}1 x_{}1 + a_{}2 x_{}2 et même ou plus généralement \vec{y} = X \vec{a} (produit matriciel)
Quelques notions
Multiplication de matrices
Python a introduit l’opĂ©rateur @
dans la version 3.5. Cet opérateur permet de multiplier des matrices.
PEP 465 introduced the
https://alysivji.github.io/python-matrix-multiplication-operator.html@
infix operator that is designated to be used for matrix multiplication. The acceptance and implementation of this proposal in Python 3.5 was a signal to the scientific community that Python is taking its role as a numerical computation language very seriously
import numpy as np
A = np.matrix('3 1; 8 2')
B = np.matrix('6 1; 7 9')
A @ B
Code language: JavaScript (javascript)
matrix([[25, 12],
[62, 26]])
Code language: CSS (css)
Tenseur
n=100 x = torch.ones(n,2)
Returns a tensor filled with the scalar value 1, with the shape defined by the variable argument
https://pytorch.org/docs/stable/torch.htmlsizes
.
Tout d’abord on crĂ©e un tenseur de shape (forme) 2 (en clair, une matrice). Ce tenseur est initialisĂ© Ă 1.
Ensuite, on remplace la colonne 1 par un nombre aléatoire compris entre -1 et 1.
x[:,0].uniform_(-1.,1)
Code language: CSS (css)
Fills
https://pytorch.org/docs/stable/tensors.html#torch.Tensor.uniform_self
tensor with numbers sampled from the continuous uniform distribution:
x[:5]
tensor([[ 0.1205, 1.0000],
[ 0.1748, 1.0000],
[ 0.9000, 1.0000],
[-0.4400, 1.0000],
[ 0.6781, 1.0000]])
Code language: CSS (css)
Bruit
Returns a tensor filled with random numbers from a uniform distribution on the interval [0,1]https://pytorch.org/docs/stable/torch.html?highlight=torch%20rand#torch.rand
Pour créer un vecteur de n (100) nombres aléatoires.
torch.rand(n)
Code language: CSS (css)
Nuage de points
On crĂ©e le nuage de points par calcul matriciel. On initialise a (notre paramètre). C’est un vecteur de 2 lignes * 1 colonne. On a donc un vecteur [3, 2}
a = tensor(3.,2);
On fait le produit de la matrice de dimension (100,2) par le vecteur (2,1), ce qui nous donne un vecteur de dimension (100)
y = x@a + torch.rand(n)

Notre nuage a cette forme :
plt.scatter(x[:,0], y);
Code language: CSS (css)

Gradient
On cherche la valeur des paramètres de la droite, c’est Ă dire les poids (a et b). Ici c’est plus exactement a_{1} et a_{2} (car il comprend b, il a 2 valeurs)
Nous allons chercher la valeur des paramètres par itĂ©ration en comparant l’Ă©cart entre les rĂ©sultats calculĂ©s et les valeurs connues. Pour cela, il nous faut une fonction de coĂ»t. On choisit comme fonction, la moyenne des carrĂ©s des Ă©carts.
fonction de coût
def mse(y_hat, y): return ((y_hat-y)**2).mean()
Code language: JavaScript (javascript)
Par exemple si :
a = tensor(-1.,1) y_hat = x@a mse(y_hat, y)
alors MSE (mean square error) =
tensor(6.2704)
Code language: CSS (css)
graphiquement on a :
plt.scatter(x[:,0],y)
plt.scatter(x[:,0],y_hat);
Code language: CSS (css)

calcul du gradient
On initialise a :
a = nn.Parameter(a)
On définit la fonction update() de la façon suivante :
def update():
y_hat = x@a
loss = mse(y, y_hat)
if t % 10 == 0: print(loss)
loss.backward()
with torch.no_grad():
a.sub_(lr * a.grad)
a.grad.zero_()
Code language: JavaScript (javascript)
- tout d’abord on calcule y_hat (la droite avec les nouveaux paramètres)
- ensuite on calcule l’erreur (la perte) loss
- on affiche cette perte toutes les 10 fois
- on calcule le gradient, c’est ce que permet backward()
- puis on on remplace a par sa valeur réduire du gradient multiplié par le learning rate
- et on remet Ă zero le gradient
gradient : Computes the gradient of current tensorÂ
https://pytorch.org/docs/stable/autograd.html?highlight=backward#torch.Tensor.backward
no.grad() Context-manager that disabled gradient calculation.
https://pytorch.org/docs/stable/autograd.html?highlight=no_grad#torch.autograd.no_grad
L’instructionÂ
https://docs.python.org/fr/3/reference/compound_stmts.html#the-with-statementwith
 est utilisĂ©e pour encapsuler l’exĂ©cution d’un bloc avec des mĂ©thodes dĂ©finies par un gestionnaire de contexteÂ
La fonction Ă©tant dĂ©finie, il ne reste qu’Ă boucler :
lr = 1e-1 for t in range(100): update()
résultat
plt.scatter(x[:,0],y)
plt.scatter(x[:,0],x@a);
Code language: CSS (css)

Animation
L’objet n’est pa de dĂ©crire ici matplotlib. Les informations sont minimales.
from matplotlib import animation, rc
rc('animation', html='jshtml')
Code language: JavaScript (javascript)
On initialise a, on définit la figure, on affiche le nuage de points, et la première droite.
a = nn.Parameter(tensor(-1.,1))
fig = plt.figure()
plt.scatter(x[:,0], y, c='orange')
line, = plt.plot(x[:,0], x@a)
plt.close()
Code language: JavaScript (javascript)
puis on itère
def animate(i):
update()
line.set_ydata(x@a)
return line,
animation.FuncAnimation(fig, animate, np.arange(0, 100), interval=20)
Code language: CSS (css)
Résumé
Si vous avez compris, la descente du gradient, alors sachez qu’un rĂ©seau de neurones fonctionne de la mĂŞme façon. On compare le rĂ©sultat calculĂ© avec celui qu’il devrait ĂŞtre grâce Ă une fonction de coĂ»t, on cherche de nouveaux paramètres qui minimise la fonction de coĂ»t, avec le calcul du gradient, puis on itère.
On a les étapes suivantes :
- intialisation des paramètres de notre modèle (ici une droite, a et b sont les paramètres)
- calcul des valeurs y_hat avec ces paramètres
- calcul du coût (erreur)
- minimisation de la fonction de coût, calcul du gradient
- mise Ă jour des paramètres a.sub_(lr * a.grad) en soustrayant le gradient multipliĂ© par le learning rate (pas d’apprentissage)
- itération