Cette page a été traduite par l'API Cloud Translation.
Switch to English

Migrez votre code TensorFlow 1 vers TensorFlow 2

Voir sur TensorFlow.org Exécuter dans Google Colab Afficher la source sur GitHub Télécharger le carnet

Ce document est destiné aux utilisateurs d'API TensorFlow de bas niveau. Si vous utilisez les API de haut niveau ( tf.keras ), il se peut que vous tf.keras que peu ou pas d'action à entreprendre pour rendre votre code entièrement compatible avec TensorFlow 2.0:

Il est toujours possible d'exécuter du code 1.X, non modifié ( sauf pour contrib ), dans TensorFlow 2.0:

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

Cependant, cela ne vous permet pas de profiter de la plupart des améliorations apportées à TensorFlow 2.0. Ce guide vous aidera à mettre à jour votre code, le rendant plus simple, plus performant et plus facile à maintenir.

Script de conversion automatique

La première étape, avant d'essayer d'implémenter les changements décrits dans ce document, est d'essayer d'exécuter le script de mise à niveau .

Cela fera une première étape lors de la mise à niveau de votre code vers TensorFlow 2.0. Mais cela ne peut pas rendre votre code idiomatique à 2.0. Votre code peut toujours utiliser les points de terminaison tf.compat.v1 pour accéder aux espaces réservés, aux sessions, aux collections et à d'autres fonctionnalités de style 1.x.

Changements de comportement de haut niveau

Si votre code fonctionne dans TensorFlow 2.0 à l'aide de tf.compat.v1.disable_v2_behavior() , vous devrez peut-être corriger des changements de comportement globaux. Les principaux changements sont:

  • Eager execution, v1.enable_eager_execution() : Tout code qui utilise implicitement un tf.Graph échouera. Assurez-vous d'encapsuler ce code dans un with tf.Graph().as_default() .

  • Variables de ressources, v1.enable_resource_variables() : Certains codes peuvent dépendre de comportements non déterministes activés par les variables de référence TF. Les variables de ressources sont verrouillées lors de l'écriture et offrent ainsi des garanties de cohérence plus intuitives.

    • Cela peut changer le comportement dans les cas extrêmes.
    • Cela peut créer des copies supplémentaires et peut avoir une utilisation de la mémoire plus élevée.
    • Cela peut être désactivé en passant use_resource=False au constructeur tf.Variable .
  • v1.enable_v2_tensorshape() tensorielles, v1.enable_v2_tensorshape() : TF 2.0 simplifie le comportement des formes tensorielles. Au lieu de t.shape[0].value vous pouvez dire t.shape[0] . Ces changements doivent être minimes et il est logique de les corriger immédiatement. Voir TensorShape pour des exemples.

  • Flux de contrôle, v1.enable_control_flow_v2() : L'implémentation du flux de contrôle TF 2.0 a été simplifiée et produit ainsi différentes représentations graphiques. Veuillez signaler les bogues pour tout problème.

Rendre le code 2.0 natif

Ce guide présente plusieurs exemples de conversion de code TensorFlow 1.x en TensorFlow 2.0. Ces modifications permettront à votre code de tirer parti des optimisations des performances et des appels d'API simplifiés.

Dans chaque cas, le motif est:

1. Remplacez les appels v1.Session.run

Chaque appel v1.Session.run doit être remplacé par une fonction Python.

  • Les feed_dict et v1.placeholder deviennent des arguments de fonction.
  • Les fetches deviennent la valeur de retour de la fonction.
  • Pendant la conversion, une exécution rapide permet un débogage facile avec des outils Python standard tels que pdb .

Après cela, ajoutez un décorateur tf.function pour le faire fonctionner efficacement dans le graphe. Consultez le Guide des autographes pour en savoir plus sur son fonctionnement.

Notez que:

  • Contrairement à v1.Session.run une tf.function a une signature de retour fixe et renvoie toujours toutes les sorties. Si cela entraîne des problèmes de performances, créez deux fonctions distinctes.

  • Il n'y a pas besoin de tf.control_dependencies ou d'opérations similaires: une tf.function se comporte comme si elle était exécutée dans l'ordre d'écriture. tf.Variable affectations tf.Variable et tf.assert s, par exemple, sont exécutées automatiquement.

La section des modèles de conversion contient un exemple fonctionnel de ce processus de conversion.

2. Utilisez des objets Python pour suivre les variables et les pertes

Tout suivi de variable basé sur le nom est fortement déconseillé dans TF 2.0. Utilisez des objets Python pour suivre les variables.

Utilisez tf.Variable au lieu de v1.get_variable .

Chaque v1.variable_scope doit être converti en objet Python. En règle générale, ce sera l'un des:

Si vous avez besoin d'agréger des listes de variables (comme tf.Graph.get_collection(tf.GraphKeys.VARIABLES) ), utilisez les .variables et .trainable_variables des objets Layer et Model .

Ces classes Layer et Model implémentent plusieurs autres propriétés qui suppriment le besoin de collections globales. Leur propriété .losses peut remplacer l'utilisation de la collection tf.GraphKeys.LOSSES .

Consultez les guides Keras pour plus de détails.

3. Améliorez vos boucles d'entraînement

Utilisez l'API de plus haut niveau qui fonctionne pour votre cas d'utilisation. Préférez tf.keras.Model.fit à la création de vos propres boucles d'entraînement.

Ces fonctions de haut niveau gèrent une grande partie des détails de bas niveau qui pourraient être faciles à manquer si vous écrivez votre propre boucle d'entraînement. Par exemple, ils collectent automatiquement les pertes de régularisation et définissent l'argument training=True lors de l'appel du modèle.

4. Mettez à niveau vos pipelines d'entrée de données

Utilisez les ensembles de données tf.data pour l'entrée de données. Ces objets sont efficaces, expressifs et s'intègrent bien avec tensorflow.

Ils peuvent être transmis directement à la méthode tf.keras.Model.fit .

model.fit(dataset, epochs=5)

Ils peuvent être itérés sur Python directement standard:

for example_batch, label_batch in dataset:
    break

5. compat.v1 symboles compat.v1

Le module tf.compat.v1 contient l'API TensorFlow 1.x complète, avec sa sémantique d'origine.

Le script de mise à niveau TF2 convertira les symboles en leurs équivalents 2.0 si une telle conversion est sûre, c'est-à-dire s'il peut déterminer que le comportement de la version 2.0 est exactement équivalent (par exemple, il renommera v1.arg_max en tf.argmax , car ce sont la même fonction).

Une fois le script de mise à niveau terminé avec un morceau de code, il est probable qu'il y ait de nombreuses mentions de compat.v1 . Il vaut la peine de parcourir le code et de les convertir manuellement en l'équivalent 2.0 (cela devrait être mentionné dans le journal s'il y en a un).

Conversion de modèles

Variables de bas niveau et exécution des opérateurs

Exemples d'utilisation d'API de bas niveau:

  • utilisation de portées variables pour contrôler la réutilisation
  • création de variables avec v1.get_variable .
  • accéder explicitement aux collections
  • accéder implicitement aux collections avec des méthodes comme:

  • utilisation de v1.placeholder pour configurer les entrées graphiques

  • exécution de graphiques avec Session.run

  • initialisation manuelle des variables

Avant de convertir

Voici à quoi ces modèles peuvent ressembler dans le code utilisant TensorFlow 1.x.

import tensorflow as tf
import tensorflow.compat.v1 as v1

import tensorflow_datasets as tfds
g = v1.Graph()

with g.as_default():
  in_a = v1.placeholder(dtype=v1.float32, shape=(2))
  in_b = v1.placeholder(dtype=v1.float32, shape=(2))

  def forward(x):
    with v1.variable_scope("matmul", reuse=v1.AUTO_REUSE):
      W = v1.get_variable("W", initializer=v1.ones(shape=(2,2)),
                          regularizer=lambda x:tf.reduce_mean(x**2))
      b = v1.get_variable("b", initializer=v1.zeros(shape=(2)))
      return W * x + b

  out_a = forward(in_a)
  out_b = forward(in_b)
  reg_loss=v1.losses.get_regularization_loss(scope="matmul")

with v1.Session(graph=g) as sess:
  sess.run(v1.global_variables_initializer())
  outs = sess.run([out_a, out_b, reg_loss],
                feed_dict={in_a: [1, 0], in_b: [0, 1]})

print(outs[0])
print()
print(outs[1])
print()
print(outs[2])
[[1. 0.]
 [1. 0.]]

[[0. 1.]
 [0. 1.]]

1.0

Après la conversion

Dans le code converti:

  • Les variables sont des objets Python locaux.
  • La fonction forward définit toujours le calcul.
  • L'appel Session.run est remplacé par un appel à forward
  • Le décorateur optionnel tf.function peut être ajouté pour la performance.
  • Les régularisations sont calculées manuellement, sans faire référence à aucune collection globale.
  • Pas de session ni d'espace réservé.
W = tf.Variable(tf.ones(shape=(2,2)), name="W")
b = tf.Variable(tf.zeros(shape=(2)), name="b")

@tf.function
def forward(x):
  return W * x + b

out_a = forward([1,0])
print(out_a)
tf.Tensor(
[[1. 0.]
 [1. 0.]], shape=(2, 2), dtype=float32)

out_b = forward([0,1])

regularizer = tf.keras.regularizers.l2(0.04)
reg_loss=regularizer(W)

Modèles basés sur tf.layers

Le module v1.layers est utilisé pour contenir des fonctions de couche qui s'appuyaient sur v1.variable_scope pour définir et réutiliser des variables.

Avant de convertir

def model(x, training, scope='model'):
  with v1.variable_scope(scope, reuse=v1.AUTO_REUSE):
    x = v1.layers.conv2d(x, 32, 3, activation=v1.nn.relu,
          kernel_regularizer=lambda x:0.004*tf.reduce_mean(x**2))
    x = v1.layers.max_pooling2d(x, (2, 2), 1)
    x = v1.layers.flatten(x)
    x = v1.layers.dropout(x, 0.1, training=training)
    x = v1.layers.dense(x, 64, activation=v1.nn.relu)
    x = v1.layers.batch_normalization(x, training=training)
    x = v1.layers.dense(x, 10)
    return x
train_data = tf.ones(shape=(1, 28, 28, 1))
test_data = tf.ones(shape=(1, 28, 28, 1))

train_out = model(train_data, training=True)
test_out = model(test_data, training=False)

print(train_out)
print()
print(test_out)
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:4: conv2d (from tensorflow.python.keras.legacy_tf_layers.convolutional) is deprecated and will be removed in a future version.
Instructions for updating:
Use `tf.keras.layers.Conv2D` instead.
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/convolutional.py:424: Layer.apply (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `layer.__call__` method instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:5: max_pooling2d (from tensorflow.python.keras.legacy_tf_layers.pooling) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.MaxPooling2D instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:6: flatten (from tensorflow.python.keras.legacy_tf_layers.core) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.Flatten instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:7: dropout (from tensorflow.python.keras.legacy_tf_layers.core) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.dropout instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:8: dense (from tensorflow.python.keras.legacy_tf_layers.core) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.Dense instead.
WARNING:tensorflow:From <ipython-input-1-1c8189d0d453>:9: batch_normalization (from tensorflow.python.keras.legacy_tf_layers.normalization) is deprecated and will be removed in a future version.
Instructions for updating:
Use keras.layers.BatchNormalization instead.  In particular, `tf.control_dependencies(tf.GraphKeys.UPDATE_OPS)` should not be used (consult the `tf.keras.layers.BatchNormalization` documentation).
tf.Tensor([[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]], shape=(1, 10), dtype=float32)

tf.Tensor(
[[ 0.25911403  0.04995662 -0.29216325 -0.2735252  -0.3113699  -0.00610226
  -0.00793289 -0.02005042 -0.22002988 -0.11050846]], shape=(1, 10), dtype=float32)

Après la conversion

La plupart des arguments sont restés les mêmes. Mais notez les différences:

  • L'argument d' training est transmis à chaque couche par le modèle lors de son exécution.
  • Le premier argument de la fonction de model origine (l'entrée x ) a disparu. En effet, les calques d'objets séparent la construction du modèle de l'appel du modèle.

Notez également que:

  • Si vous utilisiez des régularisateurs d'initialiseurs de tf.contrib , ceux-ci ont plus de changements d'arguments que d'autres.
  • Le code n'écrit plus dans les collections, donc des fonctions comme v1.losses.get_regularization_loss ne v1.losses.get_regularization_loss plus ces valeurs, ce qui pourrait interrompre vos boucles d'entraînement.
model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.04),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

train_data = tf.ones(shape=(1, 28, 28, 1))
test_data = tf.ones(shape=(1, 28, 28, 1))
train_out = model(train_data, training=True)
print(train_out)
tf.Tensor([[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]], shape=(1, 10), dtype=float32)

test_out = model(test_data, training=False)
print(test_out)
tf.Tensor(
[[-0.04179893 -0.07949039 -0.21679714  0.11532308  0.15619203 -0.0883522
   0.12719868 -0.0547747  -0.03558816  0.02265415]], shape=(1, 10), dtype=float32)

# Here are all the trainable variables.
len(model.trainable_variables)
8
# Here is the regularization loss.
model.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=0.083086945>]

Variables mixtes et v1.layers

Le code existant mélange souvent des variables et des opérations TF 1.x de niveau inférieur avec des v1.layers niveau v1.layers .

Avant de convertir

def model(x, training, scope='model'):
  with v1.variable_scope(scope, reuse=v1.AUTO_REUSE):
    W = v1.get_variable(
      "W", dtype=v1.float32,
      initializer=v1.ones(shape=x.shape),
      regularizer=lambda x:0.004*tf.reduce_mean(x**2),
      trainable=True)
    if training:
      x = x + W
    else:
      x = x + W * 0.5
    x = v1.layers.conv2d(x, 32, 3, activation=tf.nn.relu)
    x = v1.layers.max_pooling2d(x, (2, 2), 1)
    x = v1.layers.flatten(x)
    return x

train_out = model(train_data, training=True)
test_out = model(test_data, training=False)

Après la conversion

Pour convertir ce code, suivez le modèle de mappage de couches en couches comme dans l'exemple précédent.

Le schéma général est:

  • Collectez les paramètres de couche dans __init__ .
  • Construisez les variables dans build .
  • Exécutez les calculs en cours d' call et renvoyez le résultat.

La v1.variable_scope est essentiellement une couche à part entière. tf.keras.layers.Layer donc en tant que tf.keras.layers.Layer . Consultez le guide pour plus de détails.

# Create a custom layer for part of the model
class CustomLayer(tf.keras.layers.Layer):
  def __init__(self, *args, **kwargs):
    super(CustomLayer, self).__init__(*args, **kwargs)

  def build(self, input_shape):
    self.w = self.add_weight(
        shape=input_shape[1:],
        dtype=tf.float32,
        initializer=tf.keras.initializers.ones(),
        regularizer=tf.keras.regularizers.l2(0.02),
        trainable=True)

  # Call method will sometimes get used in graph mode,
  # training will get turned into a tensor
  @tf.function
  def call(self, inputs, training=None):
    if training:
      return inputs + self.w
    else:
      return inputs + self.w * 0.5
custom_layer = CustomLayer()
print(custom_layer([1]).numpy())
print(custom_layer([1], training=True).numpy())
[1.5]
[2.]

train_data = tf.ones(shape=(1, 28, 28, 1))
test_data = tf.ones(shape=(1, 28, 28, 1))

# Build the model including the custom layer
model = tf.keras.Sequential([
    CustomLayer(input_shape=(28, 28, 1)),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
])

train_out = model(train_data, training=True)
test_out = model(test_data, training=False)

Quelques points à noter:

  • Les modèles et couches Keras sous-classés doivent s'exécuter à la fois dans les graphiques v1 (pas de dépendances de contrôle automatique) et en mode hâte

    • Enveloppez l' call() dans un tf.function() pour obtenir l'autographe et les dépendances de contrôle automatique
  • N'oubliez pas d'accepter un argument d' training à call .

    • Parfois, c'est un tf.Tensor
    • Parfois, il s'agit d'un booléen Python.
  • Créez des variables de modèle dans constructor ou Model.build utilisant self.add_weight() .

    • Dans Model.build vous avez accès à la forme d'entrée, vous pouvez donc créer des poids avec une forme correspondante.
    • L'utilisation de tf.keras.layers.Layer.add_weight permet à Keras de suivre les variables et les pertes de régularisation.
  • Ne gardez pas tf.Tensors dans vos objets.

    • Ils peuvent être créés soit dans une fonction tf.function soit dans le contexte tf.function , et ces tenseurs se comportent différemment.
    • Utilisez tf.Variable s pour state, elles sont toujours utilisables dans les deux contextes
    • tf.Tensors sont uniquement pour les valeurs intermédiaires.

Une note sur Slim & contrib.layers

Une grande quantité de code TensorFlow 1.x plus ancien utilise la bibliothèque Slim , qui était fournie avec TensorFlow 1.x en tant que tf.contrib.layers . En tant que module contrib , il n'est plus disponible dans TensorFlow 2.0, même dans tf.compat.v1 . La conversion de code à l'aide de Slim vers TF 2.0 est plus v1.layers que la conversion de référentiels utilisant des v1.layers . En fait, il peut être judicieux de convertir d'abord votre code Slim en v1.layers , puis de le convertir en Keras.

  • Supprimer arg_scopes , tous les arg_scopes doivent être explicites
  • Si vous les utilisez, divisez normalizer_fn et activation_fn dans leurs propres couches
  • Les couches de conversion séparables correspondent à une ou plusieurs couches Keras différentes (couches Keras en profondeur, ponctuelles et séparables)
  • Slim et v1.layers ont des noms d'arg et des valeurs par défaut différents
  • Certains arguments ont des échelles différentes
  • Si vous utilisez des modèles pré-formés Slim, essayez les modèles pré-formés de Keras à partir de tf.keras.applications ou TF2 SavedModels de TF Hub exportés à partir du code Slim original.

Certaines couches de tf.contrib peut-être pas été déplacées vers le noyau TensorFlow, mais ont plutôt été déplacées vers le package de modules complémentaires TF .

Formation

Il existe de nombreuses façons d'alimenter des données dans un modèle tf.keras . Ils accepteront les générateurs Python et les tableaux Numpy en entrée.

La méthode recommandée pour tf.data données à un modèle consiste à utiliser le package tf.data , qui contient une collection de classes hautes performances pour manipuler les données.

Si vous utilisez toujours tf.queue , ceux-ci sont désormais uniquement pris en charge en tant que structures de données et non en tant que pipelines d'entrée.

Utilisation des ensembles de données

Le package TensorFlow Datasets ( tfds ) contient des utilitaires pour charger des ensembles de données prédéfinis en tant tf.data.Dataset .

Pour cet exemple, chargez l'ensemble de données MNIST, à l'aide de tfds :

datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets['train'], datasets['test']
WARNING:absl:Dataset mnist is hosted on GCS. It will automatically be downloaded to your
local data directory. If you'd instead prefer to read directly from our public
GCS bucket (recommended if you're running on GCP), you can instead pass
`try_gcs=True` to `tfds.load` or set `data_dir=gs://tfds-data/datasets`.


Downloading and preparing dataset mnist/3.0.1 (download: 11.06 MiB, generated: 21.00 MiB, total: 32.06 MiB) to /home/kbuilder/tensorflow_datasets/mnist/3.0.1...
Dataset mnist downloaded and prepared to /home/kbuilder/tensorflow_datasets/mnist/3.0.1. Subsequent calls will reuse this data.

Préparez ensuite les données pour la formation:

  • Redimensionnez chaque image.
  • Mélangez l'ordre des exemples.
  • Collectez des lots d'images et d'étiquettes.
BUFFER_SIZE = 10 # Use a much larger value for real code.
BATCH_SIZE = 64
NUM_EPOCHS = 5


def scale(image, label):
  image = tf.cast(image, tf.float32)
  image /= 255

  return image, label

Pour garder l'exemple court, coupez le jeu de données pour ne renvoyer que 5 lots:

train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
test_data = mnist_test.map(scale).batch(BATCH_SIZE)

STEPS_PER_EPOCH = 5

train_data = train_data.take(STEPS_PER_EPOCH)
test_data = test_data.take(STEPS_PER_EPOCH)
image_batch, label_batch = next(iter(train_data))

Utiliser les boucles d'entraînement Keras

Si vous n'avez pas besoin d'un contrôle de bas niveau de votre processus d'entraînement, il est recommandé d'utiliser les méthodes intégrées d' fit , d' evaluate et de predict Keras. Ces méthodes fournissent une interface uniforme pour entraîner le modèle quelle que soit l'implémentation (séquentielle, fonctionnelle ou sous-classée).

Les avantages de ces méthodes comprennent:

  • Ils acceptent les tableaux Numpy, les générateurs Python et, tf.data.Datasets
  • Ils appliquent automatiquement la régularisation et les pertes d'activation.
  • Ils prennent en charge tf.distribute pour la formation multi-appareils .
  • Ils prennent en charge les callables arbitraires en tant que pertes et métriques.
  • Ils prennent en charge les rappels tels que tf.keras.callbacks.TensorBoard et les rappels personnalisés.
  • Ils sont performants et utilisent automatiquement les graphiques TensorFlow.

Voici un exemple d'entraînement d'un modèle à l'aide d'un jeu de Dataset . (Pour plus de détails sur la façon dont cela fonctionne, consultez les didacticiels .)

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

# Model is the full model w/o custom layers
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

model.fit(train_data, epochs=NUM_EPOCHS)
loss, acc = model.evaluate(test_data)

print("Loss {}, Accuracy {}".format(loss, acc))
Epoch 1/5
5/5 [==============================] - 0s 6ms/step - loss: 1.4729 - accuracy: 0.5437
Epoch 2/5
5/5 [==============================] - 0s 6ms/step - loss: 0.4612 - accuracy: 0.9125
Epoch 3/5
5/5 [==============================] - 0s 6ms/step - loss: 0.3007 - accuracy: 0.9594
Epoch 4/5
5/5 [==============================] - 0s 6ms/step - loss: 0.2222 - accuracy: 0.9875
Epoch 5/5
5/5 [==============================] - 0s 6ms/step - loss: 0.1858 - accuracy: 0.9875
5/5 [==============================] - 0s 4ms/step - loss: 1.5550 - accuracy: 0.5594
Loss 1.5550143718719482, Accuracy 0.559374988079071

Écrivez votre propre boucle

Si l'étape d'entraînement du modèle Keras fonctionne pour vous, mais que vous avez besoin de plus de contrôle en dehors de cette étape, envisagez d'utiliser la méthode tf.keras.Model.train_on_batch , dans votre propre boucle d'itération de données.

Rappelez-vous: De nombreuses choses peuvent être implémentées sous forme de tf.keras.callbacks.Callback .

Cette méthode présente de nombreux avantages des méthodes mentionnées dans la section précédente, mais donne à l'utilisateur le contrôle de la boucle externe.

Vous pouvez également utiliser tf.keras.Model.test_on_batch ou tf.keras.Model.evaluate pour vérifier les performances pendant l'entraînement.

Pour continuer à entraîner le modèle ci-dessus:

# Model is the full model w/o custom layers
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

for epoch in range(NUM_EPOCHS):
  #Reset the metric accumulators
  model.reset_metrics()

  for image_batch, label_batch in train_data:
    result = model.train_on_batch(image_batch, label_batch)
    metrics_names = model.metrics_names
    print("train: ",
          "{}: {:.3f}".format(metrics_names[0], result[0]),
          "{}: {:.3f}".format(metrics_names[1], result[1]))
  for image_batch, label_batch in test_data:
    result = model.test_on_batch(image_batch, label_batch,
                                 # return accumulated metrics
                                 reset_metrics=False)
  metrics_names = model.metrics_names
  print("\neval: ",
        "{}: {:.3f}".format(metrics_names[0], result[0]),
        "{}: {:.3f}".format(metrics_names[1], result[1]))
train:  loss: 0.151 accuracy: 1.000
train:  loss: 0.212 accuracy: 0.953
train:  loss: 0.186 accuracy: 0.969
train:  loss: 0.217 accuracy: 0.969
train:  loss: 0.201 accuracy: 0.984

eval:  loss: 1.567 accuracy: 0.597
train:  loss: 0.109 accuracy: 1.000
train:  loss: 0.098 accuracy: 1.000
train:  loss: 0.104 accuracy: 1.000
train:  loss: 0.131 accuracy: 0.984
train:  loss: 0.113 accuracy: 0.984

eval:  loss: 1.545 accuracy: 0.625
train:  loss: 0.076 accuracy: 1.000
train:  loss: 0.087 accuracy: 1.000
train:  loss: 0.081 accuracy: 1.000
train:  loss: 0.081 accuracy: 1.000
train:  loss: 0.077 accuracy: 1.000

eval:  loss: 1.509 accuracy: 0.731
train:  loss: 0.059 accuracy: 1.000
train:  loss: 0.065 accuracy: 1.000
train:  loss: 0.062 accuracy: 1.000
train:  loss: 0.061 accuracy: 1.000
train:  loss: 0.056 accuracy: 1.000

eval:  loss: 1.485 accuracy: 0.781
train:  loss: 0.055 accuracy: 1.000
train:  loss: 0.051 accuracy: 1.000
train:  loss: 0.052 accuracy: 1.000
train:  loss: 0.050 accuracy: 1.000
train:  loss: 0.055 accuracy: 1.000

eval:  loss: 1.464 accuracy: 0.803

Personnalisez l'étape de formation

Si vous avez besoin de plus de flexibilité et de contrôle, vous pouvez l'obtenir en implémentant votre propre boucle d'entraînement. Il y a trois étapes:

  1. Itérez sur un générateur Python ou tf.data.Dataset pour obtenir des lots d'exemples.
  2. Utilisez tf.GradientTape pour collecter les dégradés.
  3. Utilisez l'un des tf.keras.optimizers pour appliquer des mises à jour de poids aux variables du modèle.

Rappelles toi:

  • Incluez toujours un argument d' training sur la méthode d' call des couches et des modèles sous-classés.
  • Assurez-vous d'appeler le modèle avec l'argument d' training correctement défini.
  • Selon l'utilisation, les variables de modèle peuvent ne pas exister tant que le modèle n'est pas exécuté sur un lot de données.
  • Vous devez gérer manuellement des éléments tels que les pertes de régularisation pour le modèle.

Notez les simplifications relatives à la v1:

  • Il n'est pas nécessaire d'exécuter des initialiseurs de variables. Les variables sont initialisées à la création.
  • Il n'est pas nécessaire d'ajouter des dépendances de contrôle manuel. Même dans les opérations tf.function agissent comme en mode hâte.
model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
])

optimizer = tf.keras.optimizers.Adam(0.001)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

@tf.function
def train_step(inputs, labels):
  with tf.GradientTape() as tape:
    predictions = model(inputs, training=True)
    regularization_loss=tf.math.add_n(model.losses)
    pred_loss=loss_fn(labels, predictions)
    total_loss=pred_loss + regularization_loss

  gradients = tape.gradient(total_loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))

for epoch in range(NUM_EPOCHS):
  for inputs, labels in train_data:
    train_step(inputs, labels)
  print("Finished epoch", epoch)

Finished epoch 0
Finished epoch 1
Finished epoch 2
Finished epoch 3
Finished epoch 4

Métriques et pertes de style nouveau

Dans TensorFlow 2.0, les métriques et les pertes sont des objets. Ceux-ci fonctionnent à la fois avec empressement et dans tf.function s.

Un objet de perte est appelable et attend les (y_true, y_pred) comme arguments:

cce = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
cce([[1, 0]], [[-1.0,3.0]]).numpy()
4.01815

Un objet métrique a les méthodes suivantes:

L'objet lui-même est appelable. L'appel met à jour l'état avec de nouvelles observations, comme avec update_state , et renvoie le nouveau résultat de la métrique.

Vous n'avez pas besoin d'initialiser manuellement les variables d'une métrique, et comme TensorFlow 2.0 a des dépendances de contrôle automatique, vous n'avez pas non plus à vous en préoccuper.

Le code ci-dessous utilise une métrique pour suivre la perte moyenne observée dans une boucle d'apprentissage personnalisée.

# Create the metrics
loss_metric = tf.keras.metrics.Mean(name='train_loss')
accuracy_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')

@tf.function
def train_step(inputs, labels):
  with tf.GradientTape() as tape:
    predictions = model(inputs, training=True)
    regularization_loss=tf.math.add_n(model.losses)
    pred_loss=loss_fn(labels, predictions)
    total_loss=pred_loss + regularization_loss

  gradients = tape.gradient(total_loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))
  # Update the metrics
  loss_metric.update_state(total_loss)
  accuracy_metric.update_state(labels, predictions)


for epoch in range(NUM_EPOCHS):
  # Reset the metrics
  loss_metric.reset_states()
  accuracy_metric.reset_states()

  for inputs, labels in train_data:
    train_step(inputs, labels)
  # Get the metric results
  mean_loss=loss_metric.result()
  mean_accuracy = accuracy_metric.result()

  print('Epoch: ', epoch)
  print('  loss:     {:.3f}'.format(mean_loss))
  print('  accuracy: {:.3f}'.format(mean_accuracy))

Epoch:  0
  loss:     0.177
  accuracy: 0.981
Epoch:  1
  loss:     0.150
  accuracy: 0.988
Epoch:  2
  loss:     0.134
  accuracy: 0.997
Epoch:  3
  loss:     0.116
  accuracy: 1.000
Epoch:  4
  loss:     0.097
  accuracy: 1.000

Noms des métriques Keras

Dans TensorFlow 2.0, les modèles keras sont plus cohérents sur la gestion des noms de métriques.

Maintenant , quand vous passez une chaîne dans la liste des paramètres, cette chaîne exacte est utilisée comme indicateur du name . Ces noms sont visibles dans l'objet historique renvoyé par model.fit , et dans les journaux passés à keras.callbacks . est défini sur la chaîne que vous avez transmise dans la liste de métriques.

model.compile(
    optimizer = tf.keras.optimizers.Adam(0.001),
    loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics = ['acc', 'accuracy', tf.keras.metrics.SparseCategoricalAccuracy(name="my_accuracy")])
history = model.fit(train_data)
5/5 [==============================] - 0s 6ms/step - loss: 0.1139 - acc: 0.9937 - accuracy: 0.9937 - my_accuracy: 0.9937

history.history.keys()
dict_keys(['loss', 'acc', 'accuracy', 'my_accuracy'])

Cela diffère des versions précédentes où le passage de metrics=["accuracy"] entraînerait dict_keys(['loss', 'acc'])

Optimiseurs Keras

Les optimiseurs de v1.train , comme v1.train.AdamOptimizer et v1.train.GradientDescentOptimizer , ont des équivalents dans tf.keras.optimizers .

Convertir v1.train en keras.optimizers

Voici quelques éléments à garder à l'esprit lors de la conversion de vos optimiseurs:

Nouveaux tf.keras.optimizers par défaut pour certains tf.keras.optimizers

Il n'y a aucun changement pour les optimizers.SGD , optimizers.Adam ou optimizers.RMSprop .

Les taux d'apprentissage par défaut suivants ont changé:

TensorBoard

TensorFlow 2 inclut des modifications importantes de l'API tf.summary utilisée pour écrire des données récapitulatives pour la visualisation dans TensorBoard. Pour une introduction générale au nouveau tf.summary , il existe plusieurs tutoriels disponibles qui utilisent l'API TF 2. Cela inclut un guide de migration TensorBoard TF 2

Sauvegarde et chargement

Compatibilité des points de contrôle

TensorFlow 2.0 utilise des points de contrôle basés sur des objets .

Les points de contrôle basés sur les noms à l'ancienne peuvent toujours être chargés, si vous faites attention. Le processus de conversion de code peut entraîner des changements de nom de variable, mais il existe des solutions de contournement.

L'approche la plus simple consiste à aligner les noms du nouveau modèle avec les noms du point de contrôle:

  • Les variables ont toujours un argument de name vous pouvez définir.
  • Modèles KERAS prennent également un name argument qu'ils fixent comme préfixe pour leurs variables.
  • La fonction v1.name_scope peut être utilisée pour définir des préfixes de nom de variable. Ceci est très différent de tf.variable_scope . Cela n'affecte que les noms et ne suit pas les variables et ne les réutilise pas.

Si cela ne fonctionne pas pour votre cas d'utilisation, essayez la fonction v1.train.init_from_checkpoint . Il prend un argument assignment_map , qui spécifie le mappage des anciens noms aux nouveaux noms.

Le référentiel TensorFlow Estimator comprend un outil de conversion pour mettre à niveau les points de contrôle des estimateurs prédéfinis de TensorFlow 1.X vers 2.0. Il peut servir d'exemple sur la façon de créer un outil pour un cas d'utilisation similaire.

Compatibilité des modèles enregistrés

Il n'y a pas de problèmes de compatibilité significatifs pour les modèles enregistrés.

  • Les modèles enregistrés TensorFlow 1.x fonctionnent dans TensorFlow 2.x.
  • Les modèles enregistrés TensorFlow 2.x fonctionnent dans TensorFlow 1.x, si toutes les opérations sont prises en charge.

Un Graph.pb ou Graph.pbtxt

Il n'existe pas de moyen simple de mettre à niveau un fichier Graph.pb brut vers TensorFlow 2.0. Votre meilleur pari est de mettre à jour le code qui a généré le fichier.

Mais, si vous avez un "Frozen graph" (un tf.Graph où les variables ont été transformées en constantes), alors il est possible de le convertir en une fonction concrete_function utilisant v1.wrap_function :

def wrap_frozen_graph(graph_def, inputs, outputs):
  def _imports_graph_def():
    tf.compat.v1.import_graph_def(graph_def, name="")
  wrapped_import = tf.compat.v1.wrap_function(_imports_graph_def, [])
  import_graph = wrapped_import.graph
  return wrapped_import.prune(
      tf.nest.map_structure(import_graph.as_graph_element, inputs),
      tf.nest.map_structure(import_graph.as_graph_element, outputs))

Par exemple, voici un graphique frozed pour Inception v1, à partir de 2016:

path = tf.keras.utils.get_file(
    'inception_v1_2016_08_28_frozen.pb',
    'http://storage.googleapis.com/download.tensorflow.org/models/inception_v1_2016_08_28_frozen.pb.tar.gz',
    untar=True)
Downloading data from http://storage.googleapis.com/download.tensorflow.org/models/inception_v1_2016_08_28_frozen.pb.tar.gz
24698880/24695710 [==============================] - 1s 0us/step

Chargez le tf.GraphDef :

graph_def = tf.compat.v1.GraphDef()
loaded = graph_def.ParseFromString(open(path,'rb').read())

Enveloppez-le dans une fonction concrete_function :

inception_func = wrap_frozen_graph(
    graph_def, inputs='input:0',
    outputs='InceptionV1/InceptionV1/Mixed_3b/Branch_1/Conv2d_0a_1x1/Relu:0')

Passez-lui un tenseur comme entrée:

input_img = tf.ones([1,224,224,3], dtype=tf.float32)
inception_func(input_img).shape
TensorShape([1, 28, 28, 96])

Estimateurs

Formation avec les estimateurs

Les estimateurs sont pris en charge dans TensorFlow 2.0.

Lorsque vous utilisez des estimateurs, vous pouvez utiliser input_fn() , tf.estimator.TrainSpec et tf.estimator.EvalSpec de TensorFlow 1.x.

Voici un exemple utilisant input_fn avec train et évaluer les spécifications.

Création des spécifications input_fn et train / eval

# Define the estimator's input_fn
def input_fn():
  datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
  mnist_train, mnist_test = datasets['train'], datasets['test']

  BUFFER_SIZE = 10000
  BATCH_SIZE = 64

  def scale(image, label):
    image = tf.cast(image, tf.float32)
    image /= 255

    return image, label[..., tf.newaxis]

  train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
  return train_data.repeat()

# Define train & eval specs
train_spec = tf.estimator.TrainSpec(input_fn=input_fn,
                                    max_steps=STEPS_PER_EPOCH * NUM_EPOCHS)
eval_spec = tf.estimator.EvalSpec(input_fn=input_fn,
                                  steps=STEPS_PER_EPOCH)

Utilisation d'une définition de modèle Keras

Il existe certaines différences dans la manière de construire vos estimateurs dans TensorFlow 2.0.

Nous vous recommandons de définir votre modèle à l'aide de Keras, puis d'utiliser l'utilitaire tf.keras.estimator.model_to_estimator pour transformer votre modèle en estimateur. Le code ci-dessous montre comment utiliser cet utilitaire lors de la création et de la formation d'un estimateur.

def make_model():
  return tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10)
  ])
model = make_model()

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

estimator = tf.keras.estimator.model_to_estimator(
  keras_model = model
)

tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
INFO:tensorflow:Using default config.

INFO:tensorflow:Using default config.

Warning:tensorflow:Using temporary folder as model directory: /tmp/tmpgnqimrn9

Warning:tensorflow:Using temporary folder as model directory: /tmp/tmpgnqimrn9

INFO:tensorflow:Using the Keras model provided.

INFO:tensorflow:Using the Keras model provided.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_estimator/python/estimator/keras.py:220: set_learning_phase (from tensorflow.python.keras.backend) is deprecated and will be removed after 2020-10-11.
Instructions for updating:
Simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_estimator/python/estimator/keras.py:220: set_learning_phase (from tensorflow.python.keras.backend) is deprecated and will be removed after 2020-10-11.
Instructions for updating:
Simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpgnqimrn9', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpgnqimrn9', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

INFO:tensorflow:Not using Distribute Coordinator.

INFO:tensorflow:Not using Distribute Coordinator.

INFO:tensorflow:Running training and evaluation locally (non-distributed).

INFO:tensorflow:Running training and evaluation locally (non-distributed).

INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.

INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/training_util.py:236: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/training/training_util.py:236: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Warm-starting with WarmStartSettings: WarmStartSettings(ckpt_to_initialize_from='/tmp/tmpgnqimrn9/keras/keras_model.ckpt', vars_to_warm_start='.*', var_name_to_vocab_info={}, var_name_to_prev_var_name={})

INFO:tensorflow:Warm-starting with WarmStartSettings: WarmStartSettings(ckpt_to_initialize_from='/tmp/tmpgnqimrn9/keras/keras_model.ckpt', vars_to_warm_start='.*', var_name_to_vocab_info={}, var_name_to_prev_var_name={})

INFO:tensorflow:Warm-starting from: /tmp/tmpgnqimrn9/keras/keras_model.ckpt

INFO:tensorflow:Warm-starting from: /tmp/tmpgnqimrn9/keras/keras_model.ckpt

INFO:tensorflow:Warm-starting variables only in TRAINABLE_VARIABLES.

INFO:tensorflow:Warm-starting variables only in TRAINABLE_VARIABLES.

INFO:tensorflow:Warm-started 8 variables.

INFO:tensorflow:Warm-started 8 variables.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpgnqimrn9/model.ckpt.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpgnqimrn9/model.ckpt.

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:loss = 2.5481484, step = 0

INFO:tensorflow:loss = 2.5481484, step = 0

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...

INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpgnqimrn9/model.ckpt.

INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpgnqimrn9/model.ckpt.

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_v1.py:2048: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.

Warning:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_v1.py:2048: Model.state_updates (from tensorflow.python.keras.engine.training) is deprecated and will be removed in a future version.
Instructions for updating:
This property should not be used in TensorFlow 2.0, as updates are applied automatically.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Starting evaluation at 2020-09-19T01:25:32Z

INFO:tensorflow:Starting evaluation at 2020-09-19T01:25:32Z

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Restoring parameters from /tmp/tmpgnqimrn9/model.ckpt-25

INFO:tensorflow:Restoring parameters from /tmp/tmpgnqimrn9/model.ckpt-25

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Evaluation [1/5]

INFO:tensorflow:Evaluation [1/5]

INFO:tensorflow:Evaluation [2/5]

INFO:tensorflow:Evaluation [2/5]

INFO:tensorflow:Evaluation [3/5]

INFO:tensorflow:Evaluation [3/5]

INFO:tensorflow:Evaluation [4/5]

INFO:tensorflow:Evaluation [4/5]

INFO:tensorflow:Evaluation [5/5]

INFO:tensorflow:Evaluation [5/5]

INFO:tensorflow:Inference Time : 0.86522s

INFO:tensorflow:Inference Time : 0.86522s

INFO:tensorflow:Finished evaluation at 2020-09-19-01:25:33

INFO:tensorflow:Finished evaluation at 2020-09-19-01:25:33

INFO:tensorflow:Saving dict for global step 25: accuracy = 0.553125, global_step = 25, loss = 1.6822916

INFO:tensorflow:Saving dict for global step 25: accuracy = 0.553125, global_step = 25, loss = 1.6822916

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpgnqimrn9/model.ckpt-25

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpgnqimrn9/model.ckpt-25

INFO:tensorflow:Loss for final step: 0.46296218.

INFO:tensorflow:Loss for final step: 0.46296218.

({'accuracy': 0.553125, 'loss': 1.6822916, 'global_step': 25}, [])

Utilisation d'un model_fn personnalisé

Si vous avez un estimateur personnalisé model_fn existant que vous devez gérer, vous pouvez convertir votre model_fn pour utiliser un modèle Keras.

Cependant, pour des raisons de compatibilité, un model_fn personnalisé model_fn toujours en mode graphique de style 1.x. Cela signifie qu'il n'y a aucune exécution hâtive et aucune dépendance de contrôle automatique.

Model_fn personnalisé avec des modifications minimes

Pour que votre model_fn personnalisé fonctionne dans TF 2.0, si vous préférez des modifications minimes au code existant, les symboles tf.compat.v1 tels que les optimizers et les metrics peuvent être utilisés.

L'utilisation d'un modèle Keras dans un model_fn personnalisé est similaire à son utilisation dans une boucle d'entraînement personnalisée:

  • Définissez la phase d' training manière appropriée, en fonction de l'argument mode .
  • Transmettez explicitement les trainable_variables du modèle à l'optimiseur.

Mais il existe des différences importantes, par rapport à une boucle personnalisée :

  • Au lieu d'utiliser Model.losses , extrayez les pertes en utilisant Model.get_losses_for .
  • Extrayez les mises à jour du modèle à l'aide de Model.get_updates_for .

Le code suivant crée un estimateur à partir d'un model_fn personnalisé, illustrant toutes ces préoccupations.

def my_model_fn(features, labels, mode):
  model = make_model()

  optimizer = tf.compat.v1.train.AdamOptimizer()
  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

  training = (mode == tf.estimator.ModeKeys.TRAIN)
  predictions = model(features, training=training)

  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

  reg_losses = model.get_losses_for(None) + model.get_losses_for(features)
  total_loss=loss_fn(labels, predictions) + tf.math.add_n(reg_losses)

  accuracy = tf.compat.v1.metrics.accuracy(labels=labels,
                                           predictions=tf.math.argmax(predictions, axis=1),
                                           name='acc_op')

  update_ops = model.get_updates_for(None) + model.get_updates_for(features)
  minimize_op = optimizer.minimize(
      total_loss,
      var_list=model.trainable_variables,
      global_step=tf.compat.v1.train.get_or_create_global_step())
  train_op = tf.group(minimize_op, update_ops)

  return tf.estimator.EstimatorSpec(
    mode=mode,
    predictions=predictions,
    loss=total_loss,
    train_op=train_op, eval_metric_ops={'accuracy': accuracy})

# Create the Estimator & Train
estimator = tf.estimator.Estimator(model_fn=my_model_fn)
tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
INFO:tensorflow:Using default config.

INFO:tensorflow:Using default config.

Warning:tensorflow:Using temporary folder as model directory: /tmp/tmpdqm3gv9f

Warning:tensorflow:Using temporary folder as model directory: /tmp/tmpdqm3gv9f

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpdqm3gv9f', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpdqm3gv9f', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

INFO:tensorflow:Not using Distribute Coordinator.

INFO:tensorflow:Not using Distribute Coordinator.

INFO:tensorflow:Running training and evaluation locally (non-distributed).

INFO:tensorflow:Running training and evaluation locally (non-distributed).

INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.

INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpdqm3gv9f/model.ckpt.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpdqm3gv9f/model.ckpt.

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:loss = 2.6994424, step = 0

INFO:tensorflow:loss = 2.6994424, step = 0

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...

INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpdqm3gv9f/model.ckpt.

INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpdqm3gv9f/model.ckpt.

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Starting evaluation at 2020-09-19T01:25:36Z

INFO:tensorflow:Starting evaluation at 2020-09-19T01:25:36Z

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Restoring parameters from /tmp/tmpdqm3gv9f/model.ckpt-25

INFO:tensorflow:Restoring parameters from /tmp/tmpdqm3gv9f/model.ckpt-25

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Evaluation [1/5]

INFO:tensorflow:Evaluation [1/5]

INFO:tensorflow:Evaluation [2/5]

INFO:tensorflow:Evaluation [2/5]

INFO:tensorflow:Evaluation [3/5]

INFO:tensorflow:Evaluation [3/5]

INFO:tensorflow:Evaluation [4/5]

INFO:tensorflow:Evaluation [4/5]

INFO:tensorflow:Evaluation [5/5]

INFO:tensorflow:Evaluation [5/5]

INFO:tensorflow:Inference Time : 0.91620s

INFO:tensorflow:Inference Time : 0.91620s

INFO:tensorflow:Finished evaluation at 2020-09-19-01:25:36

INFO:tensorflow:Finished evaluation at 2020-09-19-01:25:36

INFO:tensorflow:Saving dict for global step 25: accuracy = 0.6, global_step = 25, loss = 1.5189537

INFO:tensorflow:Saving dict for global step 25: accuracy = 0.6, global_step = 25, loss = 1.5189537

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpdqm3gv9f/model.ckpt-25

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpdqm3gv9f/model.ckpt-25

INFO:tensorflow:Loss for final step: 0.5045532.

INFO:tensorflow:Loss for final step: 0.5045532.

({'accuracy': 0.6, 'loss': 1.5189537, 'global_step': 25}, [])

model_fn personnalisé avec symboles TF 2.0

Si vous souhaitez vous débarrasser de tous les symboles TF 1.x et mettre à niveau votre model_fn personnalisé vers TF 2.0 natif, vous devez mettre à jour l'optimiseur et les métriques vers tf.keras.optimizers et tf.keras.metrics .

Dans le model_fn personnalisé, en plus des modifications ci-dessus, d'autres mises à niveau doivent être effectuées:

Pour l'exemple ci-dessus de my_model_fn , le code migré avec les symboles 2.0 est affiché comme my_model_fn :

def my_model_fn(features, labels, mode):
  model = make_model()

  training = (mode == tf.estimator.ModeKeys.TRAIN)
  loss_obj = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
  predictions = model(features, training=training)

  # Get both the unconditional losses (the None part)
  # and the input-conditional losses (the features part).
  reg_losses = model.get_losses_for(None) + model.get_losses_for(features)
  total_loss=loss_obj(labels, predictions) + tf.math.add_n(reg_losses)

  # Upgrade to tf.keras.metrics.
  accuracy_obj = tf.keras.metrics.Accuracy(name='acc_obj')
  accuracy = accuracy_obj.update_state(
      y_true=labels, y_pred=tf.math.argmax(predictions, axis=1))

  train_op = None
  if training:
    # Upgrade to tf.keras.optimizers.
    optimizer = tf.keras.optimizers.Adam()
    # Manually assign tf.compat.v1.global_step variable to optimizer.iterations
    # to make tf.compat.v1.train.global_step increased correctly.
    # This assignment is a must for any `tf.train.SessionRunHook` specified in
    # estimator, as SessionRunHooks rely on global step.
    optimizer.iterations = tf.compat.v1.train.get_or_create_global_step()
    # Get both the unconditional updates (the None part)
    # and the input-conditional updates (the features part).
    update_ops = model.get_updates_for(None) + model.get_updates_for(features)
    # Compute the minimize_op.
    minimize_op = optimizer.get_updates(
        total_loss,
        model.trainable_variables)[0]
    train_op = tf.group(minimize_op, *update_ops)

  return tf.estimator.EstimatorSpec(
    mode=mode,
    predictions=predictions,
    loss=total_loss,
    train_op=train_op,
    eval_metric_ops={'Accuracy': accuracy_obj})

# Create the Estimator & Train.
estimator = tf.estimator.Estimator(model_fn=my_model_fn)
tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)
INFO:tensorflow:Using default config.

INFO:tensorflow:Using default config.

Warning:tensorflow:Using temporary folder as model directory: /tmp/tmp_y4k0o_v

Warning:tensorflow:Using temporary folder as model directory: /tmp/tmp_y4k0o_v

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp_y4k0o_v', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp_y4k0o_v', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

INFO:tensorflow:Not using Distribute Coordinator.

INFO:tensorflow:Not using Distribute Coordinator.

INFO:tensorflow:Running training and evaluation locally (non-distributed).

INFO:tensorflow:Running training and evaluation locally (non-distributed).

INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.

INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 0...

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp_y4k0o_v/model.ckpt.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp_y4k0o_v/model.ckpt.

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...

INFO:tensorflow:loss = 2.7534888, step = 0

INFO:tensorflow:loss = 2.7534888, step = 0

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...

INFO:tensorflow:Calling checkpoint listeners before saving checkpoint 25...

INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmp_y4k0o_v/model.ckpt.

INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmp_y4k0o_v/model.ckpt.

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...

INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 25...

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Starting evaluation at 2020-09-19T01:25:39Z

INFO:tensorflow:Starting evaluation at 2020-09-19T01:25:39Z

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Restoring parameters from /tmp/tmp_y4k0o_v/model.ckpt-25

INFO:tensorflow:Restoring parameters from /tmp/tmp_y4k0o_v/model.ckpt-25

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Evaluation [1/5]

INFO:tensorflow:Evaluation [1/5]

INFO:tensorflow:Evaluation [2/5]

INFO:tensorflow:Evaluation [2/5]

INFO:tensorflow:Evaluation [3/5]

INFO:tensorflow:Evaluation [3/5]

INFO:tensorflow:Evaluation [4/5]

INFO:tensorflow:Evaluation [4/5]

INFO:tensorflow:Evaluation [5/5]

INFO:tensorflow:Evaluation [5/5]

INFO:tensorflow:Inference Time : 0.85182s

INFO:tensorflow:Inference Time : 0.85182s

INFO:tensorflow:Finished evaluation at 2020-09-19-01:25:40

INFO:tensorflow:Finished evaluation at 2020-09-19-01:25:40

INFO:tensorflow:Saving dict for global step 25: Accuracy = 0.740625, global_step = 25, loss = 1.6748577

INFO:tensorflow:Saving dict for global step 25: Accuracy = 0.740625, global_step = 25, loss = 1.6748577

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp_y4k0o_v/model.ckpt-25

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp_y4k0o_v/model.ckpt-25

INFO:tensorflow:Loss for final step: 0.3578726.

INFO:tensorflow:Loss for final step: 0.3578726.

({'Accuracy': 0.740625, 'loss': 1.6748577, 'global_step': 25}, [])

Estimateurs préfabriqués

Les estimateurs prédéfinis de la famille tf.estimator.DNN* , tf.estimator.Linear* et tf.estimator.DNNLinearCombined* sont toujours pris en charge dans l'API TensorFlow 2.0, cependant, certains arguments ont changé:

  1. input_layer_partitioner : supprimé dans la version 2.0.
  2. loss_reduction : mis à jour vers tf.keras.losses.Reduction au lieu de tf.compat.v1.losses.Reduction . Sa valeur par défaut est également modifiée en tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE partir de tf.compat.v1.losses.Reduction.SUM .
  3. optimizer , dnn_optimizer et linear_optimizer : cet argument a été mis à jour vers tf.keras.optimizers au lieu de tf.compat.v1.train.Optimizer .

Pour migrer les modifications ci-dessus:

  1. Aucune migration n'est nécessaire pour input_layer_partitioner car la Distribution Strategy le gérera automatiquement dans TF 2.0.
  2. Pour loss_reduction , vérifiez tf.keras.losses.Reduction pour les options prises en charge.
  3. Pour les arguments de l' optimizer , si vous ne passez pas d' dnn_optimizer optimizer , dnn_optimizer ou linear_optimizer , ou si vous spécifiez l'argument d' optimizer sous forme de string dans votre code, vous n'avez rien à changer. tf.keras.optimizers est utilisé par défaut. Sinon, vous devez le mettre à jour de tf.compat.v1.train.Optimizer vers son tf.keras.optimizers correspondant

Convertisseur de point de contrôle

La migration vers keras.optimizers interrompra les points de contrôle enregistrés à l'aide de TF 1.x, car tf.keras.optimizers génère un ensemble différent de variables à enregistrer dans les points de contrôle. Pour rendre l'ancien point de contrôle réutilisable après votre migration vers TF 2.0, essayez l' outil de conversion de point de contrôle .

 curl -O https://raw.githubusercontent.com/tensorflow/estimator/master/tensorflow_estimator/python/estimator/tools/checkpoint_converter.py
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 15165  100 15165    0     0  72559      0 --:--:-- --:--:-- --:--:-- 72559

L'outil a une aide intégrée:

 python checkpoint_converter.py -h
2020-09-19 01:25:41.394385: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
usage: checkpoint_converter.py [-h]
                               {dnn,linear,combined} source_checkpoint
                               source_graph target_checkpoint

positional arguments:
  {dnn,linear,combined}
                        The type of estimator to be converted. So far, the
                        checkpoint converter only supports Canned Estimator.
                        So the allowed types include linear, dnn and combined.
  source_checkpoint     Path to source checkpoint file to be read in.
  source_graph          Path to source graph file to be read in.
  target_checkpoint     Path to checkpoint file to be written out.

optional arguments:
  -h, --help            show this help message and exit

TensorShape

Cette classe a été simplifiée pour contenir des int s, au lieu des objets tf.compat.v1.Dimension . Il n'est donc pas nécessaire d'appeler .value() pour obtenir un int .

Les objets tf.compat.v1.Dimension individuels sont toujours accessibles à partir de tf.TensorShape.dims .

Les éléments suivants illustrent les différences entre TensorFlow 1.x et TensorFlow 2.0.

# Create a shape and choose an index
i = 0
shape = tf.TensorShape([16, None, 256])
shape
TensorShape([16, None, 256])

Si vous aviez ceci dans TF 1.x:

value = shape[i].value

Ensuite, faites ceci dans TF 2.0:

value = shape[i]
value
16

Si vous aviez ceci dans TF 1.x:

for dim in shape:
    value = dim.value
    print(value)

Ensuite, faites ceci dans TF 2.0:

for value in shape:
  print(value)
16
None
256

Si vous aviez cela dans TF 1.x (ou avez utilisé une autre méthode de dimension):

dim = shape[i]
dim.assert_is_compatible_with(other_dim)

Ensuite, faites ceci dans TF 2.0:

other_dim = 16
Dimension = tf.compat.v1.Dimension

if shape.rank is None:
  dim = Dimension(None)
else:
  dim = shape.dims[i]
dim.is_compatible_with(other_dim) # or any other dimension method
True
shape = tf.TensorShape(None)

if shape:
  dim = shape.dims[i]
  dim.is_compatible_with(other_dim) # or any other dimension method

La valeur booléenne d'un tf.TensorShape est True si le rang est connu, False sinon.

print(bool(tf.TensorShape([])))      # Scalar
print(bool(tf.TensorShape([0])))     # 0-length vector
print(bool(tf.TensorShape([1])))     # 1-length vector
print(bool(tf.TensorShape([None])))  # Unknown-length vector
print(bool(tf.TensorShape([1, 10, 100])))       # 3D tensor
print(bool(tf.TensorShape([None, None, None]))) # 3D tensor with no known dimensions
print()
print(bool(tf.TensorShape(None)))  # A tensor with unknown rank.
True
True
True
True
True
True

False

Autres changements

  • Supprimer tf.colocate_with : les algorithmes de placement des appareils de TensorFlow se sont considérablement améliorés. Cela ne devrait plus être nécessaire. Si sa suppression entraîne une dégradation des performances, veuillez signaler un bogue .

  • Remplacez l'utilisation de v1.ConfigProto par les fonctions équivalentes de tf.config .

Conclusions

Le processus global est:

  1. Exécutez le script de mise à niveau.
  2. Supprimez les symboles contrib.
  3. Basculez vos modèles vers un style orienté objet (Keras).
  4. Utilisez les tf.keras formation et d'évaluation tf.keras ou tf.estimator là où vous le pouvez.
  5. Sinon, utilisez des boucles personnalisées, mais veillez à éviter les sessions et les collections.

Il faut un peu de travail pour convertir le code en TensorFlow 2.0 idiomatique, mais chaque changement entraîne:

  • Moins de lignes de code.
  • Clarté et simplicité accrues.
  • Débogage plus facile.