Régression linéaire en utilisant tensorflow

Remarque

Cet exemple est dans la documentation de TensorFlow .

Cet exemple est décrit dans cette vidéo (de 19m33s à 27m53s).

Régression linéaire avec tensorflow 2.0 en utilisant GradientTape

Régression linéaire avec tensorflow 2.0 en utilisant GradientTape

MéthodeÉcrire un programme en TensorFlow

Le programme que nous allons écrire utilise tensorflow et est écrit en python.

ExempleRégression linéaire

Un modèle de régression linéaire est un modèle de régression qui cherche à établir une relation linéaire entre une variable y, dite expliquée, et une ou plusieurs variables x, dites explicatives : On parle aussi de modèle linéaire ou de modèle de régression linéaire.

1
import tensorflow as tf
2
import numpy as np
3
4
class Model(object):
5
    def __init__(self, a, b):
6
        self.a = a
7
        self.b = b
8
    def __call__(self, x):
9
        return self.a * x + self.b
10
11
def train(model, inputs, outputs, learning_rate):
12
    with tf.GradientTape() as t:
13
        t.watch([model.a, model.b])
14
        current_loss = perte(model(inputs), outputs)
15
    da, db = t.gradient(current_loss, [model.a, model.b])
16
    model.a = tf.add(model.a,tf.constant(-learning_rate * da))
17
    model.b = tf.add(model.b,tf.constant(-learning_rate * db))
18
19
def perte(predicted_y, target_y):
20
    return tf.reduce_mean(tf.square(predicted_y - target_y))
21
  
22
23
a_mc2 = tf.Variable(2.3)
24
b_mc2 = tf.Variable(0.5)
25
model_ref = Model(a_mc2,b_mc2)
26
x = np.array([1,2,3,4],np.float32)
27
y = np.array([3,5,7,10],np.float32)
28
learning_rate = 0.005
29
30
model = Model(tf.Variable(7.3),tf.Variable(5.5))
31
32
print('Perte: ', perte(model(x), y).numpy())
33
print('(a, b) : (', model.a.numpy(),', ',model.b.numpy(),')')
34
35
epochs = range(1000)
36
for epoch in epochs:
37
    train(model, x, y, learning_rate)
38
print('Perte: ', perte(model(x), y).numpy())
39
print('(a, b) : (', model.a.numpy(),', ',model.b.numpy(),')')
40
41
42

a et b sont les deux paramètres du modèle (variable), on utilise tf.Variable avec un dtype float (32 bits) par défaut.

Les données x et y sont des tableaux numpy.

La fonction de perte permet de mesurer l'écart entre le modèle et les données. On utilise simplement l'erreur des moindres carrés :

\(\sum_{i=0}^{N-1}(y_i-ax_i-b)^2\)

1
def perte(predicted_y, target_y):
2
    return tf.reduce_mean(tf.square(predicted_y - target_y))

La fonction train ajuste les paramètres a et b du modèle :

1
def train(model, inputs, outputs, learning_rate):
2
    with tf.GradientTape() as t:
3
        t.watch([model.a, model.b])
4
        current_loss = perte(model(inputs), outputs)
5
    da, db = t.gradient(current_loss, [model.a, model.b])
6
    model.a = tf.add(model.a,tf.constant(-learning_rate * da))
7
    model.b = tf.add(model.b,tf.constant(-learning_rate * db))
8

Le calcul du gradient est effectué par la classe tf.GradientTape et la méthode t.gradient

1
    with tf.GradientTape() as t:
2
        t.watch([model.a, model.b])
3
        current_loss = perte(model(inputs), outputs)
4
    da, db = t.gradient(current_loss, [model.a, model.b])

Pour calculer la valeur du sortie du modèle, on appelle la méthode __call__ (associée à l'opérateur ()) de l'objet avec en paramètre l'entrée du modèle:

1
model(x)

ExempleExemple avec le tracé de la descente du gradient

1
import tensorflow as tf
2
import numpy as np
3
import matplotlib as mpl
4
from mpl_toolkits.mplot3d import Axes3D
5
from matplotlib import pyplot as plt
6
7
class Model(object):
8
    def __init__(self, a, b):
9
        self.a = a
10
        self.b = b
11
    def __call__(self, x):
12
        return self.a * x + self.b
13
14
def train(model, inputs, outputs, learning_rate):
15
    with tf.GradientTape() as t:
16
        t.watch([model.a, model.b])
17
        current_loss = perte(model(inputs), outputs)
18
    da, db = t.gradient(current_loss, [model.a, model.b])
19
    model.a = tf.add(model.a,tf.constant(-learning_rate * da))
20
    model.b = tf.add(model.b,tf.constant(-learning_rate * db))
21
22
        
23
        
24
model = Model(tf.Variable(3.0),tf.Variable(5.0))
25
26
assert model(3.0).numpy() == 14.0
27
28
def perte(predicted_y, target_y):
29
    return tf.reduce_mean(tf.square(predicted_y - target_y))
30
  
31
32
a_mc2 = tf.Variable(2.3)
33
b_mc2 = tf.Variable(0.5)
34
model_ref = Model(a_mc2,b_mc2)
35
x = np.array([1,2,3,4],np.float32)
36
y = np.array([3,5,7,10],np.float32)
37
NUM_EXAMPLES = x.shape
38
learning_rate = 0.005
39
40
model = Model(tf.Variable(7.3),tf.Variable(5.5))
41
42
print('Perte: ', perte(model(x), y).numpy())
43
print('(a, b) : (', model.a.numpy(),', ',model.b.numpy(),')')
44
45
46
chemin = list()
47
epochs = range(1000)
48
for epoch in epochs:
49
    train(model, x, y, learning_rate)
50
    chemin.append([model.a.numpy(), model.b.numpy(),perte(model(x), y)])
51
print('Perte: ', perte(model(x), y).numpy())
52
print('(a, b) : (', model.a.numpy(),', ',model.b.numpy(),')')
53
54
aa = np.arange(-5 + model.a.numpy(), 5 + model.a.numpy(), 0.05)
55
bb = np.arange(-5 + model.b.numpy(), 5 + model.b.numpy(), 0.05)
56
a_, b_ = np.meshgrid(aa, bb)
57
zz = np.zeros(a_.shape,np.float32)
58
for idx in range(x.shape[0]):
59
    zz = zz + (a_ * x[idx] + b_ - y[idx]) ** 2
60
plt.figure(1)
61
plt.scatter(x, y, c='b',label='Donnees')
62
plt.plot(x, model_ref(x), c='r',label='Droite des moindres carres')
63
plt.plot(x, model( x) , c='g',label='descente de gradient')
64
plt.scatter(x, y, c='r')
65
plt.legend()
66
fig = plt.figure(2)
67
ax = fig.gca(projection='3d')
68
surf = ax.plot_wireframe(a_, b_, zz/x.shape[0],
69
                       rstride=10, cstride=10)
70
ax.plot([x[0] for x in chemin], [x[1] for x in chemin], [x[2] for x in chemin], label='gradient descendant')
71
ax.scatter([x[0] for x in chemin], [x[1] for x in chemin], [x[2] for x in chemin],c='r')
72
ax.legend()
73
plt.show()