Université de Bordeaux, Master Mention Informatique

Intelligence Artificielle

Deep Learning, feuille 1

Présentation

Le but de ce premier TD est de vous familiariser avec les réseaux de neurones et leur entraînement. Nous allons passer en revue les éléments de base suivant :

  • données d'apprentissage,

  • fonction de perte (loss function)

  • descente de gradient

    Pour cela, nous allons utiliser un réseau de neurone (composé d'un seul neurone en fait) pour deux tâches :

    • une régression linéaire simple

    • une régression logistique.

Commençons par importer quelques unes des bibliothèques usuelles :

In [55]:
import numpy as np
import random as rd
import matplotlib.pyplot as plt
%matplotlib inline

import warnings
warnings.simplefilter('ignore')

On génère les données

Afin de réaliser une régression linéaire simple, nous allongs générer un nuage de points. Exécutez le code de la cellule suivante :

In [56]:
#Data: 
def generate(m, sizeNoise, slope, intersect):    
    x = [rd.random()*50 + 5 for i in range(m)]
    noise = [rd.random() * sizeNoise for i in range(m)]#np.rand(m,1) * sizeNoise
    y = [intersect + slope*x[i] + noise[i] for i in range(m)] 
    return np.array([x]), np.array([y])

m = 100
sizeNoise = 10
a = 0.8
b =  20
    
X, Y = generate(m, sizeNoise, a, b)
plt.grid()
plt.scatter(X, Y)
Out[56]:
<matplotlib.collections.PathCollection at 0x7ff0736bc0d0>

Exercice 1. Un neurone :

Comme vu en cours, un neurone formel est représenté comme suit :

Un neurone formel (Mc Culloch & Pitts (1943))

  1. Nommez chacun des élements du neurone.

  2. Ecrivez une fonction neuron(x, w, b, f) permettant d'implémenter ce neurone

In [ ]:
 
  1. Définissez deux fonctions id et sigmoid définies par : $$ id(z) = z \mbox{ et } sigmoid(z) = \frac{1}{1+ e^{-z}}. $$
In [58]:
 
  1. Testez vos fonctions. L'exécution de la cellule suivante devrait donner le résultat affiché.
In [59]:
x = np.array([[1, 2, 3]])
y = np.array([1, 0, 1])

w = np.array([1])
b = [1]
y_hat = neuron(x, w, b, id)
print('x: ', x)
print('y_hat: ', y_hat)
x:  [[1 2 3]]
y_hat:  [2 3 4]

Exercice 2. Régression linéaire :

Dans cet exercice, nous allons entraîner un neurone pour réaliser une régression linéaire simple.

  1. Dessiner le neurone qui sera utilisé. Identifiez bien les paramètres à trouver.

Il suffit de prendre $p=1$ et $f=id$ dans le neurone formel de la figure ci-dessus.

Les paramètres à trouver sont $w$ et $b$. Ils correspondent respectivement à $\beta_1$ et $\beta_0$ dans l'expression de la régression linéaire simple (voir votre cours de ACID).

  1. Ecrivez le code de la fonction loss(y, y_hat) définie comme la moyenne des carrés des écarts :
$$ loss\left(y, \hat{y}\right) = \frac 1 {n} \sum_{i=1}^n \left(\hat{y_i} - y_i)\right)^2. $$
In [ ]:
 
  1. Calculez le gradient de la fonction ${\cal L} = loss$ par rapport aux deux variables $w$ et $b$.
In [ ]:
 
  1. Ecrivez la focntion gradient(x, y_hat, y) retournant le gradient de la fonction $\cal L$.
In [61]:
 
  1. Ecrivez une fonction train(x, y, nu, epochs) qui réalise une déscente du gradient de la fonction $\cal L$ afin de trouver les paramètres $w$ et $b$ minimisant la valeur de $\cal L$.
In [62]:
 
  1. Entraînez votre neurone. Prenez $0.001$ comme valeur pour le pas d'apprentissage, et 10000 pour le nombre d'epochs.
In [ ]:
 
  1. Donnez l'équation de la droite de régression obtenue. Ecrivez l'instruction permettant de calculer les valeurs prédites.
In [64]:
 
  1. Dessinez la droite de régression sur la même figure que le nuage de point.
In [ ]:
 
  1. Comparez le résultat obtenu avec la droite donnée par linregress du sous module stats du module scipy.
In [ ]:
 
In [ ]:
 

Exercice 3. Régression logistique :

Dans cet exercice, nous allons transformer le neurone afin de l'utiliser pour réaliser une classification. Nous allons nous limiter à une classification bianire : les élements appartiennent soit à une classe 0 soit à une classe 1.

  1. Comment devons-nous appeler la "fonction" neuron pour que le fonction d'activation soit la sigmoid ?
In [68]:
 
x:  [[1 2 3]]
y_hat:  [0.88079708 0.95257413 0.98201379]
  1. Exécutez la cellule suivante pour générer les données, les découper en deux parties train et test, etc. Observez le résultat de la cellule.
In [69]:
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

X, y = make_classification(n_samples=1000, n_features=1, n_classes=2, 
                           n_informative=1, n_redundant=0, n_repeated=0,
                          n_clusters_per_class=1)

X_train, X_test, y_train, y_test = train_test_split(X, y)
print(X_train.shape)
print(y_train.shape)
print(np.unique(y))
(750, 1)
(750,)
[0 1]
  1. Définissez la nouvelle fonction de perte. Nous allons utiliser la fonction cross_entropy vue en cours :
$$ \cal L = -\frac 1 n \sum_{i=1} y_i\times \log\left(\hat{y}_i\right) $$
In [70]:
 
  1. Ecrivez les expressions mathématiques de ce que calcule votre neurone.
In [ ]:
 
  1. Calculez le gradient de $\cal L$ et écrivez la fonction correspondante
In [ ]:
 
In [71]:
 
  1. Adaptez une fonction train(x, y, nu, epochs) pour réaliser une déscente du gradient de la fonction $\cal L$ afin de trouver les paramètres $w$ et $b$ minimisant la valeur de $\cal L$.
In [72]:
 
  1. Exécutez la cellule suivante pour que vos calculs matriciels puissent se faire et entraînez votre neurone.
In [ ]:
X_train = np.reshape(X_train, (X_train.shape[1], X_train.shape[0]))
print(X_train.shape)
print(y_train.shape)
In [ ]:
 
  1. Evaluez votre modèle. Pour cela :

8.1. Exécutez la cellule suivante pour formater les données de test.

In [75]:
X_test = np.reshape(X_test, (X_test.shape[1], X_test.shape[0]))

8.2. Appliquez votre neurone aux données de test et observez le résultat obtenu.

In [ ]:
 

8.3. Transformez les sorties en 0 et 1 :

In [ ]:
 

8.4. Evaluez la qualité du modèle obtenu

In [ ]:
 
In [ ]:
 
In [ ]: