TF1.x -> Descripción general de la migración TF2

TensorFlow 2 es fundamentalmente diferente de TF1.x en varios aspectos. Aún puede ejecutar código TF1.x sin modificar ( excepto contrib ) en instalaciones binarias TF2 de esta manera:

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

Sin embargo, esto no ejecuta comportamientos ni API de TF2 y es posible que no funcione como se esperaba con el código escrito para TF2. Si no está ejecutando con los comportamientos de TF2 activos, efectivamente está ejecutando TF1.x sobre una instalación de TF2. Lea la guía de comportamiento de TF1 vs TF2 para obtener más detalles sobre en qué se diferencia TF2 de TF1.x.

Esta guía proporciona una descripción general del proceso para migrar su código TF1.x a TF2. Esto le permite aprovechar las mejoras de funciones nuevas y futuras y también hacer que su código sea más simple, más eficaz y más fácil de mantener.

Si está utilizando las API de alto nivel de tf.keras y está entrenando exclusivamente con model.fit , su código debería ser más o menos totalmente compatible con TF2, excepto por las siguientes advertencias:

Proceso de migración TF2

Antes de migrar, conozca el comportamiento y las diferencias de API entre TF1.x y TF2 leyendo la guía .

  1. Ejecute el script automatizado para convertir parte del uso de la API TF1.x a tf.compat.v1 .
  2. Elimine los símbolos tf.contrib antiguos (consulte TF Addons y TF-Slim ).
  3. Haga que los pases directos del modelo TF1.x se ejecuten en TF2 con la ejecución ansiosa habilitada.
  4. Actualice su código TF1.x para entrenar bucles y guardar/cargar modelos a equivalentes TF2.
  5. (Opcional) Migre sus API tf.compat.v1 compatibles con TF2 a API TF2 idiomáticas.

Las siguientes secciones amplían los pasos descritos anteriormente.

Ejecute el script de conversión de símbolos

Esto ejecuta un paso inicial para reescribir los símbolos de su código para ejecutarlos en binarios de TF 2.x, pero no hará que su código sea idiomático para TF 2.x ni hará que su código sea automáticamente compatible con los comportamientos de TF2.

Lo más probable es que su código siga utilizando puntos finales tf.compat.v1 para acceder a marcadores de posición, sesiones, colecciones y otras funciones de estilo TF1.x.

Lea la guía para obtener más información sobre las mejores prácticas para utilizar el script de conversión de símbolos.

Eliminar el uso de tf.contrib

El módulo tf.contrib se ha desactivado y varios de sus submódulos se han integrado en la API principal de TF2. Los otros submódulos ahora se derivan de otros proyectos como TF IO y TF Addons .

Una gran cantidad de código TF1.x antiguo utiliza la biblioteca Slim , que estaba empaquetada con TF1.x como tf.contrib.layers . Al migrar su código Slim a TF2, cambie los usos de su Slim API para que apunten al paquete tf-slim pip . Luego, lea la guía de mapeo de modelos para aprender cómo convertir código Slim.

Alternativamente, si usa modelos previamente entrenados de Slim, puede considerar probar los modelos previamente entrenados de Keras desde tf.keras.applications o los TF2 SavedModel de TF Hub exportados desde el código Slim original.

Haga que los pases hacia adelante del modelo TF1.x se ejecuten con los comportamientos TF2 habilitados

Seguimiento de variables y pérdidas

TF2 no admite colecciones globales.

La ejecución ansiosa en TF2 no admite las API basadas en colecciones tf.Graph . Esto afecta la forma en que construye y realiza un seguimiento de las variables.

Para el nuevo código TF2, usaría tf.Variable en lugar de v1.get_variable y usaría objetos Python para recopilar y rastrear variables en lugar de tf.compat.v1.variable_scope . Normalmente este sería uno de:

Listas agregadas de variables (como tf.Graph.get_collection(tf.GraphKeys.VARIABLES) ) con los atributos .variables y .trainable_variables de los objetos Layer , Module o Model .

Las clases 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 .

Lea la guía de mapeo de modelos para obtener más información sobre el uso de las correcciones de modelado de código TF2 para incrustar su código existente basado en get_variable y variable_scope dentro de Layers , Models y Modules . Esto le permitirá ejecutar pases hacia adelante con la ejecución ansiosa habilitada sin reescrituras importantes.

Adaptarse a otros cambios de comportamiento

Si la guía de mapeo del modelo por sí sola no es suficiente para que su modelo avance ejecutando otros cambios de comportamiento que pueden ser más detallados, consulte la guía sobre comportamientos TF1.x vs TF2 para conocer los otros cambios de comportamiento y cómo puede adaptarse a ellos. . Consulte también la guía para crear nuevas capas y modelos mediante subclases para obtener más detalles.

Validando tus resultados

Consulte la guía de validación de modelos para obtener herramientas sencillas y orientación sobre cómo puede validar (numéricamente) que su modelo se está comportando correctamente cuando la ejecución activa está habilitada. Puede que esto le resulte especialmente útil si lo combina con la guía de mapeo de modelos .

Actualización de capacitación, evaluación e importación/exportación de código

Los bucles de entrenamiento de TF1.x creados con v1.Session -style tf.estimator.Estimator sy otros enfoques basados ​​en colecciones no son compatibles con los nuevos comportamientos de TF2. Es importante que migre todo su código de entrenamiento TF1.x, ya que combinarlo con el código TF2 puede provocar comportamientos inesperados.

Puede elegir entre varias estrategias para hacer esto.

El enfoque de más alto nivel es utilizar tf.keras . Las funciones de alto nivel en Keras gestionan muchos de los detalles de bajo nivel que pueden pasar fácilmente 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.

Consulte la guía de migración de Estimator para saber cómo migrar el código de tf.estimator.Estimator para usar bucles de entrenamiento básicos y personalizados tf.keras .

Los bucles de entrenamiento personalizados le brindan un control más preciso sobre su modelo, como el seguimiento de los pesos de capas individuales. Lea la guía sobre cómo crear bucles de entrenamiento desde cero para aprender cómo usar tf.GradientTape para recuperar los pesos del modelo y usarlos para actualizar el modelo.

Convertir optimizadores TF1.x en optimizadores Keras

Los optimizadores en tf.compat.v1.train , como el optimizador Adam y el optimizador de descenso de gradiente , tienen equivalentes en tf.keras.optimizers .

La siguiente tabla resume cómo puede convertir estos optimizadores heredados a sus equivalentes de Keras. Puede reemplazar directamente la versión TF1.x con la versión TF2 a menos que se requieran pasos adicionales (como actualizar la tasa de aprendizaje predeterminada ).

Tenga en cuenta que la conversión de sus optimizadores puede hacer que los puntos de control antiguos sean incompatibles .

TF1.x TF2 Pasos adicionales
`tf.v1.train.GradientDescentOptimizer` tf.keras.optimizers.SGD Ninguno
`tf.v1.train.MomentumOptimizer` tf.keras.optimizers.SGD Incluir el argumento "impulso"
`tf.v1.train.AdamOptimizer` tf.keras.optimizers.Adam Cambie el nombre de los argumentos `beta1` y `beta2` a `beta_1` y `beta_2`
`tf.v1.train.RMSPropOptimizer` tf.keras.optimizers.RMSprop Cambie el nombre del argumento "decay" a "rho"
`tf.v1.train.AdadeltaOptimizer` tf.keras.optimizers.Adadelta Ninguno
`tf.v1.train.AdagradOptimizer` tf.keras.optimizers.Adagrad Ninguno
`tf.v1.train.FtrlOptimizer` tf.keras.optimizers.Ftrl Elimine los argumentos `accum_name` y `linear_name`
`tf.contrib.AdamaxOptimizer` tf.keras.optimizers.Adamax Cambie el nombre de los argumentos `beta1` y `beta2` a `beta_1` y `beta_2`
`tf.contrib.Nadam` tf.keras.optimizers.Nadam Cambie el nombre de los argumentos `beta1` y `beta2` a `beta_1` y `beta_2`

Actualizar canales de entrada de datos

Hay muchas formas de introducir datos en 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. Los dataset que pertenecen a tf.data son eficientes, expresivos y se integran bien con TF2.

Se pueden pasar directamente al método tf.keras.Model.fit .

model.fit(dataset, epochs=5)

Se pueden iterar directamente sobre Python estándar:

for example_batch, label_batch in dataset:
    break

Si todavía usa tf.queue , ahora solo se admiten como estructuras de datos, no como canalizaciones de entrada.

También debe migrar todo el código de preprocesamiento de funciones que utiliza tf.feature_columns . Lea la guía de migración para más detalles.

Guardar y cargar modelos

TF2 utiliza puntos de control basados ​​en objetos. Lea la guía de migración de puntos de control para obtener más información sobre cómo migrar puntos de control TF1.x basados ​​en nombres. Lea también la guía de puntos de control en los documentos principales de TensorFlow.

No existen problemas de compatibilidad importantes para los modelos guardados. Lea la guía SavedModel para obtener más información sobre cómo migrar SavedModel s en TF1.x a TF2. En general,

  • Los modelos_guardados de TF1.x funcionan en TF2.
  • Los modelos guardados de TF2 funcionan en TF1.x si todas las operaciones son compatibles.

Consulte también la sección GraphDef en la guía de migración SavedModel para obtener más información sobre cómo trabajar con objetos Graph.pb y Graph.pbtxt .

(Opcional) Migrar los símbolos tf.compat.v1

El módulo tf.compat.v1 contiene la API TF1.x completa, con su semántica original.

Incluso después de seguir los pasos anteriores y terminar con un código que es totalmente compatible con todos los comportamientos de TF2, es probable que haya muchas menciones de apis compat.v1 que resultan ser compatibles con TF2. Debe evitar el uso de estas API heredadas compat.v1 para cualquier código nuevo que escriba, aunque seguirán funcionando para el código ya escrito.

Sin embargo, puede optar por migrar los usos existentes a API TF2 no heredadas. Las cadenas de documentación de los símbolos compat.v1 individuales a menudo explicarán cómo migrarlos a API TF2 no heredadas. Además, la sección de la guía de mapeo de modelos sobre migración incremental a API TF2 idiomáticas también puede ayudar con esto.

Recursos y lecturas adicionales

Como se mencionó anteriormente, es una buena práctica migrar todo el código TF1.x a TF2. Lea las guías en la sección Migrar a TF2 de la guía de TensorFlow para obtener más información.

,

TensorFlow 2 es fundamentalmente diferente de TF1.x en varios aspectos. Aún puede ejecutar código TF1.x sin modificar ( excepto contrib ) en instalaciones binarias TF2 de esta manera:

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

Sin embargo, esto no ejecuta comportamientos ni API de TF2 y es posible que no funcione como se esperaba con el código escrito para TF2. Si no está ejecutando con los comportamientos de TF2 activos, efectivamente está ejecutando TF1.x sobre una instalación de TF2. Lea la guía de comportamiento de TF1 vs TF2 para obtener más detalles sobre en qué se diferencia TF2 de TF1.x.

Esta guía proporciona una descripción general del proceso para migrar su código TF1.x a TF2. Esto le permite aprovechar las mejoras de funciones nuevas y futuras y también hacer que su código sea más simple, más eficaz y más fácil de mantener.

Si está utilizando las API de alto nivel de tf.keras y está entrenando exclusivamente con model.fit , su código debería ser más o menos totalmente compatible con TF2, excepto por las siguientes advertencias:

Proceso de migración TF2

Antes de migrar, conozca el comportamiento y las diferencias de API entre TF1.x y TF2 leyendo la guía .

  1. Ejecute el script automatizado para convertir parte del uso de la API TF1.x a tf.compat.v1 .
  2. Elimine los símbolos tf.contrib antiguos (consulte TF Addons y TF-Slim ).
  3. Haga que los pases directos del modelo TF1.x se ejecuten en TF2 con la ejecución ansiosa habilitada.
  4. Actualice su código TF1.x para entrenar bucles y guardar/cargar modelos a equivalentes TF2.
  5. (Opcional) Migre sus API tf.compat.v1 compatibles con TF2 a API TF2 idiomáticas.

Las siguientes secciones amplían los pasos descritos anteriormente.

Ejecute el script de conversión de símbolos

Esto ejecuta un paso inicial para reescribir los símbolos de su código para ejecutarlos en binarios de TF 2.x, pero no hará que su código sea idiomático para TF 2.x ni hará que su código sea automáticamente compatible con los comportamientos de TF2.

Lo más probable es que su código siga utilizando puntos finales tf.compat.v1 para acceder a marcadores de posición, sesiones, colecciones y otras funciones de estilo TF1.x.

Lea la guía para obtener más información sobre las mejores prácticas para utilizar el script de conversión de símbolos.

Eliminar el uso de tf.contrib

El módulo tf.contrib se ha desactivado y varios de sus submódulos se han integrado en la API principal de TF2. Los otros submódulos ahora se derivan de otros proyectos como TF IO y TF Addons .

Una gran cantidad de código TF1.x antiguo utiliza la biblioteca Slim , que estaba empaquetada con TF1.x como tf.contrib.layers . Al migrar su código Slim a TF2, cambie los usos de su Slim API para que apunten al paquete tf-slim pip . Luego, lea la guía de mapeo de modelos para aprender cómo convertir código Slim.

Alternativamente, si usa modelos previamente entrenados de Slim, puede considerar probar los modelos previamente entrenados de Keras desde tf.keras.applications o los TF2 SavedModel de TF Hub exportados desde el código Slim original.

Haga que los pases hacia adelante del modelo TF1.x se ejecuten con los comportamientos TF2 habilitados

Seguimiento de variables y pérdidas

TF2 no admite colecciones globales.

La ejecución ansiosa en TF2 no admite las API basadas en colecciones tf.Graph . Esto afecta la forma en que construye y realiza un seguimiento de las variables.

Para el nuevo código TF2, usaría tf.Variable en lugar de v1.get_variable y usaría objetos Python para recopilar y rastrear variables en lugar de tf.compat.v1.variable_scope . Normalmente este sería uno de:

Listas agregadas de variables (como tf.Graph.get_collection(tf.GraphKeys.VARIABLES) ) con los atributos .variables y .trainable_variables de los objetos Layer , Module o Model .

Las clases 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 .

Lea la guía de mapeo de modelos para obtener más información sobre el uso de las correcciones de modelado de código TF2 para incrustar su código existente basado en get_variable y variable_scope dentro de Layers , Models y Modules . Esto le permitirá ejecutar pases hacia adelante con la ejecución ansiosa habilitada sin reescrituras importantes.

Adaptarse a otros cambios de comportamiento

Si la guía de mapeo del modelo por sí sola no es suficiente para que su modelo avance ejecutando otros cambios de comportamiento que pueden ser más detallados, consulte la guía sobre comportamientos TF1.x vs TF2 para conocer los otros cambios de comportamiento y cómo puede adaptarse a ellos. . Consulte también la guía para crear nuevas capas y modelos mediante subclases para obtener más detalles.

Validando tus resultados

Consulte la guía de validación de modelos para obtener herramientas sencillas y orientación sobre cómo puede validar (numéricamente) que su modelo se está comportando correctamente cuando la ejecución entusiasta está habilitada. Puede que esto le resulte especialmente útil si lo combina con la guía de mapeo de modelos .

Actualización de capacitación, evaluación e importación/exportación de código

Los bucles de entrenamiento de TF1.x creados con v1.Session -style tf.estimator.Estimator sy otros enfoques basados ​​en colecciones no son compatibles con los nuevos comportamientos de TF2. Es importante que migre todo su código de entrenamiento TF1.x, ya que combinarlo con el código TF2 puede provocar comportamientos inesperados.

Puede elegir entre varias estrategias para hacer esto.

El enfoque de más alto nivel es utilizar tf.keras . Las funciones de alto nivel en Keras gestionan muchos de los detalles de bajo nivel que pueden pasar fácilmente 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.

Consulte la guía de migración de Estimator para saber cómo migrar el código de tf.estimator.Estimator para usar bucles de entrenamiento básicos y personalizados tf.keras .

Los bucles de entrenamiento personalizados le brindan un control más preciso sobre su modelo, como el seguimiento de los pesos de capas individuales. Lea la guía sobre cómo crear bucles de entrenamiento desde cero para aprender cómo usar tf.GradientTape para recuperar los pesos del modelo y usarlos para actualizar el modelo.

Convertir optimizadores TF1.x en optimizadores Keras

Los optimizadores en tf.compat.v1.train , como el optimizador Adam y el optimizador de descenso de gradiente , tienen equivalentes en tf.keras.optimizers .

La siguiente tabla resume cómo puede convertir estos optimizadores heredados a sus equivalentes de Keras. Puede reemplazar directamente la versión TF1.x con la versión TF2 a menos que se requieran pasos adicionales (como actualizar la tasa de aprendizaje predeterminada ).

Tenga en cuenta que la conversión de sus optimizadores puede hacer que los puntos de control antiguos sean incompatibles .

TF1.x TF2 Pasos adicionales
`tf.v1.train.GradientDescentOptimizer` tf.keras.optimizers.SGD Ninguno
`tf.v1.train.MomentumOptimizer` tf.keras.optimizers.SGD Incluir el argumento "impulso"
`tf.v1.train.AdamOptimizer` tf.keras.optimizers.Adam Cambie el nombre de los argumentos `beta1` y `beta2` a `beta_1` y `beta_2`
`tf.v1.train.RMSPropOptimizer` tf.keras.optimizers.RMSprop Cambie el nombre del argumento "decay" a "rho"
`tf.v1.train.AdadeltaOptimizer` tf.keras.optimizers.Adadelta Ninguno
`tf.v1.train.AdagradOptimizer` tf.keras.optimizers.Adagrad Ninguno
`tf.v1.train.FtrlOptimizer` tf.keras.optimizers.Ftrl Elimine los argumentos `accum_name` y `linear_name`
`tf.contrib.AdamaxOptimizer` tf.keras.optimizers.Adamax Cambie el nombre de los argumentos `beta1` y `beta2` a `beta_1` y `beta_2`
`tf.contrib.Nadam` tf.keras.optimizers.Nadam Cambie el nombre de los argumentos `beta1` y `beta2` a `beta_1` y `beta_2`

Actualizar canales de entrada de datos

Hay muchas formas de introducir datos en 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. Los dataset que pertenecen a tf.data son eficientes, expresivos y se integran bien con TF2.

Se pueden pasar directamente al método tf.keras.Model.fit .

model.fit(dataset, epochs=5)

Se pueden iterar directamente sobre Python estándar:

for example_batch, label_batch in dataset:
    break

Si todavía usa tf.queue , ahora solo se admiten como estructuras de datos, no como canalizaciones de entrada.

También debe migrar todo el código de preprocesamiento de funciones que utiliza tf.feature_columns . Lea la guía de migración para más detalles.

Guardar y cargar modelos

TF2 utiliza puntos de control basados ​​en objetos. Lea la guía de migración de puntos de control para obtener más información sobre cómo migrar puntos de control TF1.x basados ​​en nombres. Lea también la guía de puntos de control en los documentos principales de TensorFlow.

No existen problemas de compatibilidad importantes para los modelos guardados. Lea la guía SavedModel para obtener más información sobre cómo migrar SavedModel s en TF1.x a TF2. En general,

  • Los modelos_guardados de TF1.x funcionan en TF2.
  • Los modelos guardados de TF2 funcionan en TF1.x si todas las operaciones son compatibles.

Consulte también la sección GraphDef en la guía de migración SavedModel para obtener más información sobre cómo trabajar con objetos Graph.pb y Graph.pbtxt .

(Opcional) Migrar los símbolos tf.compat.v1

El módulo tf.compat.v1 contiene la API TF1.x completa, con su semántica original.

Incluso después de seguir los pasos anteriores y terminar con un código que es totalmente compatible con todos los comportamientos de TF2, es probable que haya muchas menciones de apis compat.v1 que resultan ser compatibles con TF2. Debe evitar el uso de estas API heredadas compat.v1 para cualquier código nuevo que escriba, aunque seguirán funcionando para el código ya escrito.

Sin embargo, puede optar por migrar los usos existentes a API TF2 no heredadas. Las cadenas de documentación de los símbolos compat.v1 individuales a menudo explicarán cómo migrarlos a API TF2 no heredadas. Además, la sección de la guía de mapeo de modelos sobre migración incremental a API TF2 idiomáticas también puede ayudar con esto.

Recursos y lecturas adicionales

Como se mencionó anteriormente, es una buena práctica migrar todo el código TF1.x a TF2. Lea las guías en la sección Migrar a TF2 de la guía de TensorFlow para obtener más información.