![]() | ![]() | ![]() | ![]() |
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:
- Verifique a taxa de aprendizado padrão do otimizador .
- Observe que o "nome" no qual as métricas são registradas pode ter mudado .
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 TensorFlow 2.x, mas não pode tornar seu código idiomático para 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 umtf.Graph
falhará. Certifique-se de envolver este código em umwith 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 durante a gravação 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 construtortf.Variable
.
Formas do tensor,
v1.enable_v2_tensorshape()
: TensorFlow 2.x simplifica o comportamento das formas do tensor. Em vez det.shape[0].value
você pode dizert.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, arquive 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
ev1.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
, umatf.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: Umtf.function
se comporta como se fosse executado na ordem em que foi escrito.tf.Variable
atribuições detf.Variable
etf.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 construir 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 pipelines 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. Migrar 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 pedaço 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 de 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 locais do Python.
- A função
forward
ainda define o cálculo. - A chamada
Session.run
é substituída por uma chamada paraforward
. - 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 pilha simples de camadas se encaixa perfeitamente em
tf.keras.Sequential
. (Para modelos mais complexos, verifique as camadas e modelos personalizados e os guias de API funcionais .) - O modelo rastreia as variáveis e perdas de regularização.
- A conversão foi um para um porque há um mapeamento direto de
v1.layers
paratf.keras.layers
.
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 entradax
) 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, portanto, funções como
v1.losses.get_regularization_loss
não retornarão mais esses valores, potencialmente interrompendo 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 gráficos v1 (sem dependências de controle automático) e no modo ansioso:
- Envolva a
call
em umtf.function
para obter autógrafos e dependências de controle automático.
- Envolva a
Não se esqueça de aceitar um argumento de
training
paracall
:- Às vezes é um
tf.Tensor
- Às vezes é um booleano Python
- Às vezes é um
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
- Em
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, elas sempre podem ser usadas em ambos os contextos -
tf.Tensors
são apenas para valores intermediários
- Eles podem ser criados em uma função
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 o 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 primeiro seu código Slim para v1.layers
, em seguida, converter para Keras.
- Remova
arg_scopes
, todos os args precisam ser explícitos. - Se você usá-los, divida
normalizer_fn
eactivation_fn
em suas próprias camadas. - Camadas conv separáveis são mapeadas para uma ou mais camadas Keras diferentes (camadas Keras profundas, pontuais 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 alimentar dados para 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 controle de baixo nível de seu processo de treinamento, é recomendado usar os 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 suportam
tf.distribute
paratf.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 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
.
Esse 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 precisar de mais flexibilidade e controle, você pode obtê-los implementando seu próprio ciclo de treinamento. Existem três etapas:
tf.data.Dataset
atf.data.Dataset
sobre um gerador Python outf.data.Dataset
para obter lotes de exemplos.- Use
tf.GradientTape
para coletar gradientes. - 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 decall
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 modotf.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:
-
Metric.update_state()
: adicione novas observações. -
Metric.result()
: obtém o resultado atual da métrica, dados os valores observados. -
Metric.reset_states()
: limpa todas as observações.
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 abaixo 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, onde 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:
- Atualizar seus otimizadores pode tornar os pontos de verificação antigos incompatíveis .
- Todos os epsilons agora são padronizados para
1e-7
vez de1e-8
(que é insignificante na maioria dos casos de uso). -
v1.train.GradientDescentOptimizer
pode ser substituído diretamente portf.keras.optimizers.SGD
. -
v1.train.MomentumOptimizer
pode ser substituído diretamente pelo otimizadorSGD
usando o argumento momentum:tf.keras.optimizers.SGD(..., momentum=...)
. -
v1.train.AdamOptimizer
pode ser convertido para usartf.keras.optimizers.Adam
. Os argumentosbeta1
ebeta2
foram renomeados parabeta_1
ebeta_2
. -
v1.train.RMSPropOptimizer
pode ser convertido emtf.keras.optimizers.RMSprop
. O argumentodecay
foi renomeado pararho
. -
v1.train.AdadeltaOptimizer
pode ser convertido diretamente paratf.keras.optimizers.Adadelta
. -
tf.train.AdagradOptimizer
pode ser convertido diretamente emtf.keras.optimizers.Adagrad
. -
tf.train.FtrlOptimizer
pode ser convertido diretamente emtf.keras.optimizers.Ftrl
. Osaccum_name
elinear_name
argumentos foram removidos. -
tf.contrib.AdamaxOptimizer
etf.contrib.NadamOptimizer
podem ser convertidos diretamente emtf.keras.optimizers.Adamax
etf.keras.optimizers.Nadam
, respectivamente. Os argumentosbeta1
ebeta2
foram renomeados parabeta_1
ebeta_2
.
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:
-
optimizers.Adagrad
de 0,01 a 0,001 -
optimizers.Adadelta
de 1,0 a 0,001 -
optimizers.Adamax
de 0,002 a 0,001 -
optimizers.Nadam
de 0,002 a 0,001
TensorBoard
O TensorFlow 2.x inclui mudanças significativas na API tf.summary
usada para escrever dados resumidos 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ê for cuidadoso. O processo de conversão do código pode resultar em mudanças 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 usam 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 detf.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 início 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 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 especificações de treinamento e avaliação.
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.
É recomendado que você defina seu modelo usando Keras, então use 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 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 demode
. - 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 usandoModel.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 você quiser se livrar de todos os símbolos do TensorFlow 1.x e atualizar seu model_fn
personalizado para o TensorFlow 2.x, será necessário 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:
- Use
tf.keras.optimizers
vez dev1.train.Optimizer
. - Passe explicitamente as
trainable_variables
do modelo paratf.keras.optimizers
. - Para calcular o
train_op/minimize_op
,- Use
Optimizer.get_updates
se a perda forTensor
perda escalar (não um chamável). O primeiro elemento na lista retornada é otrain_op/minimize_op
desejado. - Se a perda
train_op/minimize_op
ser chamada (como uma função), useOptimizer.minimize
para obtertrain_op/minimize_op
.
- Use
- Use
tf.keras.metrics
vez detf.compat.v1.metrics
para avaliação.
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:
-
input_layer_partitioner
: removido na v2. -
loss_reduction
: atualizado paratf.keras.losses.Reduction
vez detf.compat.v1.losses.Reduction
. Seu valor padrão também é alterado paratf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE
detf.compat.v1.losses.Reduction.SUM
. -
optimizer
,dnn_optimizer
elinear_optimizer
: este argumento foi atualizado paratf.keras.optimizers
vez detf.compat.v1.train.Optimizer
.
Para migrar as alterações acima:
- Nenhuma migração é necessária para
input_layer_partitioner
uma vez que aDistribution Strategy
tratará disso automaticamente no TensorFlow 2.x. - Para
loss_reduction
, verifiquetf.keras.losses.Reduction
para as opções suportadas. - Para argumentos do
optimizer
:- Se você não: 1) passar o argumento
optimizer
,dnn_optimizer
oulinear_optimizer
, ou 2) especificar o argumento dooptimizer
como umastring
em seu código, não será necessário alterar nada porquetf.keras.optimizers
é usado por padrão . - Caso contrário, você precisa atualizá-lo de
tf.compat.v1.train.Optimizer
para seutf.keras.optimizers
correspondente.
- Se você não: 1) passar o argumento
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 checkpoint antigo reutilizável após a migração para o TensorFlow 2.x, experimente a ferramenta de conversão de checkpoint .
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 detf.config
.
Conclusões
O processo geral é:
- Execute o script de atualização.
- Remova os símbolos contrib.
- Mude seus modelos para um estilo orientado a objetos (Keras).
- Use
tf.keras
outf.estimator
loops de treinamento e avaliação onde puder. - 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 mudança resulta em:
- Menos linhas de código.
- Maior clareza e simplicidade.
- Depuração mais fácil.