Aurélien Géron (AG) publie la seconde édition de son livre « Hands-on Machine Learning with Scikit-Learn, Keras, and TensorFlow« .
La différence fondamentale entre les deux éditions est le support de Keras, TensorFlow 2 et l’ajout de quelques chapitres sur le renforcement, NLP, et GAN.
De façon identique à l’édition précédente, le livre est d’excellente qualité. Maîtriser ce qui est décrit ici permettra à tous les débutants d’acquérir les bases nécessaires pour commencer des travaux sérieux en Machine Learning.
Associés à son livre, on retrouvera 17 Notebooks Jupyter sur GitHub.
Pour illustrer son livre, nous présentons ici le chapitre 14 : Deep Computer Vision Using Convolutional Neural Networks avec nos commentaires.
Les convolutions
AG décrit ici le principe des convolutions.
AG explique ce que sont les strides, le padding, les filtres (kernels) . Pour bien comprendre la notion de kernel, en complément voir ce site et celui-ci.
AG définit aussi les feature maps qui sont pour lui les résultats des opérations de convolution sur une image. Il y a autant de feature maps que de filters.
La définition de feature maps est discutée fréquemment par d’autres auteurs (est-ce la même chose que l’activation map ? ou convolved feature ? est-ce avant le ReLU, avant le Pooling ? Pour AG, feature map = convolved feature.
Il n’est pas facile pour les débutants de comprendre les convolutions.
Lisez : A guide to convolution arithmetic for deep learning de Vincent Dumoulin et Francesco Visin si vous êtes un peu perdus.
TensorFlow implementation
Analysons ligne par ligne l’exemple du livre.
from sklearn.datasets import load_sample_image
Sklearn est vraiment un outil très pédagogique (le meilleur probablement). Qu’on puisse lire une seule image d’exemple est extraordinaire !
Seules 2 options sont possibles (china.jpg et flower.jpg).
# Load sample images
china = load_sample_image("china.jpg") / 255
flower = load_sample_image("flower.jpg") / 255
Les 2 images sont au format (427, 640, 3). Comme les images ont des valeurs dans l’intervalle 0..255, pour les transformer en float, alors on divise les valeurs des pixels par 255. Est-ce indispensable ? AG ne le dit pas.
images = np.array([china, flower])
On crée un tableau d’images (images) puis on initialise les variables batch_size (=2 puisqu’on a 2 images), height = 427, width = 640 (la taille de l’image) et channels = 3 car on a des images en couleur.
batch_size, height, width, channels = images.shape
Ensuite on crée les kernels.
On a un filters qui est un tenseur de shape (7,7,3,2). D’abord initialisé à 0, ensuite le 1er kernel est dédié à la reconnaissance des lignes verticales, le second aux lignes horizontales.
# Create 2 filters
filters = np.zeros(shape=(7, 7, channels, 2), dtype=np.float32) filters[:, 3, :, 0] = 1 # vertical line
filters[3, :, :, 1] = 1 # horizontal line
Puis vient la convolution. Attention, si vous utilisez tf (<2.0) alors il y a une erreur dans le code (strides ne doit pas être un entier). Par contre, avec tf > 2.0 vous pouvez garder cette ligne telle quelle.
https://www.tensorflow.org/api_docs/python/tf/nn/conv2d
strides
: A list ofints
. 1-D tensor of length 4. The stride of the sliding window for each dimension ofinput
. The dimension order is determined by the value ofdata_format
, see below for details.
Au lieu de : (avec tf <2.0)
outputs = tf.nn.conv2d(images, filters, strides=1, padding="SAME")
Il faut :
outputs = tf.nn.conv2d(images, filters, strides=[1,1,1,1], padding="SAME")
On termine par afficher le résultat de la convolution.
plt.imshow(outputs[0, :, :, 1], cmap="gray") # plot 1st image's 2nd feature map
plt.show()
Le livre d’A. Géron, dans sa 2nde édition, mérite indubitablement qu’on s’y intéresse. Contrairement à ce qu’une lecture rapide laisserait penser, il n’est pas très simple. Il est dense, ce qui fait tout son intérêt.
Il faut le lire et le relire. Nous y reviendrons !