TensorFlow 2.0 alpha est désormais disponible. Ce framework a un impact considérable sur la communauté du deep learning. Chercheurs, développeurs, praticiens l'ont adopté comme jamais auparavant. Il est sans conteste l'un des moteurs du décollage des applications d'apprentissage profond les plus impressionnantes que nous voyons aujourd'hui. Cela étant dit, TensorFlow 1.xa aussi ses limites (comme beaucoup d'autres frameworks). Comme l'a dit Martin Wicke (Software Engineer de l'équipe TensorFlow) lors du TF Dev Summit 2019 :
Nous avons beaucoup appris depuis la version 1.0.
Fort de ces enseignements issus d'une large base d'utilisateurs et des issues GitHub, l'équipe TensorFlow a publié TensorFlow 2.0 alpha, qui apporte de nombreux changements importants pour améliorer les performances, l'expérience développeur, etc. Vous pouvez ainsi prototyper rapidement et bénéficier de nombreuses pratiques modernes de deep learning. Dans cet article, vous étudierez certaines de ces évolutions au travers d'implémentations concises.
Remarque : les mises à jour présentées ici sont, selon l'auteur, les plus significatives. Vous aurez besoin d'une expérience préalable avec TensorFlow et Keras pour suivre l'article. Voici quelques ressources utiles si vous souhaitez un rappel sur TensorFlow et Keras :
Pour mettre à jour vers TensorFlow 2.0, exécutez la ligne suivante dans un Jupyter Notebook :
!pip install tensorflow==2.0.0-alpha0
La variante GPU peut être installée de la même manière (CUDA requis au préalable) :
!pip install tensorflow-gpu==2.0.0-alpha0
Vous trouverez plus d'informations sur le processus d'installation ici.
Plusieurs mises à jour étudiées ci-dessous incluent des implémentations en code. Dans ces cas, vous aurez besoin d'un jeu de données. Pour cet article, vous utiliserez le jeu de données Adult de l'UCI Archive.
import pandas as pd
columns =["Age","WorkClass","fnlwgt","Education","EducationNum","MaritalStatus","Occupation","Relationship","Race","Gender","CapitalGain","CapitalLoss","HoursPerWeek","NativeCountry","Income"]
data = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data',
header=None,
names=columns)
data.head()Propulsé par
Age
WorkClass
fnlwgt
Education
EducationNum
MaritalStatus
Occupation
Relationship
Race
Gender
CapitalGain
CapitalLoss
HoursPerWeek
NativeCountry
Income
0
39
State-gov
77516
Bachelors
13
Never-married
Adm-clerical
Not-in-family
White
Male
2174
0
40
United-States
<=50K
1
50
Self-emp-not-inc
83311
Bachelors
13
Married-civ-spouse
Exec-managerial
Husband
White
Male
0
0
13
United-States
<=50K
2
38
Private
215646
HS-grad
9
Divorced
Handlers-cleaners
Not-in-family
White
Male
0
0
40
United-States
<=50K
3
53
Private
234721
11th
7
Married-civ-spouse
Handlers-cleaners
Husband
Black
Male
0
0
40
United-States
<=50K
4
28
Private
338409
Bachelors
13
Married-civ-spouse
Prof-specialty
Wife
Black
Female
0
0
40
Cuba
<=50K
Ce jeu de données correspond à une tâche de classification binaire : prédire si une personne gagnera plus de 50 000 $ par an ou non, à partir d'un ensemble d'informations personnelles.
Effectuons un prétraitement basique, puis créons des jeux d'entraînement et de test selon un découpage 80:20 :
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
import numpy as np
# Encodage des labels
le = LabelEncoder()
data = data.apply(le.fit_transform)# Séparer les variables explicatives et convertir en tableaux NumPy
X = data.iloc[:,0:-1].values
y = data['Income'].values
# Découpage
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=7)Propulsé par
À ce stade, votre environnement est opérationnel avec TensorFlow 2.0 installé et un jeu de données chargé dans votre espace de travail. Passons maintenant aux nouveautés.
1. Eager execution activée par défaut
Avec TensorFlow 2.0, plus besoin de créer une session et d'exécuter le graphe de calcul à l'intérieur. L'eager execution est activée par défaut dans la version 2.0, ce qui permet de construire vos modèles et de les exécuter immédiatement. Vous pouvez choisir de la désactiver ainsi :
tf.compat.v1.disable_eager_execution() (en supposant que tensorflow est importé sous l'alias tf.)
Voici une petite comparaison en code qui illustre la différence :
2. tf.function et AutoGraph
Si l'eager execution offre une programmation impérative, pour l'entraînement distribué, l'optimisation à grande échelle et la production, l'exécution en graphe à la TensorFlow 1.x conserve des atouts. Avec TensorFlow 2.0, vous conservez l'exécution basée sur des graphes, mais de manière plus flexible, grâce à tf.function et à AutoGraph.
tf.function vous permet de définir des graphes TensorFlow avec une syntaxe de type Python via la fonctionnalité AutoGraph. AutoGraph prend en charge un ensemble étendu de constructions Python, notamment if, for, while, iterators, etc. Il existe toutefois des limitations. Vous trouverez ici la liste complète des compatibilités actuellement disponibles. Ci-dessous, un exemple montrant avec quelle facilité définir un graphe TensorFlow avec un simple decorator.
import tensorflow as tf
# Définir la passe avant@tf.functiondefsingle_layer(x, y):return tf.nn.relu(tf.matmul(x, y))# Générer des données aléatoires issues d'une loi uniforme
x = tf.random.uniform((2,3))
y = tf.random.uniform((3,5))
single_layer(x, y)Propulsé par
<tf.Tensor: id=73, shape=(2,5), dtype=float32, numpy=array([[0.5779363,0.11255255,0.26296678,0.12809312,0.23484911],[0.5932371,0.1793559,0.2845083,0.23249313,0.21367362]],
dtype=float32)>Propulsé par
Notez que vous n'avez pas eu à créer de sessions ni de placeholders pour exécuter la fonction single_layer(). C'est l'un des atouts de tf.function. En coulisses, il applique les optimisations nécessaires pour accélérer votre code.
3. tf.variable_scope n'est plus nécessaire
Dans TensorFlow 1.x, pour utiliser tf.layers comme variables et les réutiliser, vous deviez recourir au bloc tf.variable. Ce n'est plus le cas avec TensorFlow 2.0. keras étant l'API haut niveau centrale de TensorFlow 2.0, toutes les couches créées avec tf.layers peuvent être intégrées facilement dans une définition tf.keras.Sequential. Le code est plus lisible et vous suivez aisément variables et pertes.
Exemple :
# Définir le modèle
model = tf.keras.Sequential([
tf.keras.layers.Dropout(rate=0.2, input_shape=X_train.shape[1:]),
tf.keras.layers.Dense(units=64, activation='relu'),
tf.keras.layers.Dropout(rate=0.2),
tf.keras.layers.Dense(units=64, activation='relu'),
tf.keras.layers.Dropout(rate=0.2),
tf.keras.layers.Dense(units=1, activation='sigmoid')])# Obtenir les probabilités de sortie
out_probs = model(X_train.astype(np.float32), training=True)print(out_probs)Propulsé par
tf.Tensor([[1.][0.12573627][1.]...[1.][1.][1.]], shape=(26048,1), dtype=float32)Propulsé par
Dans l'exemple ci-dessus, vous avez simplement fait passer les données d'entraînement dans le model pour récupérer les probabilités brutes. Il s'agit d'une passe avant. Vous pouvez bien sûr entraîner le modèle :
model.compile(loss='binary_crossentropy', optimizer='adam')
model.fit(X_train, y_train,
validation_data=(X_test, y_test),
epochs=5, batch_size=64)Propulsé par
En recherche comme en production, il est souvent nécessaire d'écrire des couches personnalisées pour des cas d'usage spécifiques. TensorFlow 2.0 facilite grandement l'écriture d'une couche custom et son utilisation avec les couches existantes. Vous pouvez aussi personnaliser la passe avant de votre modèle comme vous le souhaitez.
Pour créer une couche personnalisée, l'option la plus simple est d'étendre la classe Layer de tf.keras.layers puis de la définir en conséquence. Vous créerez une couche custom et définirez ses calculs de passe avant. Voici la sortie de help(tf.keras.layers.Layer), qui indique ce qu'il faut spécifier pour y parvenir :
En suivant ces indications, vous allez :
Définir le constructeur avec le nombre de sorties
Dans la méthode build(), ajouter les poids de la couche
Enfin, dans la méthode call(), définir la passe avant en chaînant multiplication de matrices et relu()
classMyDenseLayer(tf.keras.layers.Layer):# Définir le constructeurdef__init__(self, num_outputs):super(MyDenseLayer, self).__init__()
self.num_outputs = num_outputs
# Définir la fonction build pour ajouter les poidsdefbuild(self, input_shape):
self.kernel = self.add_variable("kernel",
shape=[input_shape[-1],
self.num_outputs])# Définir la passe avantdefcall(self,input):
matmul = tf.matmul(input, self.kernel)return tf.nn.relu(matmul)# Initialiser la couche avec 10 unités de sortie
layer = MyDenseLayer(10)# Fournir la forme d'entrée
layer(tf.random.uniform((10,3)))# Afficher les paramètres entraînables de la coucheprint(layer.trainable_variables)Propulsé par
[<tf.Variable 'my_dense_layer_7/kernel:0' shape=(3,10) dtype=float32, numpy=array([[0.43613756,0.21344548,0.37803996,0.65583944,0.11884308,0.13909656,0.30802298,0.5313586,0.04967308,0.32889426],[0.1680265,-0.59944266,-0.4014195,0.14887196,0.07071263,0.37862527,-0.5822403,-0.5963166,0.3106798,0.05353856],[-0.44345278,-0.23122305,-0.62959856,-0.43062705,0.13194847,-0.60124606,-0.62745696,0.12254918,-0.09806103,-0.45324165]],
dtype=float32)>]Propulsé par
Vous pouvez composer plusieurs couches en étendant la classe Model de tf.keras. En savoir plus sur la composition de modèles ici.
5. Plus de flexibilité pour l'entraînement des modèles
TensorFlow utilise la différenciation automatique pour calculer les gradients de la fonction de perte par rapport aux paramètres du modèle. tf.GradientTape crée un contexte (tape) dans lequel TensorFlow enregistre les opérations dont les gradients seront calculés. Pour illustrer, définissons un modèle à plus bas niveau en étendant la classe tf.keras.Model.
from tensorflow.keras import Model
classCustomModel(Model):def__init__(self):super(CustomModel, self).__init__()
self.do1 = tf.keras.layers.Dropout(rate=0.2, input_shape=(14,))
self.fc1 = tf.keras.layers.Dense(units=64, activation='relu')
self.do2 = tf.keras.layers.Dropout(rate=0.2)
self.fc2 = tf.keras.layers.Dense(units=64, activation='relu')
self.do3 = tf.keras.layers.Dropout(rate=0.2)
self.out = tf.keras.layers.Dense(units=1, activation='sigmoid')defcall(self, x):
x = self.do1(x)
x = self.fc1(x)
x = self.do2(x)
x = self.fc2(x)
x = self.do3(x)return self.out(x)
model = CustomModel()Propulsé par
La topologie de ce modèle est exactement la même que celle définie plus haut. Pour l'entraîner via différenciation automatique, définissez la fonction de perte et l'optimiseur comme suit :
loss_func = tf.keras.losses.BinaryCrossentropy()
optimizer = tf.keras.optimizers.Adam()Propulsé par
Définissons maintenant les métriques utilisées pour mesurer les performances pendant l'entraînement, à savoir la perte et la précision du modèle.
# Moyenne de la perte sur la taille des batchs au sein d'une époque
train_loss = tf.keras.metrics.Mean(name='train_loss')
train_acc = tf.keras.metrics.BinaryAccuracy(name='train_acc')
valid_loss = tf.keras.metrics.Mean(name='test_loss')
valid_acc = tf.keras.metrics.BinaryAccuracy(name='valid_acc')Propulsé par
tf.data fournit des utilitaires pour définir des pipelines de données d'entrée. C'est particulièrement utile avec de grands volumes de données.
Vous allez maintenant définir le générateur de données qui produira des batchs pendant l'entraînement.
Vous êtes prêt à entraîner le modèle avec tf.GradientTape. Commencez par définir une méthode qui entraîne le modèle avec les données fournies via tf.data.DataSet. Enveloppez aussi les étapes d'entraînement dans le décorateur tf.function pour bénéficier des gains de performance.
Entraînement et validation du modèle
# Entraîner le modèle@tf.functiondefmodel_train(features, labels):# Définir le contexte GradientTapewith tf.GradientTape()as tape:# Probabilités de sortie
predictions = model(features)# Calcul de la perte
loss = loss_func(labels, predictions)# Gradients
gradients = tape.gradient(loss, model.trainable_variables)# Mise à jour des poids
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
train_loss(loss)
train_acc(labels, predictions)Propulsé par
# Validation du modèle@tf.functiondefmodel_validate(features, labels):
predictions = model(features)
t_loss = loss_func(labels, predictions)
valid_loss(t_loss)
valid_acc(labels, predictions)Propulsé par
Utilisez ces deux méthodes pour entraîner et valider le modèle sur 5 époques.
for epoch inrange(5):for features, labels in train_ds:
model_train(features, labels)for test_features, test_labels in test_ds:
model_validate(test_features, test_labels)
template ='Epoch {}, train_loss: {}, train_acc: {}, train_loss: {}, test_acc: {}'print(template.format(epoch+1,
train_loss.result(),
train_acc.result()*100,
valid_loss.result(),
valid_acc.result()*100))Propulsé par
Cet exemple s'inspire de cet exemple proposé par les auteurs de TensorFlow 2.0.
6. TensorFlow Datasets
Un module séparé nommé DataSets permet d'opérer avec le modèle de manière élégante. Vous l'avez déjà aperçu plus haut. Dans cette section, voyons comment charger MNIST comme vous le souhaitez.
Installez la bibliothèque tensorflow_datasets avec pip. Une fois installée, vous êtes prêt. Elle propose plusieurs fonctions utilitaires pour préparer votre pipeline de construction de données avec souplesse. Pour en savoir plus, consultez ce dépôt et cette vidéo. Voici comment construire un pipeline d'entrée pour charger MNIST.
import tensorflow_datasets as tfds
# Récupérer la classe DatasetBuilder par son nom
mnist_builder = tfds.builder("mnist")# Télécharger le dataset
mnist_builder.download_and_prepare()# Construire des tf.data.Dataset : train et test
ds_train, ds_test = mnist_builder.as_dataset(split=[tfds.Split.TRAIN, tfds.Split.TEST])Propulsé par
Vous pouvez ignorer l'avertissement. Remarquez la simplicité avec laquelle tensorflow_datasets gère le pipeline.
# Préparer des batchs de 128 à partir de l'ensemble d'entraînement
ds_train = ds_train.batch(128)# Charger le dataset de la manière la plus simplefor features in ds_train:
image, label = features["image"], features["label"]Propulsé par
Vous pouvez maintenant afficher la première image parmi celles chargées. Remarque : tensorflow_datasets fonctionne aussi bien en mode eager qu'en mode graphe.
import matplotlib.pyplot as plt
%matplotlib inline
# Convertir un tenseur TensorFlow avec# .numpy()
plt.imshow(image[0].numpy().reshape(28,28), cmap=plt.cm.binary)
plt.show()Propulsé par
7. Politique de précision mixte automatique
La politique de précision mixte a été proposée par NVIDIA l'année dernière. L'article original est disponible ici. L'idée : utiliser un mélange de demi-précision (FP16) et de pleine précision (FP32) pour tirer le meilleur des deux. Les gains observés pour l'entraînement de réseaux très profonds sont remarquables (temps et scores).
Si vous disposez d'un environnement GPU compatible CUDA (génération Volta, Tesla T4 par exemple) et que vous avez installé la variante GPU de TensorFlow 2.0, vous pouvez demander à TensorFlow d'entraîner en précision mixte ainsi :
Les opérations du graphe TensorFlow seront alors castées automatiquement. Vous observerez souvent un gain notable de performance. Vous pouvez également optimiser les opérations cœur de TensorFlow avec la précision mixte. Pour en savoir plus, consultez cet article.
Veuillez noter que cette fonctionnalité n'est prise en charge que dans le conteneur Docker TensorFlow de NVIDIA. Pour intégrer la précision mixte de manière native avec tf.keras, nous vous suggérons de lire cet article. Merci à Abhishek Thanki de nous l'avoir signalé.
8. Entraînement distribué
TensorFlow 2.0 facilite grandement la distribution de l'entraînement sur plusieurs GPU. C'est particulièrement utile en production pour faire face à de très fortes charges. Il suffit d'englober votre bloc d'entraînement dans un bloc with.
Commencez par définir une stratégie de distribution :
La stratégie « mirrored » crée une réplique par GPU, et les variables du modèle sont répliquées de manière identique. Vous pouvez ensuite utiliser la stratégie ainsi :
with mirrored_strategy.scope():
model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
model.compile(loss='mse', optimizer='sgd')
model.fit(X_train, y_train,
validation_data=(X_test, y_test),
batch_size=128,
epochs=10)Propulsé par
Remarque : ce code n'est utile que si vous avez plusieurs GPU configurés sur une même machine. Il existe plusieurs stratégies de distribution à configurer. Plus d'informations ici.
9. TensorBoard dans Jupyter Notebook
C'est sans doute la nouveauté la plus enthousiasmante. Vous pouvez visualiser l'entraînement du modèle directement dans votre Jupyter Notebook via TensorBoard. Le nouveau TensorBoard apporte de nombreuses fonctionnalités comme le profilage mémoire, l'affichage d'images (dont matrice de confusion), le graphe conceptuel du modèle, etc. En savoir plus ici.
Dans cette section, vous allez configurer votre environnement pour afficher TensorBoard dans Jupyter Notebook. Commencez par charger l'extension tensorboard.notebook :
Définissez ensuite le callback TensorBoard via le module tf.keras.callbacks.
from datetime import datetime
import os
# Créer un répertoire pour stocker les journaux d'entraînement
os.mkdir("logs")# Définir le callback
logdir ="logs"
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=logdir)Propulsé par
Reconstruisez le modèle avec l'API Sequential de tf.keras :
# Définir le modèle
model = tf.keras.Sequential([
tf.keras.layers.Dropout(rate=0.2, input_shape=X_train.shape[1:]),
tf.keras.layers.Dense(units=64, activation='relu'),
tf.keras.layers.Dropout(rate=0.2),
tf.keras.layers.Dense(units=64, activation='relu'),
tf.keras.layers.Dropout(rate=0.2),
tf.keras.layers.Dense(units=1, activation='sigmoid')])# Compiler le modèle
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])Propulsé par
Les jeux d'entraînement et de test ont été modifiés pour différents usages. Mieux vaut les redécouper :
# Découpage
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=7)Propulsé par
Vous pouvez lancer l'entraînement :
# Extension TensorBoard%tensorboard --logdir logs/# Passer le callback TensorBoard défini
model.fit(X_train, y_train,
validation_data=(X_test, y_test),
batch_size=64,
epochs=10,
callbacks=[tensorboard_callback],
verbose=False)Propulsé par
<iframe
width="100%"
height="800"
src="http://localhost:6006"
frameborder="0"
allowfullscreen
></iframe><tensorflow.python.keras.callbacks.History at 0x7fc215b69400>Propulsé par
Le tableau de bord TensorBoard devrait se charger dans votre Jupyter Notebook et vous permettre de suivre les métriques d'entraînement et de validation.
10. TensorFlow pour Swift
Malgré tous ses succès, un point regrettable avec Python est sa lenteur. Pour aider chercheurs, praticiens et débutants, l'équipe TensorFlow a développé une variante pour Swift. Bien que moins mûre pour la production que la version Python, elle a un vrai potentiel. Swift permet des interactions plus bas niveau et des modules de compilation avancés. Vous trouverez tout sur la variante Swift de TensorFlow ici. Nous vous recommandons aussi cette interview de Jeremy Howard par Josh Gordon, où Jeremy partage sa vision.
Et ensuite ?
Vous arrivez au terme de cet article. La beauté du deep learning réside dans ses applications. Votre prochain réflexe devrait être d'expérimenter les idées présentées ici et de les intégrer à vos projets. Cette mise à jour de TensorFlow compte parmi les plus complètes et les plus favorables aux développeurs. Pensez à consulter la playlist YouTube du TensorFlow Dev Summit de cette année, avec des nouveautés sur TensorFlow lattice, TensorFlow probability, TensorFlow lite, et bien plus.
Pour renforcer vos connaissances en deep learning, explorez ces cours :
L'essor du développement de l'intelligence artificielle (IA) a entraîné une augmentation notable de la demande en matière de calcul, d'où la nécessité de disposer de solutions matérielles robustes. Les unités de traitement graphique (GPU) et les unités de traitement tensoriel (TPU) sont devenues des technologies essentielles pour répondre à ces demandes.
Découvrez les fonctions et méthodes des listes Python. Veuillez suivre les exemples de code pour list() et d'autres fonctions et méthodes Python dès maintenant.
Découvrez les fonctions lambda Python, leur utilité et quand les utiliser. Comprend des exemples pratiques et des bonnes pratiques pour une mise en œuvre efficace.
TensorFlow 2.0 alphaest désormais disponible. Ce framework a un impact considérable sur la communauté du deep learning. Chercheurs, développeurs, praticiens l'ont adopté comme jamais auparavant. Il est sans conteste l'un des moteurs du décollage des applications d'apprentissage profond les plus impressionnantes que nous voyons aujourd'hui. Cela étant dit,TensorFlow 1.xa aussi ses limites (comme beaucoup d'autres frameworks). Comme l'a dit Martin Wicke (Software Engineer de l'équipeTensorFlow) lors du TF Dev Summit 2019 :Fort de ces enseignements issus d'une large base d'utilisateurs et des issues GitHub, l'équipe
TensorFlowa publiéTensorFlow 2.0 alpha, qui apporte de nombreux changements importants pour améliorer les performances, l'expérience développeur, etc. Vous pouvez ainsi prototyper rapidement et bénéficier de nombreuses pratiques modernes de deep learning. Dans cet article, vous étudierez certaines de ces évolutions au travers d'implémentations concises.Remarque : les mises à jour présentées ici sont, selon l'auteur, les plus significatives. Vous aurez besoin d'une expérience préalable avec
TensorFlowetKeraspour suivre l'article. Voici quelques ressources utiles si vous souhaitez un rappel surTensorFlowetKeras:Installation et jeu de données de démonstration
Pour mettre à jour vers
TensorFlow 2.0, exécutez la ligne suivante dans un Jupyter Notebook :!pip install tensorflow==2.0.0-alpha0La variante GPU peut être installée de la même manière (CUDA requis au préalable) :
!pip install tensorflow-gpu==2.0.0-alpha0Vous trouverez plus d'informations sur le processus d'installation ici.
Plusieurs mises à jour étudiées ci-dessous incluent des implémentations en code. Dans ces cas, vous aurez besoin d'un jeu de données. Pour cet article, vous utiliserez le jeu de données Adult de l'UCI Archive.
Ce jeu de données correspond à une tâche de classification binaire : prédire si une personne gagnera plus de 50 000 $ par an ou non, à partir d'un ensemble d'informations personnelles.
Effectuons un prétraitement basique, puis créons des jeux d'entraînement et de test selon un découpage 80:20 :
À ce stade, votre environnement est opérationnel avec
TensorFlow 2.0installé et un jeu de données chargé dans votre espace de travail. Passons maintenant aux nouveautés.1. Eager execution activée par défaut
Avec
TensorFlow 2.0, plus besoin de créer une session et d'exécuter le graphe de calcul à l'intérieur. L'eager execution est activée par défaut dans la version 2.0, ce qui permet de construire vos modèles et de les exécuter immédiatement. Vous pouvez choisir de la désactiver ainsi :tf.compat.v1.disable_eager_execution()(en supposant quetensorflowest importé sous l'aliastf.)Voici une petite comparaison en code qui illustre la différence :
2. tf.function et AutoGraph
Si l'eager execution offre une programmation impérative, pour l'entraînement distribué, l'optimisation à grande échelle et la production, l'exécution en graphe à la
TensorFlow 1.xconserve des atouts. AvecTensorFlow 2.0, vous conservez l'exécution basée sur des graphes, mais de manière plus flexible, grâce àtf.functionet àAutoGraph.tf.functionvous permet de définir des graphesTensorFlowavec une syntaxe de type Python via la fonctionnalitéAutoGraph.AutoGraphprend en charge un ensemble étendu de constructions Python, notammentif,for,while,iterators, etc. Il existe toutefois des limitations. Vous trouverez ici la liste complète des compatibilités actuellement disponibles. Ci-dessous, un exemple montrant avec quelle facilité définir un grapheTensorFlowavec un simpledecorator.Notez que vous n'avez pas eu à créer de sessions ni de placeholders pour exécuter la fonction
single_layer(). C'est l'un des atouts detf.function. En coulisses, il applique les optimisations nécessaires pour accélérer votre code.3.
tf.variable_scopen'est plus nécessaireDans
TensorFlow 1.x, pour utilisertf.layerscomme variables et les réutiliser, vous deviez recourir au bloctf.variable. Ce n'est plus le cas avecTensorFlow 2.0.kerasétant l'API haut niveau centrale deTensorFlow 2.0, toutes les couches créées avectf.layerspeuvent être intégrées facilement dans une définitiontf.keras.Sequential. Le code est plus lisible et vous suivez aisément variables et pertes.Exemple :
Dans l'exemple ci-dessus, vous avez simplement fait passer les données d'entraînement dans le
modelpour récupérer les probabilités brutes. Il s'agit d'une passe avant. Vous pouvez bien sûr entraîner le modèle :Vous pouvez lister les paramètres entraînables du modèle couche par couche ainsi :
4. Couches personnalisées simplifiées
En recherche comme en production, il est souvent nécessaire d'écrire des couches personnalisées pour des cas d'usage spécifiques.
TensorFlow 2.0facilite grandement l'écriture d'une couche custom et son utilisation avec les couches existantes. Vous pouvez aussi personnaliser la passe avant de votre modèle comme vous le souhaitez.Pour créer une couche personnalisée, l'option la plus simple est d'étendre la classe
Layerdetf.keras.layerspuis de la définir en conséquence. Vous créerez une couche custom et définirez ses calculs de passe avant. Voici la sortie dehelp(tf.keras.layers.Layer), qui indique ce qu'il faut spécifier pour y parvenir :En suivant ces indications, vous allez :
build(), ajouter les poids de la couchecall(), définir la passe avant en chaînant multiplication de matrices etrelu()Vous pouvez composer plusieurs couches en étendant la classe
Modeldetf.keras. En savoir plus sur la composition de modèles ici.5. Plus de flexibilité pour l'entraînement des modèles
TensorFlowutilise la différenciation automatique pour calculer les gradients de la fonction de perte par rapport aux paramètres du modèle.tf.GradientTapecrée un contexte (tape) dans lequelTensorFlowenregistre les opérations dont les gradients seront calculés. Pour illustrer, définissons un modèle à plus bas niveau en étendant la classetf.keras.Model.La topologie de ce modèle est exactement la même que celle définie plus haut. Pour l'entraîner via différenciation automatique, définissez la fonction de perte et l'optimiseur comme suit :
Définissons maintenant les métriques utilisées pour mesurer les performances pendant l'entraînement, à savoir la perte et la précision du modèle.
tf.datafournit des utilitaires pour définir des pipelines de données d'entrée. C'est particulièrement utile avec de grands volumes de données.Vous allez maintenant définir le générateur de données qui produira des batchs pendant l'entraînement.
Vous êtes prêt à entraîner le modèle avec
tf.GradientTape. Commencez par définir une méthode qui entraîne le modèle avec les données fournies viatf.data.DataSet. Enveloppez aussi les étapes d'entraînement dans le décorateurtf.functionpour bénéficier des gains de performance.Entraînement et validation du modèle
Utilisez ces deux méthodes pour entraîner et valider le modèle sur 5 époques.
Cet exemple s'inspire de cet exemple proposé par les auteurs de
TensorFlow 2.0.6. TensorFlow Datasets
Un module séparé nommé
DataSetspermet d'opérer avec le modèle de manière élégante. Vous l'avez déjà aperçu plus haut. Dans cette section, voyons comment charger MNIST comme vous le souhaitez.Installez la bibliothèque
tensorflow_datasetsavecpip. Une fois installée, vous êtes prêt. Elle propose plusieurs fonctions utilitaires pour préparer votre pipeline de construction de données avec souplesse. Pour en savoir plus, consultez ce dépôt et cette vidéo. Voici comment construire un pipeline d'entrée pour charger MNIST.Vous pouvez ignorer l'avertissement. Remarquez la simplicité avec laquelle
tensorflow_datasetsgère le pipeline.Vous pouvez maintenant afficher la première image parmi celles chargées. Remarque :
tensorflow_datasetsfonctionne aussi bien en mode eager qu'en mode graphe.7. Politique de précision mixte automatique
La politique de précision mixte a été proposée par NVIDIA l'année dernière. L'article original est disponible ici. L'idée : utiliser un mélange de demi-précision (FP16) et de pleine précision (FP32) pour tirer le meilleur des deux. Les gains observés pour l'entraînement de réseaux très profonds sont remarquables (temps et scores).
Si vous disposez d'un environnement GPU compatible CUDA (génération Volta, Tesla T4 par exemple) et que vous avez installé la variante GPU de
TensorFlow 2.0, vous pouvez demander àTensorFlowd'entraîner en précision mixte ainsi :os.environ['TF_ENABLE_AUTO_MIXED_PRECISION'] = '1'Les opérations du graphe TensorFlow seront alors castées automatiquement. Vous observerez souvent un gain notable de performance. Vous pouvez également optimiser les opérations cœur de TensorFlow avec la précision mixte. Pour en savoir plus, consultez cet article.
Veuillez noter que cette fonctionnalité n'est prise en charge que dans le conteneur Docker TensorFlow de NVIDIA. Pour intégrer la précision mixte de manière native avec tf.keras, nous vous suggérons de lire cet article. Merci à Abhishek Thanki de nous l'avoir signalé.
8. Entraînement distribué
TensorFlow 2.0facilite grandement la distribution de l'entraînement sur plusieurs GPU. C'est particulièrement utile en production pour faire face à de très fortes charges. Il suffit d'englober votre bloc d'entraînement dans un blocwith.Commencez par définir une stratégie de distribution :
mirrored_strategy = tf.distribute.MirroredStrategy()La stratégie « mirrored » crée une réplique par GPU, et les variables du modèle sont répliquées de manière identique. Vous pouvez ensuite utiliser la stratégie ainsi :
Remarque : ce code n'est utile que si vous avez plusieurs GPU configurés sur une même machine. Il existe plusieurs stratégies de distribution à configurer. Plus d'informations ici.
9. TensorBoard dans Jupyter Notebook
C'est sans doute la nouveauté la plus enthousiasmante. Vous pouvez visualiser l'entraînement du modèle directement dans votre Jupyter Notebook via
TensorBoard. Le nouveauTensorBoardapporte de nombreuses fonctionnalités comme le profilage mémoire, l'affichage d'images (dont matrice de confusion), le graphe conceptuel du modèle, etc. En savoir plus ici.Dans cette section, vous allez configurer votre environnement pour afficher
TensorBoarddans Jupyter Notebook. Commencez par charger l'extensiontensorboard.notebook:Définissez ensuite le callback
TensorBoardvia le moduletf.keras.callbacks.Reconstruisez le modèle avec l'API
Sequentialdetf.keras:Les jeux d'entraînement et de test ont été modifiés pour différents usages. Mieux vaut les redécouper :
Vous pouvez lancer l'entraînement :
Le tableau de bord
TensorBoarddevrait se charger dans votre Jupyter Notebook et vous permettre de suivre les métriques d'entraînement et de validation.10. TensorFlow pour Swift
Malgré tous ses succès, un point regrettable avec Python est sa lenteur. Pour aider chercheurs, praticiens et débutants, l'équipe
TensorFlowa développé une variante pour Swift. Bien que moins mûre pour la production que la version Python, elle a un vrai potentiel. Swift permet des interactions plus bas niveau et des modules de compilation avancés. Vous trouverez tout sur la variante Swift de TensorFlow ici. Nous vous recommandons aussi cette interview de Jeremy Howard par Josh Gordon, où Jeremy partage sa vision.Et ensuite ?
Vous arrivez au terme de cet article. La beauté du deep learning réside dans ses applications. Votre prochain réflexe devrait être d'expérimenter les idées présentées ici et de les intégrer à vos projets. Cette mise à jour de
TensorFlowcompte parmi les plus complètes et les plus favorables aux développeurs. Pensez à consulter la playlist YouTube duTensorFlowDev Summit de cette année, avec des nouveautés surTensorFlow lattice,TensorFlow probability,TensorFlow lite, et bien plus.Pour renforcer vos connaissances en deep learning, explorez ces cours :
Bon
eager_executing !