Les données dans Tensorflow
Méthode : tf.data
tf.data permet de construire une classe tf.data.Dataset représentant une séquence d'éléments. Par exemple un élément dans la régression linéaire est un couple xi, yi.
Exemple : Création d'un objet Dataset
L'objet de type Dataset contiendra nos données. Pour notre exemple de régression linéaire, l'objet contiendra les N couples (xi, yi). on utilise la méthode from_tensor_slices de la classe tf.data.Dataset :
x = np.array([1, 5, 8, 9 ,10, 15,13, 3,-2],np.float32)
y = np.array([-2,-5, -7, -12 ,-15, -5, -12,-10,-5],np.float32)
dataset = tf.data.Dataset.from_tensor_slices(( x , y ))
Utilisation de Dataset dans la descente du gradient
Méthode : Utilisation
Nous allons appliquer la descente du gradient en utilisant un objet Dataset dans le programme suivant :
import tensorflow as tf
import numpy as np
class Model(object):
def __init__(self, a, b):
self.a = a
self.b = b
def __call__(self, x):
return self.a * x + self.b
def train(model, inputs, outputs, learning_rate):
with tf.GradientTape() as t:
t.watch([model.a, model.b])
current_loss = perte(model(inputs), outputs)
da, db = t.gradient(current_loss, [model.a, model.b])
model.a = tf.add(model.a,tf.constant(-learning_rate * da))
model.b = tf.add(model.b,tf.constant(-learning_rate * db))
def perte(predicted_y, target_y):
return tf.reduce_mean(tf.square(predicted_y - target_y))
x = np.array([1, 5, 8, 9 ,10, 15,13, 3,-2],np.float32)
y = np.array([-2,-5, -7, -12 ,-15, -5, -12,-10,-5],np.float32)
dataset = tf.data.Dataset.from_tensor_slices(( x , y ))
batch_size = 9
num_epochs = 3
dataset = dataset.repeat( num_epochs ).batch( batch_size )
iterator = dataset.__iter__()
learning_rate = 0.01
model = Model(tf.Variable(7.3),tf.Variable(5.5))
print('Perte: ', perte(model(x), y).numpy())
print('(a, b) : (', model.a.numpy(),', ',model.b.numpy(),')')
for epoch in range(num_epochs):
x_batch , y_batch = iterator.get_next()
print('Donnees ajustees :', x_batch,'/',y_batch)
train(model, x_batch, y_batch, learning_rate)
print('Perte: ', perte(model(x), y).numpy())
print('(a, b) : (', model.a.numpy(),', ',model.b.numpy(),')')
Le résultat de l'exécution est :
Perte: 5729.852
(a, b) : ( 7.3 , 5.5 )
Donnees ajustees : tf.Tensor([ 1. 5. 8. 9. 10. 15. 13. 3. -2.], shape=(9,), dtype=float32) / tf.Tensor([ -2. -5. -7. -12. -15. -5. -12. -10. -5.], shape=(9,), dtype=float32)
Donnees ajustees : tf.Tensor([ 1. 5. 8. 9. 10. 15. 13. 3. -2.], shape=(9,), dtype=float32) / tf.Tensor([ -2. -5. -7. -12. -15. -5. -12. -10. -5.], shape=(9,), dtype=float32)
Donnees ajustees : tf.Tensor([ 1. 5. 8. 9. 10. 15. 13. 3. -2.], shape=(9,), dtype=float32) / tf.Tensor([ -2. -5. -7. -12. -15. -5. -12. -10. -5.], shape=(9,), dtype=float32)
Perte: 162.49437
(a, b) : ( -2.4932983 , 4.371428 )
Dans le programme précédent, l'objet dataset
est crée à l'aide des lignes suivantes:
x = np.array([1, 5, 8, 9 ,10, 15,13, 3,-2],np.float32)
y = np.array([-2,-5, -7, -12 ,-15, -5, -12,-10,-5],np.float32)
dataset = tf.data.Dataset.from_tensor_slices(( x , y ))
x et y sont des tableaux numpy contenant les données.
Ensuite on décide d'effectuer, 3 (num_epochs) itérations de l'algorithme du descente du gradient en utilisant les 9 données (batch size):
batch_size = 9
num_epochs = 3
dataset = dataset.repeat( num_epochs ).batch( batch_size )
iterator = dataset.__iter__()
On prépare les données à l'aide de la ligne dataset.repeat( num_epochs ).batch( batch_size )
et on aura accès aux données pour chaque itération à l'aide de l'objet iterator
.
Les données seront accessibles dans la boucle à l'aide de la méthode get_next() :
for epoch in range(num_epochs):
x_batch , y_batch = iterator.get_next()
Dans une première approche, une boucle a été supprimée :le nombre de données du lot est égal au nombre de données disponibles, le lot (batch size) consomme toutes les données disponibles.