![]() | ![]() | ![]() | ![]() |
Esta guía está destinada a usuarios de API de TensorFlow de bajo nivel. Si está utilizando las API de alto nivel ( tf.keras
), es posible que deba realizar poca o ninguna acción para que su código sea totalmente compatible con TensorFlow 2.x:
- Verifique la tasa de aprendizaje predeterminada de su optimizador .
- Tenga en cuenta que el "nombre" en el que se registran las métricas puede haber cambiado .
Todavía es posible ejecutar código 1.x, sin modificar ( excepto para contrib ), en TensorFlow 2.x:
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
Sin embargo, esto no le permite aprovechar muchas de las mejoras realizadas en TensorFlow 2.x. Esta guía lo ayudará a actualizar su código, haciéndolo más simple, más eficiente y más fácil de mantener.
Script de conversión automática
El primer paso, antes de intentar implementar los cambios descritos en esta guía, es intentar ejecutar el script de actualización .
Esto ejecutará un pase inicial al actualizar su código a TensorFlow 2.x, pero no puede convertir su código en idiomático a v2. Su código aún puede hacer uso de los tf.compat.v1
finales tf.compat.v1
para acceder a marcadores de posición, sesiones, colecciones y otras funciones de estilo 1.x.
Cambios de comportamiento de alto nivel
Si su código funciona en TensorFlow 2.x con tf.compat.v1.disable_v2_behavior
, todavía hay cambios de comportamiento globales que es posible que deba abordar. Los principales cambios son:
Ejecución
v1.enable_eager_execution()
,v1.enable_eager_execution()
: cualquier código que utilice implícitamente untf.Graph
fallará. Asegúrese de envolver este código en unwith tf.Graph().as_default()
.Variables de recursos,
v1.enable_resource_variables()
: parte del código puede depender de comportamientos no deterministas habilitados por las variables de referencia de TensorFlow. Las variables de recursos se bloquean mientras se escriben, por lo que proporcionan garantías de coherencia más intuitivas.- Esto puede cambiar el comportamiento en casos extremos.
- Esto puede crear copias adicionales y puede tener un mayor uso de memoria.
- Esto se puede desactivar pasando
use_resource=False
al constructortf.Variable
.
Formas de tensor,
v1.enable_v2_tensorshape()
: TensorFlow 2.x simplifica el comportamiento de las formas de tensor. En lugar det.shape[0].value
, puede decirt.shape[0]
. Estos cambios deben ser pequeños y tiene sentido corregirlos de inmediato. Consulte la sección TensorShape para ver ejemplos.Flujo de control,
v1.enable_control_flow_v2()
: la implementación del flujo de control de TensorFlow 2.x se ha simplificado y, por lo tanto, produce diferentes representaciones gráficas. Por favor, presente errores para cualquier problema.
Crear código para TensorFlow 2.x
Esta guía mostrará varios ejemplos de conversión de código de TensorFlow 1.x a TensorFlow 2.x. Estos cambios permitirán que su código aproveche las optimizaciones de rendimiento y las llamadas API simplificadas.
En cada caso, el patrón es:
1. Reemplazar v1.Session.run
llamadas v1.Session.run
Cada llamada a v1.Session.run
debe ser reemplazada por una función de Python.
-
feed_dict
yv1.placeholder
s se convierten en argumentos de función. - Las
fetches
convierten en el valor de retorno de la función. - Durante la conversión, la ejecución ávida permite una fácil depuración con herramientas estándar de Python como
pdb
.
Después de eso, agregue un decorador tf.function
para que se ejecute de manera eficiente en el gráfico. Consulte la guía de autógrafos para obtener más información sobre cómo funciona.
Tenga en cuenta que:
A diferencia de
v1.Session.run
, una funcióntf.function
tiene una firma de retorno fija y siempre devuelve todas las salidas. Si esto causa problemas de rendimiento, cree dos funciones separadas.No hay necesidad de
tf.control_dependencies
u operaciones similares: una funcióntf.function
comporta como si se ejecutara en el orden escrito.tf.Variable
asignacionestf.Variable
ytf.assert
s, por ejemplo, se ejecutan automáticamente.
La sección de conversión de modelos contiene un ejemplo práctico de este proceso de conversión.
2. Utilice objetos de Python para realizar un seguimiento de las variables y las pérdidas
Todo el seguimiento de variables basado en nombres está totalmente desaconsejado en TensorFlow 2.x. Utilice objetos de Python para realizar un seguimiento de las variables.
Utilice tf.Variable
lugar de v1.get_variable
.
Cada v1.variable_scope
debe convertirse en un objeto Python. Normalmente, este será uno de los siguientes:
Si necesita agregar listas de variables (como tf.Graph.get_collection(tf.GraphKeys.VARIABLES)
), use los .variables
y .trainable_variables
de los objetos Layer
y Model
.
Estas clases de Layer
y Model
implementan varias otras propiedades que eliminan la necesidad de colecciones globales. Su propiedad .losses
puede reemplazar el uso de la colección tf.GraphKeys.LOSSES
.
Consulte las guías de Keras para obtener más detalles.
3. Actualiza tus circuitos de entrenamiento
Utilice la API de más alto nivel que funcione para su caso de uso. Prefiere tf.keras.Model.fit
a construir tus propios circuitos de entrenamiento.
Estas funciones de alto nivel gestionan muchos de los detalles de bajo nivel que pueden ser fáciles de pasar por alto si escribe su propio ciclo de entrenamiento. Por ejemplo, recopilan automáticamente las pérdidas de regularización y establecen el argumento training=True
al llamar al modelo.
4. Actualice sus canalizaciones de entrada de datos
Utilice conjuntos de datos tf.data
para la entrada de datos. Estos objetos son eficientes, expresivos y se integran bien con tensorflow.
Se pueden pasar directamente al método tf.keras.Model.fit
.
model.fit(dataset, epochs=5)
Se pueden iterar sobre Python directamente estándar:
for example_batch, label_batch in dataset:
break
5. compat.v1
símbolos de compat.v1
El módulo tf.compat.v1
contiene la API de TensorFlow 1.x completa, con su semántica original.
El script de actualización de TensorFlow 2.x convertirá los símbolos a sus equivalentes v2 si dicha conversión es segura, es decir, si puede determinar que el comportamiento de la versión de TensorFlow 2.x es exactamente equivalente (por ejemplo, cambiará el nombre de v1.arg_max
a tf.argmax
, ya que son la misma función).
Después de que el script de actualización se realiza con un fragmento de código, es probable que haya muchas menciones de compat.v1
. Vale la pena revisar el código y convertirlos manualmente al equivalente v2 (debe mencionarse en el registro si lo hay).
Conversión de modelos
Variables de bajo nivel y ejecución del operador
Ejemplos de uso de API de bajo nivel incluyen:
- Uso de alcances variables para controlar la reutilización.
- Creando variables con
v1.get_variable
. - Acceder a colecciones de forma explícita.
Accediendo a colecciones implícitamente con métodos como:
Usando
v1.placeholder
para configurar entradas de gráficos.Ejecución de gráficos con
Session.run
.Inicializando variables manualmente.
Antes de convertir
Así es como pueden verse estos patrones en el código con 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
Después de convertir
En el código convertido:
- Las variables son objetos de Python locales.
- La función de
forward
todavía define el cálculo. - La llamada
Session.run
se reemplaza con una llamada paraforward
. - El decorador opcional
tf.function
se puede agregar para el rendimiento. - Las regularizaciones se calculan manualmente, sin hacer referencia a ninguna colección global.
- No se utilizan sesiones ni marcadores de posición .
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 basados en tf.layers
El módulo v1.layers
se utiliza para contener funciones de capa que se basaron en v1.variable_scope
para definir y reutilizar variables.
Antes de convertir
def model(x, training, scope='model'):
with v1.variable_scope(scope, reuse=v1.AUTO_REUSE):
x = v1.layers.conv2d(x, 32, 3, activation=v1.nn.relu,
kernel_regularizer=lambda x:0.004*tf.reduce_mean(x**2))
x = v1.layers.max_pooling2d(x, (2, 2), 1)
x = v1.layers.flatten(x)
x = v1.layers.dropout(x, 0.1, training=training)
x = v1.layers.dense(x, 64, activation=v1.nn.relu)
x = v1.layers.batch_normalization(x, training=training)
x = v1.layers.dense(x, 10)
return x
train_data = tf.ones(shape=(1, 28, 28, 1))
test_data = tf.ones(shape=(1, 28, 28, 1))
train_out = model(train_data, training=True)
test_out = model(test_data, training=False)
print(train_out)
print()
print(test_out)
/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 '
Después de convertir
- La simple pila de capas encaja perfectamente en
tf.keras.Sequential
. (Para modelos más complejos, consulte las capas y modelos personalizados y las guías funcionales de API ). - El modelo rastrea las variables y las pérdidas de regularización.
- La conversión fue uno a uno porque hay un mapeo directo de
v1.layers
atf.keras.layers
.
La mayoría de los argumentos se mantuvieron igual. Pero note las diferencias:
- El modelo pasa el argumento de
training
a cada capa cuando se ejecuta. - El primer argumento de la función del
model
original (la entradax
) se ha ido. Esto se debe a que las capas de objetos separan la construcción del modelo de la llamada al modelo.
También tenga en cuenta que:
- Si está utilizando regularizadores o inicializadores de
tf.contrib
, estos tienen más cambios de argumentos que otros. - El código ya no escribe en colecciones, por lo que funciones como
v1.losses.get_regularization_loss
ya no devolverán estos valores, lo que podría romper los ciclos de entrenamiento.
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>]
Variables mixtas y v1.layers
El código existente a menudo mezcla variables y operaciones de TensorFlow 1.x de nivel inferior con v1.layers
nivel v1.layers
.
Antes de convertir
def model(x, training, scope='model'):
with v1.variable_scope(scope, reuse=v1.AUTO_REUSE):
W = v1.get_variable(
"W", dtype=v1.float32,
initializer=v1.ones(shape=x.shape),
regularizer=lambda x:0.004*tf.reduce_mean(x**2),
trainable=True)
if training:
x = x + W
else:
x = x + W * 0.5
x = v1.layers.conv2d(x, 32, 3, activation=tf.nn.relu)
x = v1.layers.max_pooling2d(x, (2, 2), 1)
x = v1.layers.flatten(x)
return x
train_out = model(train_data, training=True)
test_out = model(test_data, training=False)
Después de convertir
Para convertir este código, siga el patrón de mapeo de capas a capas como en el ejemplo anterior.
El patrón general es:
- Recopile los parámetros de la capa en
__init__
. - Construye las variables en
build
. - Ejecute los cálculos en la
call
y devuelva el resultado.
v1.variable_scope
es esencialmente una capa propia. Así que tf.keras.layers.Layer
como tf.keras.layers.Layer
. Consulte la guía Creación de nuevas capas y modelos mediante subclases para obtener más detalles.
# 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)
Algunas cosas a tener en cuenta:
Los modelos y capas de Keras subclasificados deben ejecutarse tanto en gráficos v1 (sin dependencias de control automático) como en modo ansioso:
- Envuelva la
call
en untf.function
para obtener autógrafos y dependencias de control automático.
- Envuelva la
No olvide aceptar un argumento de
training
paracall
:- A veces es un
tf.Tensor
- A veces es un booleano de Python
- A veces es un
Cree variables de modelo en constructor o
Model.build
usando `self.add_weight:- En
Model.build
tiene acceso a la forma de entrada, por lo que puede crear pesos con la forma correspondiente - El uso de
tf.keras.layers.Layer.add_weight
permite a Keras realizar un seguimiento de las variables y las pérdidas de regularización
- En
No dejes
tf.Tensors
en tus objetos:- Pueden crearse en una función
tf.function
O en el contexto ansioso, y estos tensores se comportan de manera diferente - Use
tf.Variable
s para el estado, siempre se pueden usar en ambos contextos -
tf.Tensors
son solo para valores intermedios
- Pueden crearse en una función
Una nota sobre Slim y contrib.layers
Una gran cantidad de código antiguo de TensorFlow 1.x usa la biblioteca Slim , que se empaquetó con TensorFlow 1.x como tf.contrib.layers
. Como módulo contrib
, ya no está disponible en TensorFlow 2.x, incluso en tf.compat.v1
. Convertir código usando Slim a TensorFlow 2.x es más complicado que convertir repositorios que usan v1.layers
. De hecho, puede tener sentido convertir su código Slim a v1.layers
y luego convertirlo a Keras.
- Elimine
arg_scopes
, todos losarg_scopes
deben ser explícitos. - Si los usa, divida
normalizer_fn
yactivation_fn
en sus propias capas. - Las capas de conv separables se asignan a una o más capas de Keras diferentes (capas de Keras en profundidad, puntuales y separables).
- Slim y
v1.layers
tienen diferentes nombres de argumentos y valores predeterminados. - Algunos argumentos tienen diferentes escalas.
- Si usa modelos Slim pre-entrenados, pruebe los modelos pre-entrenados de Keras de
tf.keras.applications
o TensorFlow 2.x SavedModels de TF Hub exportados desde el código Slim original.
tf.contrib
posible que algunas capas de tf.contrib
no se hayan movido al núcleo de TensorFlow, sino que se hayan movido al paquete de complementos de TensorFlow .
Capacitación
Hay muchas formas de alimentar datos a un modelo tf.keras
. Aceptarán generadores de Python y matrices Numpy como entrada.
La forma recomendada de alimentar datos a un modelo es utilizar el paquete tf.data
, que contiene una colección de clases de alto rendimiento para manipular datos.
Si todavía usa tf.queue
, ahora solo se admiten como estructuras de datos, no como canalizaciones de entrada.
Usar conjuntos de datos de TensorFlow
El paquete de conjuntos de datos de TensorFlow ( tfds
) contiene utilidades para cargar conjuntos de datos predefinidos como objetostf.data.Dataset
.
Para este ejemplo, puede cargar el conjunto de datos tfds
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.
Luego, prepare los datos para el entrenamiento:
- Vuelva a escalar cada imagen.
- Mezcla el orden de los ejemplos.
- Recopile lotes de imágenes y 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 que el ejemplo sea breve, recorte el conjunto de datos para que solo devuelva 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))
Usa bucles de entrenamiento de Keras
Si no necesita un control de bajo nivel de su proceso de entrenamiento, se recomienda utilizar los métodos de fit
, evaluate
y predict
integrados de Keras. Estos métodos proporcionan una interfaz uniforme para entrenar el modelo independientemente de la implementación (secuencial, funcional o subclasificada).
Las ventajas de estos métodos incluyen:
- Aceptan matrices Numpy, generadores de Python y
tf.data.Datasets
. - Aplican pérdidas de regularización y activación de forma automática.
-
tf.distribute
para entrenamiento multidispositivo . - Admiten reclamaciones arbitrarias como pérdidas y métricas.
-
tf.keras.callbacks.TensorBoard
devoluciones de llamada comotf.keras.callbacks.TensorBoard
y devoluciones de llamada personalizadas. - Son eficaces y utilizan automáticamente los gráficos de TensorFlow.
A continuación, se muestra un ejemplo de cómo entrenar un modelo con un Dataset
. (Para obtener detalles sobre cómo funciona esto, consulte la sección de tutoriales ).
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
Escribe tu propio bucle
Si el paso de entrenamiento del modelo de Keras funciona para usted, pero necesita más control fuera de ese paso, considere usar el método tf.keras.Model.train_on_batch
, en su propio ciclo de iteración de datos.
Recuerde: se pueden implementar muchas cosas como tf.keras.callbacks.Callback
.
Este método tiene muchas de las ventajas de los métodos mencionados en la sección anterior, pero le da al usuario el control del bucle externo.
También puede utilizar tf.keras.Model.test_on_batch
o tf.keras.Model.evaluate
para comprobar el rendimiento durante el entrenamiento.
Para seguir entrenando el modelo anterior:
# 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
Personaliza el paso de entrenamiento
Si necesita más flexibilidad y control, puede tenerlo implementando su propio ciclo de entrenamiento. Hay tres pasos:
- Itere sobre un generador de Python o
tf.data.Dataset
para obtener lotes de ejemplos. - Utilice
tf.GradientTape
para recopilar gradientes. - Utilice uno de los
tf.keras.optimizers
para aplicar actualizaciones de peso a las variables del modelo.
Recuerda:
- Incluya siempre un argumento de
training
en el método decall
de capas y modelos de subclases. - Asegúrese de llamar al modelo con el argumento de
training
configurado correctamente. - Dependiendo del uso, es posible que las variables del modelo no existan hasta que el modelo se ejecute en un lote de datos.
- Necesita manejar manualmente cosas como pérdidas de regularización para el modelo.
Tenga en cuenta las simplificaciones relativas a v1:
- No es necesario ejecutar inicializadores de variables. Las variables se inicializan al crearse.
- No es necesario agregar dependencias de control manual. Incluso en
tf.function
operaciones actúan como en modo ansioso.
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
Pérdidas y métricas de nuevo estilo
En TensorFlow 2.x, las métricas y las pérdidas son objetos. Estos funcionan con entusiasmo y en tf.function
s.
Un objeto de pérdida es invocable y espera (y_true, y_pred) como argumentos:
cce = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
cce([[1, 0]], [[-1.0,3.0]]).numpy()
4.01815
Un objeto métrico tiene los siguientes métodos:
-
Metric.update_state()
: agrega nuevas observaciones. -
Metric.result()
: obtiene el resultado actual de la métrica, dados los valores observados. -
Metric.reset_states()
: borra todas las observaciones.
El objeto en sí es invocable. La llamada actualiza el estado con nuevas observaciones, como con update_state
, y devuelve el nuevo resultado de la métrica.
No es necesario que inicialice manualmente las variables de una métrica y, dado que TensorFlow 2.x tiene dependencias de control automático, tampoco debe preocuparse por ellas.
El siguiente código utiliza una métrica para realizar un seguimiento de la pérdida media observada dentro de un ciclo de entrenamiento 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
Nombres de métricas de Keras
En TensorFlow 2.x, los modelos de Keras son más consistentes en el manejo de nombres de métricas.
Ahora, cuando pasa una cadena en la lista de métricas, esa cadena exacta se usa como el name
la métrica. Estos nombres son visibles en el objeto histórico devuelto por model.fit
y en los registros pasados a keras.callbacks
. se establece en la cadena que pasó en la 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'])
Esto difiere de las versiones anteriores donde pasar metrics=["accuracy"]
daría como resultado dict_keys(['loss', 'acc'])
Optimizadores de Keras
Los optimizadores en v1.train
, como v1.train.AdamOptimizer
y v1.train.GradientDescentOptimizer
, tienen equivalentes en tf.keras.optimizers
.
Convertir v1.train
en keras.optimizers
A continuación, se indican algunos aspectos que debe tener en cuenta al convertir sus optimizadores:
- La actualización de sus optimizadores puede hacer que los puntos de control antiguos sean incompatibles .
- Todos los épsilons ahora están predeterminados en
1e-7
lugar de1e-8
(que es insignificante en la mayoría de los casos de uso). -
v1.train.GradientDescentOptimizer
puede ser reemplazado directamente portf.keras.optimizers.SGD
. -
v1.train.MomentumOptimizer
puede ser reemplazado directamente por el optimizadorSGD
usando el argumento momentum:tf.keras.optimizers.SGD(..., momentum=...)
. -
v1.train.AdamOptimizer
se puede convertir para usartf.keras.optimizers.Adam
. Se ha cambiado el nombre de los argumentosbeta1
ybeta2
abeta_1
ybeta_2
. -
v1.train.RMSPropOptimizer
se puede convertir atf.keras.optimizers.RMSprop
. Se ha cambiado el nombre del argumento dedecay
arho
. -
v1.train.AdadeltaOptimizer
se puede convertir directamente atf.keras.optimizers.Adadelta
. -
tf.train.AdagradOptimizer
se puede convertir directamente entf.keras.optimizers.Adagrad
. -
tf.train.FtrlOptimizer
se puede convertir directamente atf.keras.optimizers.Ftrl
. Se han eliminado los argumentosaccum_name
ylinear_name
. -
tf.contrib.AdamaxOptimizer
ytf.contrib.NadamOptimizer
se pueden convertir directamente entf.keras.optimizers.Adamax
ytf.keras.optimizers.Nadam
, respectivamente. Se ha cambiado el nombre de los argumentosbeta1
ybeta2
abeta_1
ybeta_2
.
Nuevos valores predeterminados para algunos tf.keras.optimizers
No hay cambios para optimizers.SGD
, optimizers.Adam
u optimizers.RMSprop
.
Las siguientes tasas de aprendizaje predeterminadas han cambiado:
-
optimizers.Adagrad
de 0,01 a 0,001 -
optimizers.Adadelta
de 1.0 a 0.001 -
optimizers.Adamax
Adamax de 0,002 a 0,001 -
optimizers.Nadam
Nadam de 0,002 a 0,001
TensorBoard
TensorFlow 2.x incluye cambios significativos en la API tf.summary
usa para escribir datos de resumen para visualización en TensorBoard. Para obtener una introducción general al nuevo tf.summary
, hay varios tutoriales disponibles que utilizan la API de TensorFlow 2.x. Esto incluye una guía de migración de TensorBoard TensorFlow 2.x.
Guardar y cargar
Compatibilidad con puntos de control
TensorFlow 2.x usa puntos de control basados en objetos .
Los puntos de control basados en nombres de estilo antiguo aún se pueden cargar, si tiene cuidado. El proceso de conversión de código puede resultar en cambios de nombre de variable, pero existen soluciones.
El enfoque más simple es alinear los nombres del nuevo modelo con los nombres en el punto de control:
- Las variables todavía tienen un argumento de
name
que puede establecer. - Los modelos de Keras también toman un argumento de
name
que establecen como prefijo para sus variables. - La función
v1.name_scope
se puede utilizar para establecer prefijos de nombre de variable. Esto es muy diferente detf.variable_scope
. Solo afecta a los nombres y no realiza un seguimiento de las variables ni la reutilización.
Si eso no funciona para su caso de uso, pruebe la función v1.train.init_from_checkpoint
. Toma un argumento assignment_map
, que especifica la asignación de nombres antiguos a nombres nuevos.
El repositorio de estimadores de TensorFlow incluye una herramienta de conversión para actualizar los puntos de control de los estimadores prefabricados de TensorFlow 1.xa 2.0. Puede servir como ejemplo de cómo crear una herramienta para un caso de uso similar.
Compatibilidad de modelos guardados
No hay problemas de compatibilidad importantes para los modelos guardados.
- Los modelos guardados de TensorFlow 1.x funcionan en TensorFlow 2.x.
- Los modelos guardados de TensorFlow 2.x funcionan en TensorFlow 1.x si se admiten todas las operaciones.
Un Graph.pb o Graph.pbtxt
No existe una forma sencilla de actualizar un archivo Graph.pb
sin Graph.pb
a TensorFlow 2.x. Su mejor opción es actualizar el código que generó el archivo.
Pero, si usted tiene un "gráfico congelado" (un tf.Graph
donde las variables se han convertido en constantes), entonces es posible convertir a un 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 ejemplo, aquí hay un gráfico congelado para 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
Cargue el tf.GraphDef
:
graph_def = tf.compat.v1.GraphDef()
loaded = graph_def.ParseFromString(open(path,'rb').read())
Envuélvalo en una concrete_function
:
inception_func = wrap_frozen_graph(
graph_def, inputs='input:0',
outputs='InceptionV1/InceptionV1/Mixed_3b/Branch_1/Conv2d_0a_1x1/Relu:0')
Pásale un 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
Entrenamiento con estimadores
Los estimadores son compatibles con TensorFlow 2.x.
Cuando usa estimadores, puede usar input_fn
, tf.estimator.TrainSpec
y tf.estimator.EvalSpec
de TensorFlow 1.x.
A continuación, se muestra un ejemplo en el que se usa input_fn
con especificaciones de entrenamiento y evaluación.
Creación de las especificaciones input_fn y 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 una definición de modelo de Keras
Existen algunas diferencias en cómo construir sus estimadores en TensorFlow 2.x.
Se recomienda que defina su modelo usando Keras, luego use la utilidad tf.keras.estimator.model_to_estimator
para convertir su modelo en un estimador. El siguiente código muestra cómo utilizar esta utilidad al crear y entrenar un 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 un model_fn
personalizado
Si tiene un estimador personalizado model_fn
existente que necesita mantener, puede convertir su model_fn
para usar un modelo de Keras.
Sin embargo, por razones de compatibilidad, un model_fn
personalizado aún se ejecutará en el modo de gráfico de estilo 1.x. Esto significa que no hay una ejecución ávida ni dependencias de control automático.
Model_fn personalizado con cambios mínimos
Para que su model_fn
personalizado funcione en TensorFlow 2.x, si prefiere cambios mínimos en el código existente, se pueden tf.compat.v1
símbolos tf.compat.v1
como optimizers
y metrics
.
Usar un modelo de Keras en un model_fn
personalizado es similar a usarlo en un ciclo de entrenamiento personalizado:
- Establezca la fase de
training
adecuada, según el argumento demode
. - Pase explícitamente las
trainable_variables
del modelo al optimizador.
Pero existen diferencias importantes en relación con un bucle personalizado :
- En lugar de utilizar
Model.losses
, extraiga las pérdidas utilizandoModel.get_losses_for
. - Extraiga las actualizaciones del modelo usando
Model.get_updates_for
.
El siguiente código crea un estimador a partir de un model_fn
personalizado, que ilustra todas estas preocupaciones.
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 con símbolos de TensorFlow 2.x
Si desea deshacerse de todos los símbolos de TensorFlow model_fn
actualizar su model_fn
personalizado a TensorFlow 2.x, debe actualizar el optimizador y las métricas a tf.keras.optimizers
y tf.keras.metrics
.
En el model_fn
personalizado_fn, además de los cambios anteriores, es necesario realizar más actualizaciones:
- Utilice
tf.keras.optimizers
lugar dev1.train.Optimizer
. - Pase explícitamente las
tf.keras.optimizers
trainable_variables
del modelo atf.keras.optimizers
. - Para calcular
train_op/minimize_op
,- Utilice
Optimizer.get_updates
si la pérdida es unTensor
pérdida escalar (no un invocable). El primer elemento de la lista devuelta es eltrain_op/minimize_op
deseado. - Si la pérdida es invocable (como una función), use
Optimizer.minimize
para obtenertrain_op/minimize_op
.
- Utilice
- Utilice
tf.keras.metrics
lugar detf.compat.v1.metrics
para la evaluación.
Para el ejemplo anterior de my_model_fn
, el código migrado con los símbolos de TensorFlow 2.x se muestra 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 prediseñados
Los estimadores prediseñados de la familia de tf.estimator.DNN*
, tf.estimator.Linear*
y tf.estimator.DNNLinearCombined*
todavía son compatibles con la API de TensorFlow 2.x. Sin embargo, algunos argumentos han cambiado:
-
input_layer_partitioner
: Eliminado en v2. -
loss_reduction
: actualizado atf.keras.losses.Reduction
lugar detf.compat.v1.losses.Reduction
. Su valor predeterminado también se cambia atf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE
detf.compat.v1.losses.Reduction.SUM
. -
optimizer
,dnn_optimizer
ylinear_optimizer
: este argumento se ha actualizado atf.keras.optimizers
lugar detf.compat.v1.train.Optimizer
.
Para migrar los cambios anteriores:
- No se necesita migración para
input_layer_partitioner
ya que laDistribution Strategy
lo manejará automáticamente en TensorFlow 2.x. - Para
loss_reduction
, consultetf.keras.losses.Reduction
para conocer las opciones admitidas. - Para los argumentos del
optimizer
:- Si no: 1) pasa el argumento del
optimizer
,dnn_optimizer
olinear_optimizer
, o 2) especifica el argumento deloptimizer
como unastring
en su código, entonces no necesita cambiar nada porquetf.keras.optimizers
se usa por defecto . - De lo contrario, debe actualizarlo desde
tf.compat.v1.train.Optimizer
a sustf.keras.optimizers
correspondientes.
- Si no: 1) pasa el argumento del
Convertidor de punto de control
La migración a keras.optimizers
romperá los puntos de control guardados con TensorFlow 1.x, ya que tf.keras.optimizers
genera un conjunto diferente de variables que se guardarán en los puntos de control. Para hacer que el punto de control antiguo sea reutilizable después de la migración a TensorFlow 2.x, prueba la herramienta de conversión de puntos de control .
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
La herramienta tiene ayuda incorporada:
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
Esta clase se simplificó para contener int
s, en lugar de objetos tf.compat.v1.Dimension
. Por lo tanto, no es necesario llamar a .value
para obtener un int
.
Los objetos individuales tf.compat.v1.Dimension
todavía son accesibles desde tf.TensorShape.dims
.
A continuación, se muestran las diferencias entre TensorFlow 1.xy TensorFlow 2.x.
# Create a shape and choose an index
i = 0
shape = tf.TensorShape([16, None, 256])
shape
TensorShape([16, None, 256])
Si tenía esto en TensorFlow 1.x:
value = shape[i].value
Luego haz esto en TensorFlow 2.x:
value = shape[i]
value
16
Si tenía esto en TensorFlow 1.x:
for dim in shape:
value = dim.value
print(value)
Luego haz esto en TensorFlow 2.x:
for value in shape:
print(value)
16 None 256
Si tenía esto en TensorFlow 1.x (o utilizó cualquier otro método de dimensión):
dim = shape[i]
dim.assert_is_compatible_with(other_dim)
Luego haz esto en 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
El valor booleano de un tf.TensorShape
es True
si se conoce el rango, False
caso contrario.
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
Otros cambios
Elimina
tf.colocate_with
: los algoritmos de ubicación de dispositivos de TensorFlow han mejorado significativamente. Esto ya no debería ser necesario. Si eliminarlo provoca una degradación del rendimiento , presente un error .Reemplace el uso de
v1.ConfigProto
con las funciones equivalentes detf.config
.
Conclusiones
El proceso general es:
- Ejecute el script de actualización.
- Elimina los símbolos contrib.
- Cambie sus modelos a un estilo orientado a objetos (Keras).
- Utilice los
tf.keras
formación y evaluación detf.keras
otf.estimator
donde pueda. - De lo contrario, use bucles personalizados, pero asegúrese de evitar sesiones y colecciones.
Se necesita un poco de trabajo para convertir el código a TensorFlow 2.x idiomático, pero cada cambio da como resultado:
- Menos líneas de código.
- Mayor claridad y sencillez.
- Depuración más sencilla.