Il est fortement recommandé d’avoir étudié le tutoriel #1 et le tutoriel #2 avant celui-ci car on y trouve de nombreux éléments communs qui ne sont pas re-expliqués ici.
Cet article commente le tutoriel Tensorflow #3 de Magnus Erik Hvass Pedersen  : Keras API. Le code est ici et la vidéo ici (en anglais).
Les convolutions ne sont pas expliquées dans notre article. Elles sont supposées connues (cf #1 et #2).
Dans ce tutoriel l’objectif est le mĂŞme que pour le tutoriel #2 mais au lieu d’utiliser les API TensorFlow on utilisera les API de Keras (voir aussi Keras tutoriel #1)
Flux
Pour rappel, le réseau implémenté est représenté ci-dessous :
Imports
En plus des imports habituels, on importe de Keras :
# from tf.keras.models import Sequential # This does not work! from tensorflow.python.keras.models import Sequential from tensorflow.python.keras.layers import InputLayer, Input from tensorflow.python.keras.layers import Reshape, MaxPooling2D from tensorflow.python.keras.layers import Conv2D, Dense, Flatten
Lorsque Magnus a Ă©crit son code il semble qu’on ne pouvait pas Ă©crire tout simplement :
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import InputLayer, Input, Reshape,MaxPooling2D, Conv2D, Dense, Flatten
dĂ©sormais c’est possible.
on peut aussi écrire :
from keras.models import Sequential
mais il faut probablement une installation séparée de Keras.`
Sequential Model
Le modèle sĂ©quentiel de Keras est ce qu’il y a de plus intĂ©ressant dans l’API car il est très simple d’utilisation.
Il suffit de dĂ©crire l’empilement des couches de neurones.
# Start construction of the Keras Sequential model. model = Sequential() # Add an input layer which is similar to a feed_dict in TensorFlow. # Note that the input-shape must be a tuple containing the image-size. model.add(InputLayer(input_shape=(img_size_flat,))) # The input is a flattened array with 784 elements, # but the convolutional layers expect images with shape (28, 28, 1) model.add(Reshape(img_shape_full)) # First convolutional layer with ReLU-activation and max-pooling. model.add(Conv2D(kernel_size=5, strides=1, filters=16, padding='same', activation='relu', name='layer_conv1')) model.add(MaxPooling2D(pool_size=2, strides=2)) # Second convolutional layer with ReLU-activation and max-pooling. model.add(Conv2D(kernel_size=5, strides=1, filters=36, padding='same', activation='relu', name='layer_conv2')) model.add(MaxPooling2D(pool_size=2, strides=2)) # Flatten the 4-rank output of the convolutional layers # to 2-rank that can be input to a fully-connected / dense layer. model.add(Flatten()) # First fully-connected / dense layer with ReLU-activation. model.add(Dense(128, activation='relu')) # Last fully-connected / dense layer with softmax-activation # for use in classification. model.add(Dense(num_classes, activation='softmax'))
Comme on peut le constater, la description du modèle est très explicite.
Attardons-nous ici sur Conv2D et MaxPooling2D.
Conv2D
Conv2D permet de faire des convolutions sur des images.
keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
Les arguments de Conv2D retenus ici sont : filters, kernel_size, strides, padding, activation, name.
Ajoutons input_shape non prĂ©sent dans l’exemple.
input_shape
When using this layer as the first layer in a model, provide the keyword argument
input_shape
(tuple of integers, does not include the batch axis), e.g.input_shape=(128, 128, 3)
for 128×128 RGB pictures indata_format="channels_last"
.
Le choix d’implĂ©mentation de l’exemple est d’ajouter une couche « virtuelle » avant la convolution 2D.
Ce n’est pas ce qu’on voit dans les exemples rĂ©cents. Rien n’empĂŞche (au contraire) de commencer comme ici :
model = Sequential() model.add(Conv2D(32, (5, 5), input_shape=(1, 28, 28), activation='relu'))
filters
filters: Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
Le schĂ©ma dĂ©crit au § flux, montre que l’output de la 1ère convolution est constituĂ© de 16 channels et celui de la seconde de 36 channels.
kernel_size
kernel_size est la dimension de la fenêtre de convolution. Lorsque, comme dans notre exemple, kernel_size est donné avec une seule dimension, celle-ci suppose une dimension équivalente sur tous les axes. kernel_size=5 est identique à  kernel_size=(5,5)
padding
Keras ne permet que deux options pour le padding de Conv2D. Soit same, soit valid.
Ces options sont celles disponibles avec TensorFlow.
Sometimes filter does not fit perfectly fit the input image. We have two options:
-
Pad the picture with zeros (zero-padding) so that it fits
-
Drop the part of the image where the filter did not fit. This is called valid padding which keeps only valid part of the image.
Pour une bonne explication du padding, voir ici.
VALID
: Don’t apply any padding, i.e., assume that all dimensions are valid so that input image fully gets covered by filter and stride you specified.
SAME
: Apply padding to input (if needed) so that input image gets fully covered by filter and stride you specified. For stride 1, this will ensure that output image size is same as input.
activation
Il existe diffĂ©rentes façons de mettre en place l’activation.
Activations can either be used through an
Activation
layer, or through theactivation
argument supported by all forward layers:
model.add(Dense(64)) model.add(Activation('tanh'))
est équivalent à :
model.add(Dense(64, activation='tanh'))
Keras propose de nombreuses fonctions d’activation. des plus connues (tanh, sigmoid, softmax, relu) aux moins (elu, selu, hard_sigmoid, …)
La fonction choisie ici est relu.
MaxPooling2D
A chaque fois que MaxPooling2D est utilisĂ© dans notre exemple, c’est avec les mĂŞmes arguments.
model.add(MaxPooling2D(pool_size=2, strides=2))
-
pool_size: integer or tuple of 2 integers, factors by which to downscale (vertical, horizontal). (2, 2) will halve the input in both spatial dimension. If only one integer is specified, the same window length will be used for both dimensions.
-
strides: Integer, tuple of 2 integers, or None. Strides values. If None, it will default to
pool_size
.
pool_size=2 est equivalent Ă Â pool_size=(2,2). Idem pour strides.
Les arguments sont les mĂŞmes que ceux de TensorFlow.
Pour une explication du pooling, voir ici.
Le pooling choisi permet, après la 1ère convolution, de réduire la taille des images de 28*28 à 14*14 et après la seconde à 7*7
Model Compilation
Il ne reste ensuite qu’Ă ajouter les fonctions d’optimisation, de perte, et de calcul de l’exactitude.
from tensorflow.python.keras.optimizers import Adam optimizer = Adam(lr=1e-3) model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
Le reste du code est le mĂŞme que pour le tutoriel #2.
Le modèle fonctionnel est décrit dans notre article suivant.