• 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 @ 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

https://alysivji.github.io/python-matrix-multiplication-operator.html
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 sizes.

https://pytorch.org/docs/stable/torch.html

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 self tensor with numbers sampled from the continuous uniform distribution:

https://pytorch.org/docs/stable/tensors.html#torch.Tensor.uniform_
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)
Produit Matriciel

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 with est utilisĂ©e pour encapsuler l’exĂ©cution d’un bloc avec des mĂ©thodes dĂ©finies par un gestionnaire de contexte 

https://docs.python.org/fr/3/reference/compound_stmts.html#the-with-statement

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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *