09 Jan

MNIST tf 2.0

TensorFlow 2.0

Il s’agit de tester le code du livre de Michelucci, Advanced Applied Deep Learning de U. Michelucci, § MNIST Classification with Eager Execution

Il n’y a là rien de spécial. Les étapes sont :

  • Récupération des données
  • Normalisation et one hot encoding
  • Transformation des données en tf.data.Dataset object
  • Construction d’un modèle Keras
  • Définition de l’optimizer et de la fonction de coût
  • Minimisation de la fonction de coût

La 2ème partie du code aborde brièvement le GPU.

20 Déc

TensorFlow Hub

TensorFlow Hub

Concevoir et mettre au point des modèles de Machine Learning/Deep Learning nécessite d’y consacrer beaucoup de temps et de disposer de connaissances multiples et variées.

Démarrer from scratch n’a pas de sens. Il faut impérativement s’appuyer sur le travail des autres. D’où l’importance des communautés.

C’est ce qu’a bien compris Google en créant tout un écosystème autour de TensorFlow, et au sein de cet environnement, TensorFlow Hub

Le Hub est en ensemble de ressources pour se former au ML, un forum d’échanges et une mailing list sur Tf mais c’est surtout des modèles prêts à l’emploi.

Ces modèles sont répartis en trois catégories : image, texte, et vidéo.

Pour expliquer comment bénéficier des modèles sauvegardés sur le Hub, le tutoriel TF Hub for TF2: Retraining an image classifier est une bonne solution. La version que nous présentons est celle disponible sur notre Drive. Pour la version originale c’est ici.

Tutoriel

Si vous n’êtes pas familier avec le traitement d’images et avec TensorFlow 2.0, renoncez à la lecture de la suite !

Le tutoriel présente un cas de Transfer Learning pour la classification d’images de fleurs.

Imports

Tout d’abord on s’assure d’utiliser la version 2.x

try:
  # %tensorflow_version only exists in Colab.
  %tensorflow_version 2.x
except Exception:
  pass

Puis on importe les packages habituels.

import itertools
import os

import matplotlib.pylab as plt
import numpy as np

import tensorflow as tf
import tensorflow_hub as hub

print("TF version:", tf.__version__)
print("Hub version:", hub.__version__)
print("GPU is", "available" if tf.test.is_gpu_available() else "NOT AVAILABLE")
TF version: 2.1.0-rc1
Hub version: 0.7.0
GPU is available

Modèle

module_selection = ("mobilenet_v2_100_224", 224) 
#@param ["(\"mobilenet_v2_100_224\", 224)", "(\"inception_v3\", 299)"] {type:"raw", allow-input: true}

handle_base, pixels = module_selection

MODULE_HANDLE="https://tfhub.dev/google/imagenet/{}/feature_vector/4".format(handle_base)
IMAGE_SIZE = (pixels, pixels)

print("Using {} with input size {}".format(MODULE_HANDLE, IMAGE_SIZE))
BATCH_SIZE = 32 #@param {type:"integer"}
Using https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/feature_vector/4 with input size (224, 224)

Tout ceci requiert quelques commentaires !

Le modèle utilisé est mobilenet_v2_100_224. Ce modèle est décrit amplement ici.

This TF Hub model uses the TF-Slim implementation of mobilenet_v2 with a depth multiplier of 1.0 and an input size of 224×224 pixels.

TF2 SavedModel

L’apprentissage de ce modèle s’est fait sur ImageNet. Les images en input doivent être carrées 224.

Jeu de données

On applique le modèle à notre jeu de données.

data_dir = tf.keras.utils.get_file(
    'flower_photos',
    'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
    untar=True)
Downloading data from https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz
228818944/228813984 [==============================] - 2s 0us/step

Les photos sont réparties en 5 catégories : daisy (marguerites), dandelion (pissenlits), roses, sunflowers (tournesols), tulips. Il y a en tout 3670 photos.

Pré-processing

datagen_kwargs = dict(rescale=1./255, validation_split=.20)
dataflow_kwargs = dict(target_size=IMAGE_SIZE, batch_size=BATCH_SIZE,
                   interpolation="bilinear")

valid_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    **datagen_kwargs)
valid_generator = valid_datagen.flow_from_directory(
    data_dir, subset="validation", shuffle=False, **dataflow_kwargs)

Les images sont normalisées (rescale=1./255), séparées en un jeu d’apprentissage et un de validation (validation_split=.20)

Le batch size est à 32 (par défaut), l’interpolation bilinéaire.

On peut ensuite choisir (ou pas) de faire de la data augmentation. Les performances dans le 1er cas seront a priori meilleures.

do_data_augmentation = False #@param {type:"boolean"}
if do_data_augmentation:
  train_datagen = tf.keras.preprocessing.image.ImageDataGenerator(
      rotation_range=40,
      horizontal_flip=True,
      width_shift_range=0.2, height_shift_range=0.2,
      shear_range=0.2, zoom_range=0.2,
      **datagen_kwargs)
else:
  train_datagen = valid_datagen
train_generator = train_datagen.flow_from_directory(
    data_dir, subset="training", shuffle=True, **dataflow_kwargs)
Found 731 images belonging to 5 classes.
Found 2939 images belonging to 5 classes.

Définition du modèle

do_fine_tuning = False #@param {type:"boolean"}

print("Building model with", MODULE_HANDLE)
model = tf.keras.Sequential([
    hub.KerasLayer(MODULE_HANDLE, trainable=do_fine_tuning),
    tf.keras.layers.Dropout(rate=0.2),
    tf.keras.layers.Dense(train_generator.num_classes, activation='softmax',
                          kernel_regularizer=tf.keras.regularizers.l2(0.0001))
])
model.build((None,)+IMAGE_SIZE+(3,))
model.summary()
Building model with https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/feature_vector/4
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
keras_layer (KerasLayer)     multiple                  2257984   
_________________________________________________________________
dropout (Dropout)            multiple                  0         
_________________________________________________________________
dense (Dense)                multiple                  6405      
=================================================================
Total params: 2,264,389
Trainable params: 6,405
Non-trainable params: 2,257,984

Le modèle est décrit en mode séquentiel. Tout d’abord on indique lequel on importe pour le transfer learning (mobilenet_v2), puis on ajoute à ce modèle un Dropout (0.2) et on termine par un Softmax (5 classes)

Apprentissage

Le reste est plus classique :

model.compile(
  optimizer=tf.keras.optimizers.SGD(lr=0.005, momentum=0.9), 
  loss=tf.keras.losses.CategoricalCrossentropy(label_smoothing=0.1),
  metrics=['accuracy'])
steps_per_epoch = train_generator.samples // train_generator.batch_size
validation_steps = valid_generator.samples // valid_generator.batch_size
hist = model.fit_generator(
    train_generator,
    epochs=5, steps_per_epoch=steps_per_epoch,
    validation_data=valid_generator,
    validation_steps=validation_steps).history