Reserve a data! O Google I / O retorna de 18 a 20 de maio Registre-se agora
Esta página foi traduzida pela API Cloud Translation.
Switch to English

Migre seu código do TensorFlow 1 para o TensorFlow 2

Ver no TensorFlow.org Executar no Google Colab Ver fonte no GitHub Baixar caderno

Este guia é para usuários de APIs TensorFlow de baixo nível. Se você estiver usando as APIs de alto nível ( tf.keras ), pode haver pouca ou nenhuma ação que você precise realizar para tornar seu código totalmente compatível com o TensorFlow 2.x:

Ainda é possível executar o código 1.x, sem modificações ( exceto para contrib ), no TensorFlow 2.x:

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

No entanto, isso não permite que você aproveite muitas das melhorias feitas no TensorFlow 2.x. Este guia o ajudará a atualizar seu código, tornando-o mais simples, com mais desempenho e mais fácil de manter.

Script de conversão automática

A primeira etapa, antes de tentar implementar as mudanças descritas neste guia, é tentar executar o script de atualização .

Isso executará uma passagem inicial ao atualizar seu código para o TensorFlow 2.x, mas não pode tornar seu código idiomático para a v2. Seu código ainda pode usar pontos de extremidade tf.compat.v1 para acessar espaços reservados, sessões, coleções e outras funcionalidades do estilo 1.x.

Mudanças comportamentais de nível superior

Se seu código funciona no TensorFlow 2.x usando tf.compat.v1.disable_v2_behavior , ainda há mudanças comportamentais globais que você pode precisar resolver. As principais mudanças são:

  • Execução v1.enable_eager_execution() , v1.enable_eager_execution() : Qualquer código que usar implicitamente um tf.Graph falhará. Certifique-se de envolver este código em um with tf.Graph().as_default() .

  • Variáveis ​​de recursos, v1.enable_resource_variables() : alguns códigos podem depender de comportamentos não determinísticos ativados por variáveis ​​de referência do TensorFlow. As variáveis ​​de recursos são bloqueadas enquanto são gravadas e, portanto, fornecem garantias de consistência mais intuitivas.

    • Isso pode alterar o comportamento em casos extremos.
    • Isso pode criar cópias extras e pode ter maior uso de memória.
    • Isso pode ser desabilitado passando use_resource=False para o construtor tf.Variable .
  • Formas do tensor, v1.enable_v2_tensorshape() : TensorFlow 2.x simplifica o comportamento das formas do tensor. Em vez de t.shape[0].value você pode dizer t.shape[0] . Essas alterações devem ser pequenas e faz sentido corrigi-las imediatamente. Consulte a seção TensorShape para exemplos.

  • Fluxo de controle, v1.enable_control_flow_v2() : a implementação do fluxo de controle do TensorFlow 2.x foi simplificada e, portanto, produz diferentes representações de gráfico. Por favor, registre bugs para quaisquer problemas.

Crie o código para TensorFlow 2.x

Este guia apresentará vários exemplos de conversão de código do TensorFlow 1.x para TensorFlow 2.x. Essas alterações permitirão que seu código aproveite as otimizações de desempenho e chamadas de API simplificadas.

Em cada caso, o padrão é:

1. Substitua chamadas v1.Session.run

Cada chamada v1.Session.run deve ser substituída por uma função Python.

  • O feed_dict e v1.placeholder s tornam-se argumentos de função.
  • As fetches tornam-se o valor de retorno da função.
  • Durante a conversão, a execução rápida permite a depuração fácil com ferramentas Python padrão como pdb .

Depois disso, adicione um decorador tf.function para que ele seja executado de forma eficiente no gráfico. Confira o guia do autógrafo para obter mais informações sobre como isso funciona.

Observe que:

  • Ao contrário da v1.Session.run , uma tf.function tem uma assinatura de retorno fixa e sempre retorna todas as saídas. Se isso causar problemas de desempenho, crie duas funções separadas.

  • Não há necessidade de um tf.control_dependencies ou operações semelhantes: Um tf.function se comporta como se fosse executado na ordem em que foi escrito. tf.Variable atribuições de tf.Variable e tf.assert s, por exemplo, são executadas automaticamente.

A seção de conversão de modelos contém um exemplo prático desse processo de conversão.

2. Use objetos Python para rastrear variáveis ​​e perdas

Todo rastreamento de variável baseado em nome é fortemente desencorajado no TensorFlow 2.x. Use objetos Python para rastrear variáveis.

Use tf.Variable vez de v1.get_variable .

Cada v1.variable_scope deve ser convertido em um objeto Python. Normalmente, será um dos seguintes:

Se você precisa de listas agregados de variáveis (como tf.Graph.get_collection(tf.GraphKeys.VARIABLES) ), use os .variables e .trainable_variables atributos da Layer e Model objetos.

Essas classes Layer e Model implementam várias outras propriedades que eliminam a necessidade de coleções globais. Sua propriedade .losses pode substituir o uso da coleção tf.GraphKeys.LOSSES .

Consulte os guias do Keras para obter mais detalhes.

3. Atualize seus loops de treinamento

Use a API de nível mais alto que funciona para seu caso de uso. Prefira tf.keras.Model.fit vez de criar seus próprios loops de treinamento.

Essas funções de alto nível gerenciam muitos dos detalhes de baixo nível que podem ser facilmente perdidos se você escrever seu próprio loop de treinamento. Por exemplo, eles coletam automaticamente as perdas de regularização e definem o argumento training=True ao chamar o modelo.

4. Atualize seus canais de entrada de dados

Use conjuntos de dados tf.data para entrada de dados. Esses objetos são eficientes, expressivos e se integram bem com tensorflow.

Eles podem ser passados ​​diretamente para o método tf.keras.Model.fit .

model.fit(dataset, epochs=5)

Eles podem ser iterados diretamente no Python padrão:

for example_batch, label_batch in dataset:
    break

5. Migre os símbolos compat.v1

O módulo tf.compat.v1 contém a API TensorFlow 1.x completa, com sua semântica original.

O script de atualização do TensorFlow 2.x converterá os símbolos em seus equivalentes v2 se essa conversão for segura, ou seja, se puder determinar que o comportamento da versão do TensorFlow 2.x é exatamente equivalente (por exemplo, ele renomeará v1.arg_max para tf.argmax , uma vez que são a mesma função).

Depois que o script de atualização é feito com um trecho de código, é provável que haja muitas menções de compat.v1 . Vale a pena examinar o código e convertê-los manualmente para o equivalente v2 (deve ser mencionado no log, se houver).

Modelos de conversão

Variáveis ​​de baixo nível e execução do operador

Exemplos de uso de API de baixo nível incluem:

  • Usando escopos variáveis ​​para controlar a reutilização.
  • Criação de variáveis ​​com v1.get_variable .
  • Acessando coleções explicitamente.
  • Acessando coleções implicitamente com métodos como:

  • Usando v1.placeholder para configurar entradas de gráfico.

  • Executando gráficos com Session.run .

  • Inicializando variáveis ​​manualmente.

Antes de converter

Veja como esses padrões podem parecer no código usando o 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

Depois de converter

No código convertido:

  • As variáveis ​​são objetos Python locais.
  • A função forward ainda define o cálculo.
  • A chamada Session.run é substituída por uma chamada para forward .
  • O decorador tf.function opcional pode ser adicionado para desempenho.
  • As regularizações são calculadas manualmente, sem fazer referência a nenhuma coleção global.
  • Não há uso de sessões ou espaços reservados .
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)

Modelos baseados em tf.layers

O módulo v1.layers é usado para conter funções de camada que dependiam de v1.variable_scope para definir e reutilizar variáveis.

Antes de converter

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)
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/convolutional.py:414: UserWarning: `tf.layers.conv2d` is deprecated and will be removed in a future version. Please Use `tf.keras.layers.Conv2D` instead.
  warnings.warn('`tf.layers.conv2d` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py:2273: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.
  warnings.warn('`layer.apply` is deprecated and '
tf.Tensor([[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]], shape=(1, 10), dtype=float32)

tf.Tensor(
[[ 0.379358   -0.55901194  0.48704922  0.11619566  0.23902717  0.01691487
   0.07227738  0.14556988  0.2459927   0.2501198 ]], shape=(1, 10), dtype=float32)
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/pooling.py:310: UserWarning: `tf.layers.max_pooling2d` is deprecated and will be removed in a future version. Please use `tf.keras.layers.MaxPooling2D` instead.
  warnings.warn('`tf.layers.max_pooling2d` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/core.py:329: UserWarning: `tf.layers.flatten` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Flatten` instead.
  warnings.warn('`tf.layers.flatten` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/core.py:268: UserWarning: `tf.layers.dropout` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dropout` instead.
  warnings.warn('`tf.layers.dropout` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/core.py:171: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.
  warnings.warn('`tf.layers.dense` is deprecated and '
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/legacy_tf_layers/normalization.py:308: UserWarning: `tf.layers.batch_normalization` is deprecated and will be removed in a future version. Please use `tf.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.layers.batch_normalization` is deprecated and '

Depois de converter

A maioria dos argumentos permaneceu igual. Mas observe as diferenças:

  • O argumento de training é passado para cada camada pelo modelo quando ele é executado.
  • O primeiro argumento para a função do model original (a entrada x ) se foi. Isso ocorre porque as camadas do objeto separam a construção do modelo da chamada do modelo.

Observe também que:

  • Se você estiver usando regularizadores ou inicializadores de tf.contrib , eles terão mais mudanças de argumento do que outros.
  • O código não grava mais em coleções, então funções como v1.losses.get_regularization_loss não retornarão mais esses valores, potencialmente quebrando seus loops de treinamento.
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.2145557  -0.22979769 -0.14968733  0.01208701 -0.07569927  0.3475932
   0.10718458  0.03482988 -0.04309493 -0.10469118]], 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.08174552>]

Variáveis ​​mistas e v1.layers

O código existente geralmente combina variáveis ​​e operações do TensorFlow 1.x de nível inferior com v1.layers de nível v1.layers .

Antes de converter

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)

Depois de converter

Para converter esse código, siga o padrão de mapeamento de camadas em camadas, como no exemplo anterior.

O padrão geral é:

  • Colete parâmetros de camada em __init__ .
  • Construa as variáveis ​​na build .
  • Execute os cálculos em call e retorne o resultado.

O v1.variable_scope é essencialmente uma camada própria. Portanto, reescreva-o como tf.keras.layers.Layer . Confira o guia Criando novas camadas e modelos por meio de subclasses para obter detalhes.

# 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)

Algumas coisas a serem observadas:

  • Modelos e camadas de Keras com subclasse precisam ser executados em ambos os gráficos v1 (sem dependências de controle automático) e no modo ansioso:

    • Envolva a call em um tf.function para obter autógrafos e dependências de controle automático.
  • Não se esqueça de aceitar um argumento de training para call :

    • Às vezes é um tf.Tensor
    • Às vezes é um booleano Python
  • Crie variáveis ​​de modelo no construtor ou Model.build usando `self.add_weight:

    • Em Model.build você tem acesso ao formato de entrada, então pode criar pesos com formato correspondente
    • Usar tf.keras.layers.Layer.add_weight permite que Keras rastreie variáveis ​​e perdas de regularização
  • Não mantenha tf.Tensors em seus objetos:

    • Eles podem ser criados em uma função tf.function ou no contexto ansioso, e esses tensores se comportam de maneira diferente
    • Use tf.Variable s para o estado, eles são sempre utilizáveis ​​em ambos os contextos
    • tf.Tensors são apenas para valores intermediários

Uma observação sobre Slim e contrib.layers

Uma grande quantidade de códigos mais antigos do TensorFlow 1.x usa a biblioteca Slim , que foi empacotada com o TensorFlow 1.x como tf.contrib.layers . Como um módulo contrib , ele não está mais disponível no TensorFlow 2.x, mesmo em tf.compat.v1 . Converter código usando Slim para TensorFlow 2.x envolve mais do que converter repositórios que usam v1.layers . Na verdade, pode fazer sentido converter seu código Slim para v1.layers primeiro e, em seguida, converter para Keras.

  • Remova arg_scopes , todos os args precisam ser explícitos.
  • Se você usá-los, divida normalizer_fn e activation_fn em suas próprias camadas.
  • Camadas conv separáveis ​​são mapeadas para uma ou mais camadas Keras diferentes (camadas Keras de profundidade, ponto a ponto e separáveis).
  • Slim e v1.layers têm nomes de argumento e valores padrão diferentes.
  • Alguns argumentos têm escalas diferentes.
  • Se você usa modelos pré-treinados Slim, experimente os modelos pré-treinados de Keras em tf.keras.applications ou TensorFlow 2.x SavedModels do TF Hub exportados do código Slim original.

Algumas camadas tf.contrib podem não ter sido movidas para o TensorFlow central, mas sim para o pacote de complementos do TensorFlow .

Treinamento

Existem muitas maneiras de tf.keras dados a um modelo tf.keras . Eles aceitarão geradores Python e matrizes Numpy como entrada.

A maneira recomendada de alimentar um modelo com dados é usar o pacote tf.data , que contém uma coleção de classes de alto desempenho para manipulação de dados.

Se você ainda estiver usando tf.queue , agora eles são suportados apenas como estruturas de dados, não como pipelines de entrada.

Usando conjuntos de dados TensorFlow

O pacote TensorFlow Datasets ( tfds ) contém utilitários para carregar conjuntos de dados predefinidos como objetostf.data.Dataset .

Para este exemplo, você pode carregar o conjunto de dados MNIST usando tfds :

datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets['train'], datasets['test']
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...
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`.
Dataset mnist downloaded and prepared to /home/kbuilder/tensorflow_datasets/mnist/3.0.1. Subsequent calls will reuse this data.

Em seguida, prepare os dados para o treinamento:

  • Redimensione cada imagem.
  • Misture a ordem dos exemplos.
  • Colete lotes de imagens e etiquetas.
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

Para manter o exemplo curto, apare o conjunto de dados para retornar apenas 5 lotes:

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))

Use loops de treinamento Keras

Se você não precisa de um controle de baixo nível de seu processo de treinamento, recomenda-se o uso dos métodos integrados de fit , evaluate e predict Keras. Esses métodos fornecem uma interface uniforme para treinar o modelo, independentemente da implementação (sequencial, funcional ou subclassificada).

As vantagens desses métodos incluem:

  • Eles aceitam matrizes Numpy, geradores Python e tf.data.Datasets .
  • Eles aplicam a regularização e as perdas de ativação automaticamente.
  • Eles oferecem suporte a tf.distribute para tf.distribute em vários dispositivos .
  • Eles suportam cobráveis ​​arbitrários como perdas e métricas.
  • Eles oferecem suporte a retornos de chamada como tf.keras.callbacks.TensorBoard e retornos de chamada personalizados.
  • Eles têm um bom desempenho, usando gráficos do TensorFlow automaticamente.

Aqui está um exemplo de treinamento de um modelo usando um Dataset . (Para obter detalhes sobre como isso funciona, verifique a seção de tutoriais .)

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 [==============================] - 1s 9ms/step - loss: 2.0191 - accuracy: 0.3608
Epoch 2/5
5/5 [==============================] - 0s 9ms/step - loss: 0.4736 - accuracy: 0.9059
Epoch 3/5
5/5 [==============================] - 0s 8ms/step - loss: 0.2973 - accuracy: 0.9626
Epoch 4/5
5/5 [==============================] - 0s 9ms/step - loss: 0.2108 - accuracy: 0.9911
Epoch 5/5
5/5 [==============================] - 0s 8ms/step - loss: 0.1791 - accuracy: 0.9874
5/5 [==============================] - 0s 6ms/step - loss: 1.5504 - accuracy: 0.7500
Loss 1.5504140853881836, Accuracy 0.75

Escreva seu próprio loop

Se a etapa de treinamento do modelo Keras funciona para você, mas você precisa de mais controle fora dessa etapa, considere o uso do método tf.keras.Model.train_on_batch , em seu próprio loop de iteração de dados.

Lembre-se: muitas coisas podem ser implementadas como tf.keras.callbacks.Callback .

Este método tem muitas das vantagens dos métodos mencionados na seção anterior, mas fornece ao usuário o controle do loop externo.

Você também pode usar tf.keras.Model.test_on_batch ou tf.keras.Model.evaluate para verificar o desempenho durante o treinamento.

Para continuar treinando o modelo acima:

# 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.138 accuracy: 1.000
train:  loss: 0.161 accuracy: 1.000
train:  loss: 0.159 accuracy: 0.969
train:  loss: 0.241 accuracy: 0.953
train:  loss: 0.172 accuracy: 0.969

eval:  loss: 1.550 accuracy: 0.800
train:  loss: 0.086 accuracy: 1.000
train:  loss: 0.094 accuracy: 1.000
train:  loss: 0.090 accuracy: 1.000
train:  loss: 0.119 accuracy: 0.984
train:  loss: 0.099 accuracy: 1.000

eval:  loss: 1.558 accuracy: 0.841
train:  loss: 0.076 accuracy: 1.000
train:  loss: 0.068 accuracy: 1.000
train:  loss: 0.061 accuracy: 1.000
train:  loss: 0.076 accuracy: 1.000
train:  loss: 0.076 accuracy: 1.000

eval:  loss: 1.536 accuracy: 0.841
train:  loss: 0.059 accuracy: 1.000
train:  loss: 0.056 accuracy: 1.000
train:  loss: 0.058 accuracy: 1.000
train:  loss: 0.054 accuracy: 1.000
train:  loss: 0.055 accuracy: 1.000

eval:  loss: 1.497 accuracy: 0.863
train:  loss: 0.053 accuracy: 1.000
train:  loss: 0.049 accuracy: 1.000
train:  loss: 0.044 accuracy: 1.000
train:  loss: 0.049 accuracy: 1.000
train:  loss: 0.045 accuracy: 1.000

eval:  loss: 1.463 accuracy: 0.878

Personalize a etapa de treinamento

Se você precisa de mais flexibilidade e controle, pode obtê-los implementando seu próprio ciclo de treinamento. Existem três etapas:

  1. tf.data.Dataset atf.data.Dataset em um gerador Python outf.data.Dataset para obter lotes de exemplos.
  2. Usetf.GradientTape para coletar gradientes.
  3. Use um dos tf.keras.optimizers para aplicar atualizações de peso às variáveis ​​do modelo.

Lembrar:

  • Sempre inclua um argumento de training no método de call de camadas e modelos de subclasse.
  • Certifique-se de chamar o modelo com o argumento de training definido corretamente.
  • Dependendo do uso, as variáveis ​​do modelo podem não existir até que o modelo seja executado em um lote de dados.
  • Você precisa lidar manualmente com coisas como perdas de regularização para o modelo.

Observe as simplificações em relação a v1:

  • Não há necessidade de executar inicializadores de variáveis. As variáveis ​​são inicializadas na criação.
  • Não há necessidade de adicionar dependências de controle manual. Mesmo em tf.function operações funcionam como no modo tf.function .
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étricas e perdas de novo estilo

No TensorFlow 2.x, métricas e perdas são objetos. Eles funcionam avidamente e em tf.function s.

Um objeto de perda pode ser chamado e espera o (y_true, y_pred) como argumentos:

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

Um objeto métrico tem os seguintes métodos:

O próprio objeto pode ser chamado. Chamar atualiza o estado com novas observações, como com update_state , e retorna o novo resultado da métrica.

Você não precisa inicializar manualmente as variáveis ​​de uma métrica e, como o TensorFlow 2.x tem dependências de controle automático, você também não precisa se preocupar com elas.

O código a seguir usa uma métrica para rastrear a perda média observada em um loop de treinamento personalizado.

# 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.139
  accuracy: 0.997
Epoch:  1
  loss:     0.116
  accuracy: 1.000
Epoch:  2
  loss:     0.105
  accuracy: 0.997
Epoch:  3
  loss:     0.089
  accuracy: 1.000
Epoch:  4
  loss:     0.078
  accuracy: 1.000

Nomes de métricas Keras

No TensorFlow 2.x, os modelos Keras são mais consistentes no tratamento de nomes de métricas.

Agora, quando você passa uma string na lista de métricas, essa string exata é usada como o name da métrica. Esses nomes são visíveis no objeto de histórico retornado por model.fit e nos logs passados ​​para keras.callbacks . é definido como a string que você passou na lista de métricas.

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 [==============================] - 1s 8ms/step - loss: 0.0901 - acc: 0.9923 - accuracy: 0.9923 - my_accuracy: 0.9923
history.history.keys()
dict_keys(['loss', 'acc', 'accuracy', 'my_accuracy'])

Isso difere das versões anteriores, em que passar metrics=["accuracy"] resultaria em dict_keys(['loss', 'acc'])

Otimizadores Keras

Os otimizadores em v1.train , como v1.train.AdamOptimizer e v1.train.GradientDescentOptimizer , têm equivalentes em tf.keras.optimizers .

Converter v1.train em keras.optimizers

Aqui estão alguns pontos a serem considerados ao converter seus otimizadores:

Novos padrões para alguns tf.keras.optimizers

Não há mudanças para optimizers.SGD , optimizers.Adam ou optimizers.RMSprop .

As seguintes taxas de aprendizagem padrão foram alteradas:

TensorBoard

O TensorFlow 2.x inclui mudanças significativas na API tf.summary usada para gravar dados de resumo para visualização no TensorBoard. Para uma introdução geral ao novo tf.summary , existem vários tutoriais disponíveis que usam a API TensorFlow 2.x. Isso inclui um guia de migração do TensorBoard TensorFlow 2.x.

Salvando e carregando

Compatibilidade do ponto de verificação

O TensorFlow 2.x usa pontos de verificação baseados em objetos .

Os pontos de verificação baseados em nomes no estilo antigo ainda podem ser carregados, se você tiver cuidado. O processo de conversão do código pode resultar em alterações no nome da variável, mas existem soluções alternativas.

A abordagem mais simples é alinhar os nomes do novo modelo com os nomes no checkpoint:

  • Todas as variáveis ​​ainda têm um argumento de name que você pode definir.
  • Os modelos Keras também aceitam um argumento de name como o prefixo de suas variáveis.
  • A função v1.name_scope pode ser usada para definir prefixos de nomes de variáveis. Isso é muito diferente de tf.variable_scope . Afeta apenas nomes e não rastreia variáveis ​​e reutiliza.

Se isso não funcionar para o seu caso de uso, tente a função v1.train.init_from_checkpoint . Recebe um argumento assignment_map , que especifica o mapeamento de nomes antigos para novos nomes.

O repositório TensorFlow Estimator inclui uma ferramenta de conversão para atualizar os pontos de verificação para estimadores predefinidos do TensorFlow 1.x para 2.0. Pode servir como um exemplo de como construir uma ferramenta para um caso de uso semelhante.

Compatibilidade de modelos salvos

Não há problemas de compatibilidade significativos para modelos salvos.

  • Os modelos salvos do TensorFlow 1.x funcionam no TensorFlow 2.x.
  • Os modelos salvos do TensorFlow 2.x funcionam no TensorFlow 1.x se todas as operações forem compatíveis.

A Graph.pb ou Graph.pbtxt

Não há uma maneira direta de atualizar um arquivo Graph.pb bruto para o TensorFlow 2.x. Sua melhor aposta é atualizar o código que gerou o arquivo.

Mas, se você tiver um "gráfico congelado" (um tf.Graph onde as variáveis ​​foram transformadas em constantes), é possível convertê-lo em uma função concrete_function usando 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))

Por exemplo, aqui está um gráfico congelado para o Inception v1, 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

Carregue o tf.GraphDef :

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

Envolva-o em uma função concrete_function :

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

Passe um tensor como entrada:

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

Estimadores

Treinamento com estimadores

Estimadores são compatíveis com TensorFlow 2.x.

Ao usar estimadores, você pode usar input_fn , tf.estimator.TrainSpec e tf.estimator.EvalSpec do TensorFlow 1.x.

Aqui está um exemplo usando input_fn com treinar e avaliar as especificações.

Criação das especificações input_fn e 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 and 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)

Usando uma definição de modelo Keras

Existem algumas diferenças em como construir seus estimadores no TensorFlow 2.x.

É recomendável definir seu modelo usando Keras e, em seguida, usar o utilitário tf.keras.estimator.model_to_estimator para transformar seu modelo em um estimador. O código a seguir mostra como usar esse utilitário ao criar e treinar um estimador.

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/tmp0erq3im2
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmp0erq3im2
INFO:tensorflow:Using the Keras model provided.
INFO:tensorflow:Using the Keras model provided.
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/backend.py:434: UserWarning: `tf.keras.backend.set_learning_phase` is deprecated and will be removed after 2020-10-11. To update it, simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.
  warnings.warn('`tf.keras.backend.set_learning_phase` is deprecated and '
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmp0erq3im2', '_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, '_checkpoint_save_graph_def': True, '_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/tmp0erq3im2', '_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, '_checkpoint_save_graph_def': True, '_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/tmp0erq3im2/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/tmp0erq3im2/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/tmp0erq3im2/keras/keras_model.ckpt
INFO:tensorflow:Warm-starting from: /tmp/tmp0erq3im2/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/tmp0erq3im2/model.ckpt.
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmp0erq3im2/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 2.4717796, step = 0
INFO:tensorflow:loss = 2.4717796, 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/tmp0erq3im2/model.ckpt.
INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmp0erq3im2/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.
/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py:2325: UserWarning: `Model.state_updates` will be removed in a future version. This property should not be used in TensorFlow 2.0, as `updates` are applied automatically.
  warnings.warn('`Model.state_updates` will be removed in a future version. '
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:17Z
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:17Z
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmp0erq3im2/model.ckpt-25
INFO:tensorflow:Restoring parameters from /tmp/tmp0erq3im2/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.86556s
INFO:tensorflow:Inference Time : 0.86556s
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:18
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:18
INFO:tensorflow:Saving dict for global step 25: accuracy = 0.6, global_step = 25, loss = 1.6160676
INFO:tensorflow:Saving dict for global step 25: accuracy = 0.6, global_step = 25, loss = 1.6160676
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp0erq3im2/model.ckpt-25
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmp0erq3im2/model.ckpt-25
INFO:tensorflow:Loss for final step: 0.37597787.
INFO:tensorflow:Loss for final step: 0.37597787.
({'accuracy': 0.6, 'loss': 1.6160676, 'global_step': 25}, [])

Usando um model_fn personalizado

Se você tiver um estimador customizado model_fn que precise manter, poderá converter seu model_fn para usar um modelo Keras.

No entanto, por motivos de compatibilidade, um model_fn personalizado ainda será executado no modo de gráfico no estilo 1.x. Isso significa que não há execução rápida e nem dependências de controle automático.

Model_fn personalizado com alterações mínimas

Para fazer seu model_fn personalizado funcionar no TensorFlow 2.x, se você preferir mudanças mínimas no código existente, símbolos tf.compat.v1 , como optimizers e metrics podem ser usados.

Usar um modelo Keras em um model_fn personalizado é semelhante a usá-lo em um loop de treinamento personalizado:

  • Defina a fase de training apropriadamente, com base no argumento de mode .
  • Passe explicitamente as trainable_variables do modelo para o otimizador.

Mas existem diferenças importantes, em relação a um loop personalizado :

  • Em vez de usar Model.losses , extraia as perdas usando Model.get_losses_for .
  • Extraia as atualizações do modelo usando Model.get_updates_for .

O código a seguir cria um estimador a partir de um model_fn personalizado, ilustrando todas essas questões.

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/tmpifj8mysl
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpifj8mysl
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpifj8mysl', '_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, '_checkpoint_save_graph_def': True, '_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/tmpifj8mysl', '_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, '_checkpoint_save_graph_def': True, '_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/tmpifj8mysl/model.ckpt.
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpifj8mysl/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 3.0136237, step = 0
INFO:tensorflow:loss = 3.0136237, 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/tmpifj8mysl/model.ckpt.
INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpifj8mysl/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 2021-01-06T02:31:20Z
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:20Z
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpifj8mysl/model.ckpt-25
INFO:tensorflow:Restoring parameters from /tmp/tmpifj8mysl/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.97406s
INFO:tensorflow:Inference Time : 0.97406s
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:21
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:21
INFO:tensorflow:Saving dict for global step 25: accuracy = 0.59375, global_step = 25, loss = 1.6248872
INFO:tensorflow:Saving dict for global step 25: accuracy = 0.59375, global_step = 25, loss = 1.6248872
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpifj8mysl/model.ckpt-25
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpifj8mysl/model.ckpt-25
INFO:tensorflow:Loss for final step: 0.35726172.
INFO:tensorflow:Loss for final step: 0.35726172.
({'accuracy': 0.59375, 'loss': 1.6248872, 'global_step': 25}, [])

model_fn personalizado com símbolos TensorFlow 2.x

Se quiser se livrar de todos os símbolos do TensorFlow 1.x e atualizar seu model_fn personalizado para TensorFlow 2.x, você precisa atualizar o otimizador e as métricas para tf.keras.optimizers e tf.keras.metrics .

No model_fn personalizado, além das alterações acima, mais atualizações precisam ser feitas:

Para o exemplo acima de my_model_fn , o código migrado com os símbolos do TensorFlow 2.x é mostrado como:

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 and 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/tmpc93qfnv6
WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpc93qfnv6
INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpc93qfnv6', '_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, '_checkpoint_save_graph_def': True, '_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/tmpc93qfnv6', '_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, '_checkpoint_save_graph_def': True, '_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/tmpc93qfnv6/model.ckpt.
INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpc93qfnv6/model.ckpt.
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:Calling checkpoint listeners after saving checkpoint 0...
INFO:tensorflow:loss = 2.5293791, step = 0
INFO:tensorflow:loss = 2.5293791, 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/tmpc93qfnv6/model.ckpt.
INFO:tensorflow:Saving checkpoints for 25 into /tmp/tmpc93qfnv6/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 2021-01-06T02:31:24Z
INFO:tensorflow:Starting evaluation at 2021-01-06T02:31:24Z
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpc93qfnv6/model.ckpt-25
INFO:tensorflow:Restoring parameters from /tmp/tmpc93qfnv6/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.86534s
INFO:tensorflow:Inference Time : 0.86534s
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:25
INFO:tensorflow:Finished evaluation at 2021-01-06-02:31:25
INFO:tensorflow:Saving dict for global step 25: Accuracy = 0.59375, global_step = 25, loss = 1.7570661
INFO:tensorflow:Saving dict for global step 25: Accuracy = 0.59375, global_step = 25, loss = 1.7570661
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpc93qfnv6/model.ckpt-25
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 25: /tmp/tmpc93qfnv6/model.ckpt-25
INFO:tensorflow:Loss for final step: 0.47094986.
INFO:tensorflow:Loss for final step: 0.47094986.
({'Accuracy': 0.59375, 'loss': 1.7570661, 'global_step': 25}, [])

Estimadores pré-fabricados

Estimadores tf.estimator.DNN* na família de tf.estimator.DNN* , tf.estimator.Linear* e tf.estimator.DNNLinearCombined* ainda são compatíveis com a API TensorFlow 2.x. No entanto, alguns argumentos mudaram:

  1. input_layer_partitioner : removido na v2.
  2. loss_reduction : atualizado para tf.keras.losses.Reduction vez de tf.compat.v1.losses.Reduction . Seu valor padrão também é alterado para tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE de tf.compat.v1.losses.Reduction.SUM .
  3. optimizer , dnn_optimizer e linear_optimizer : este argumento foi atualizado para tf.keras.optimizers vez de tf.compat.v1.train.Optimizer .

Para migrar as alterações acima:

  1. Nenhuma migração é necessária para input_layer_partitioner pois a Distribution Strategy irá lidar com isso automaticamente no TensorFlow 2.x.
  2. Para loss_reduction , verifique tf.keras.losses.Reduction para as opções suportadas.
  3. Para argumentos do optimizer :
    • Se você não: 1) passar o argumento optimizer , dnn_optimizer ou linear_optimizer , ou 2) especificar o argumento do optimizer como uma string em seu código, você não precisa alterar nada porque tf.keras.optimizers é usado por padrão .
    • Caso contrário, você precisa atualizá-lo de tf.compat.v1.train.Optimizer para seu tf.keras.optimizers correspondente.

Conversor de ponto de verificação

A migração para keras.optimizers interromperá os pontos de verificação salvos com o TensorFlow 1.x, pois tf.keras.optimizers gera um conjunto diferente de variáveis ​​a serem salvas nos pontos de verificação. Para tornar o ponto de verificação antigo reutilizável após a migração para o TensorFlow 2.x, experimente a ferramenta de conversão de pontos de verificação .

 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  40656      0 --:--:-- --:--:-- --:--:-- 40656

A ferramenta possui ajuda integrada:

 python checkpoint_converter.py -h
2021-01-06 02:31:26.297951: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
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

Essa classe foi simplificada para conter int s, em vez de objetos tf.compat.v1.Dimension . Portanto, não há necessidade de chamar .value para obter um int .

Os objetos tf.compat.v1.Dimension individuais ainda podem ser acessados ​​em tf.TensorShape.dims .

A seguir, demonstramos as diferenças entre o TensorFlow 1.x e o TensorFlow 2.x.

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

Se você tinha isso no TensorFlow 1.x:

value = shape[i].value

Em seguida, faça isso no TensorFlow 2.x:

value = shape[i]
value
16

Se você tinha isso no TensorFlow 1.x:

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

Em seguida, faça isso no TensorFlow 2.x:

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

Se você tinha isso no TensorFlow 1.x (ou usou qualquer outro método de dimensão):

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

Em seguida, faça isso no TensorFlow 2.x:

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

O valor booleano de um tf.TensorShape é True se a classificação for conhecida, False caso contrário.

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

Outras mudanças

  • Remova tf.colocate_with : os algoritmos de posicionamento de dispositivos do TensorFlow melhoraram significativamente. Isso não deve mais ser necessário. Se removê-lo causar uma degradação do desempenho, informe um bug .

  • Substitua o uso de v1.ConfigProto pelas funções equivalentes de tf.config .

Conclusões

O processo geral é:

  1. Execute o script de atualização.
  2. Remova os símbolos contrib.
  3. Mude seus modelos para um estilo orientado a objetos (Keras).
  4. Use tf.keras ou tf.estimator loops de treinamento e avaliação onde puder.
  5. Caso contrário, use loops personalizados, mas certifique-se de evitar sessões e coleções.

É um pouco trabalhoso converter o código para o TensorFlow 2.x idiomático, mas cada alteração resulta em:

  • Menos linhas de código.
  • Maior clareza e simplicidade.
  • Depuração mais fácil.