Recension de Machine Learning with TensorFlow de Nishant Shula

Le livre est publié par les éditions MEAP Edition (Manning Edition), un éditeur qui présente de très nombreux livres sur le machine learning. La version étudiée ici est sortie en 2017. L’auteur est Nishant Shula

Le livre a 240 pages.

Le code expliqué dans le livre est disponible sur GitHub, à l’adresse https://github.com/BinRoot/TensorFlow-Book/

Les thèmes abordés par le livre sont assez classiques : une introduction à TensorFlow, les algorithmes de base (régression linéaire, classification, clustering, Markov), puis les réseaux de neurones (autoencoder, renforcement, CNN, RNN).

Ce qui est intéressant, c’est la façon de traiter le sujet : cool, bien illustrée, progressive.

Chapitre 1 : A machine-learning odyssey

Ce chapitre décrit les concepts de base du machine learning (les distances L0, L1, L2, les types d’apprentissage (supervisé, non supervisé, renforcement) et présente les concurrents à Tf.

Chapitre 2 : TensorFlow essentials

Ce chapitre n’apporte rien de plus à ce qu’on trouve dans la documentation de TensorFlow. Il y est question de matrices, de tenseurs, de variables, constantes, placeholders, … 

Chapitre 3 : Linear regression and beyond

La régression linéaire, traitée par TensorFlow, est très bien expliquée dans ce chapitre. Nous insistons un peu plus sur ce chapitre afin de présenter le travail de l’auteur et de montrer comme aborder la régression linéaire avec TensorFlow.

Utiliser TensorFlow pour une régression linéaire, c’est choisir un outil sur-dimensionné pour résoudre le problème – mais ça a du sens dans un but didactique. Pour ceux qui veulent aller plus loin sur le sujet, voir ici.

Toutes les lignes du code du livre sont commentées par nous, de façon un peu plus approfondie, afin de s’adresser aux néophytes Python et TensorFlow.

%matplotlib inline est une fonction magique.

IPython has a set of predefined ‘magic functions’ that you can call with a command line style syntax. There are two kinds of magics, line-oriented and cell-oriented. Line magics are prefixed with the % character and work much like OS command-line calls: they get as an argument the rest of the line, where arguments are passed without parentheses or quotes. Lines magics can return results and can be used in the right hand side of an assignment.

Cette fonction magique permet d’afficher les graphiques dans Jupyter, au moment où les fonctions sont appelées.

With this backend, the output of plotting commands is displayed inline within frontends like the Jupyter notebook, directly below the code cell that produced it. The resulting plots will then also be stored in the notebook document.

%matplotlib inline

Importation de TensorFlow, NumPy et matplotlib.
NumPy est un module spécialisé dans la manipulation des matrices.

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

Le nombre d’epochs est le nombre de parcours de l’ensemble du jeu de données.

learning_rate et training_epochs sont des hyperparamètres. Leurs valeurs sont arbitraires ici. D’ailleurs, avec learning_rate = 0.1 nous obtenons le même résultat !

Nous reviendrons sur le learning_rate.

learning_rate = 0.01
training_epochs = 100

numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)

Return evenly spaced numbers over a specified interval.

Returns num evenly spaced samples, calculated over the interval [start, stop].

Exemple : 

np.linspace(2.0, 3.0, num=5)

array([ 2. , 2.25, 2.5 , 2.75, 3. ])

np.linspace(2.0, 3.0, num=5, endpoint=False)

array([ 2. , 2.2, 2.4, 2.6, 2.8])

np.linspace(2.0, 3.0, num=5, retstep=True)

(array([ 2. , 2.25, 2.5 , 2.75, 3. ]), 0.25

#C The input values are 101 evenly spaced numbers between -1 and 1
x_train = np.linspace(-1, 1, 101)

On ajoute du bruit à y_train afin que les données ne soient pas totalement linéaires.

#D The output values are proportional to the input but with added noise
y_train = 2 * x_train + np.random.randn(*x_train.shape) * 0.33

Pour rappel, x_train.shape = (101, )

numpy.random.randn(d0, d1, , dn) returns a sample (or samples) from the “standard normal” distribution.

Puis on affiche les données 

plt.scatter(x_train, y_train)

La notion de placeholder en TensorFlow n’est pas si simple.

#D Set up the input and output nodes as placeholders since the value will be injected by x_train and y_train.
X = tf.placeholder("float")
Y = tf.placeholder("float")

L'auteur définit le placeholder de la façon suivante :

A value that is unassigned, but will be initialized by the session wherever it is run. Typically, placeholders are the input and output of your model.

Ce qui est difficile à comprendre, c’est la différence entre placeholder et variable. L’explication d’Aurélien Géron est plus claire : 

For this, we need a way to replace X and y at every iteration with the next mini-batch. The simplest way to do this is to use placeholder nodes. These nodes are special because they don’t actually perform any computation, they just output the data you tell them to output at runtime. They are typically used to pass the training data to TensorFlow during training. If you don’t specify a value at runtime for a placeholder, you get an exception. »

Extrait de: Aurélien Géron. « Hands-On Machine Learning with Scikit-Learn and TensorFlow: Concepts, Tools, and Techniques to Build Intelligent Systems. »

def model(X, w):
  return tf.multiply(X, w)

tf.multiply returns x * y element-wise.

Just like any Tensor, variables created with Variable() can be used as inputs for other Ops in the graph.

#F Set up the weights variable
w = tf.Variable(0.0, name="weights")

Une fonction de coût mesure la distance entre la prédiction du modèle et les échantillons d’entraînement. Ici, la fonction de coût est la moyenne des carrés des distances.

tf.reduce_mean computes the mean of elements across dimensions of a tensor.

tf.square computes square of x element-wise.

#G Define the cost function
y_model = model(X, w)
cost = tf.reduce_mean(tf.square(Y-y_model))

Lorsqu’on fait de la régression, il faut trouver des paramètres qui vont minimiser une fonction de coût. La méthode utilisée ici pour trouver ces paramètres est la descente du gradient.

Cette descente du gradient est expliquée ailleurs sur notre site.

#H Define the operation that will be called on each iteration of the learning algorithm
train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

En Tf : 

A Session object encapsulates the environment in which Operation objects are executed, and Tensor objects are evaluated.

sess = tf.Session()

This is just a shortcut for variables_initializer(global_variables())

#I Set up a session and initialize all variables
init = tf.global_variables_initializer()

sess.run runs operations and evaluates tensors in fetches.

sess.run(init)

On itère sur le nombre d’epochs. Pour rappel : training_epochs = 100

range() is 0-index based, meaning list indexes start at 0, not 1. eg. The syntax to access the first element of a list is mylist[0]. Therefore the last integer generated by range() is up to, but not including, stop. For example range(0, 5) generates integers from 0 up to, but not including, 5.

#J Loop through the dataset multiple times
for epoch in range(training_epochs):
#K Loop through each item in the dataset
for (x, y) in zip(x_train, y_train):

On met à jour les données du modèle.

#L Update the model parameter(s) to try to minimize the cost function
sess.run(train_op, feed_dict={X: x, Y: y})

Puis on récupère les données.

#M Obtain the final parameter value
w_val = sess.run(w)
sess.close()

On termine par un bel affichage des données :

plt.scatter(x_train, y_train)
y_learned = x_train*w_val
plt.plot(x_train, y_learned, 'r')
plt.show()

En résumé, ce n’est pas très simple si vous débutez avec TensorFlow mais cet exercice est très utile car il permet de mieux comprendre la suite du livre. C’est beaucoup plus rapide de faire une régression linéaire avec sklearn.

L’auteur n’a pas proposé une régression linéaire de la forme y = ax+b mais uniquement y = ax (il n’y a pas de biais)

Chapitre 4 : A gentle introduction to classification

Ce chapitre aborde les notions de : accuracy, precision, recall, ROC, function sigmoïd, softmax – ce qu’on retrouve aussi dans tous les livres sur l’apprentissage automatique.

Chapitre 5 : Automatically clustering data

Le clustering (partitionnement de données) est illustré par des exemples de K-means sur des fichiers audios et par le self-organizing map (SOM) (cartes auto adaptatives).

chapitre 6 : Hidden Markov models

TensorFlow a annoncé en avril 2018, un package Probabilité (Introducing TensorFlow Probability) qui rend un peu obsolète les exemples du livre sur les chaînes de Markov.

Les autres chapitres – non détaillés ici (pour l’instant) sont : (chapitre 7 : peek into autoencoders), (chapitre 8 : Reinforcement learning), (chapitre 9 : Convolutional neural networks), (chapitre 10 : Recurrent neural networks), (chapitre 11 : Sequence-to-sequence models for chatbots) et (chapitre 12 : Utility landscape)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.