Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Actualizar el código automáticamente a TensorFlow 2

Ver en TensorFlow.org Ejecutar en Google Colab Ver fuente en GitHub Descargar cuaderno

TensorFlow 2.0 incluye muchos cambios en la API, como reordenar argumentos, cambiar el nombre de los símbolos y cambiar los valores predeterminados de los parámetros. Realizar manualmente todas estas modificaciones sería tedioso y propenso a errores. Para agilizar los cambios y hacer que su transición a TF 2.0 sea lo más fluida posible, el equipo de TensorFlow ha creado la utilidad tf_upgrade_v2 para ayudar en la transición del código heredado a la nueva API.

El uso típico es así:

tf_upgrade_v2 \
  --intree my_project/ \
  --outtree my_project_v2/ \
  --reportfile report.txt

Acelerará su proceso de actualización al convertir los scripts de Python de TensorFlow 1.x existentes en TensorFlow 2.0.

El script de conversión se automatiza tanto como sea posible, pero todavía hay cambios sintácticos y estilísticos que el script no puede realizar.

Módulos de compatibilidad

Ciertos símbolos de API no se pueden actualizar simplemente usando un reemplazo de cadena. Para garantizar que su código siga siendo compatible con TensorFlow 2.0, la secuencia de comandos de actualización incluye un módulo compat.v1 . Este módulo reemplaza los símbolos TF 1.x como tf.foo con la referencia tf.compat.v1.foo equivalente. Si bien el módulo de compatibilidad es bueno, le recomendamos que revise manualmente los reemplazos y los migre a nuevas API en el espacio de nombres tf.* lugar del espacio de nombres tf.compat.v1 más rápido posible.

Debido a la desaprobación del módulo TensorFlow 2.x (por ejemplo, tf.flags y tf.contrib ), algunos cambios no se pueden compat.v1 cambiando a compat.v1 . La actualización de este código puede requerir el uso de una biblioteca adicional (por ejemplo, absl.flags ) o cambiar a un paquete en tensorflow / addons .

El resto de esta guía demuestra cómo utilizar el script de actualización. Si bien el script de actualización es fácil de usar, se recomienda encarecidamente que utilice el script como parte del siguiente proceso:

  1. Prueba unitaria : asegúrese de que el código que está actualizando tenga un conjunto de pruebas unitarias con una cobertura razonable. Este es el código Python, por lo que el lenguaje no lo protegerá de muchas clases de errores. También asegúrese de que cualquier dependencia que tenga ya se haya actualizado para que sea compatible con TensorFlow 2.0.

  2. Instale TensorFlow 1.14 : actualice su TensorFlow a la última versión de TensorFlow 1.x, al menos 1.14. Esto incluye la API final de TensorFlow 2.0 en tf.compat.v2 .

  3. Probar con 1.14 : asegúrese de que sus pruebas unitarias pasen en este punto. Los ejecutará repetidamente a medida que actualice, por lo que comenzar desde verde es importante.

  4. Ejecute el script de actualización : Ejecute tf_upgrade_v2 en todo su árbol de fuentes, incluidas las pruebas. Esto actualizará su código a un formato en el que solo use símbolos disponibles en TensorFlow 2.0. Se accederá a los símbolos obsoletos con tf.compat.v1 . Estos eventualmente requerirán atención manual, pero no de inmediato.

  5. Ejecute las pruebas convertidas con TensorFlow 1.14 : su código aún debería ejecutarse bien en TensorFlow 1.14. Ejecute sus pruebas unitarias nuevamente. Cualquier error en sus pruebas aquí significa que hay un error en el script de actualización. Háganoslo saber .

  6. Consulte el informe de actualización para ver si hay advertencias y errores : el script escribe un archivo de informe que explica las conversiones que debe verificar o cualquier acción manual que deba realizar. Por ejemplo: cualquier instancia restante de contrib requerirá una acción manual para eliminarla. Consulte el RFC para obtener más instrucciones .

  7. Instale TensorFlow 2.0 : en este punto, debería ser seguro cambiar a TensorFlow 2.0

  8. Prueba con v1.disable_v2_behavior : Volver a ejecutar tus pruebas con al v1.disable_v2_behavior() en la función principal de pruebas debería dar los mismos resultados que ejecutar bajo 1.14.

  9. Habilite el comportamiento de la versión 2 : ahora que sus pruebas funcionan con la API de la versión 2, puede comenzar a buscar cómo activar el comportamiento de la versión 2. Dependiendo de cómo esté escrito su código, esto puede requerir algunos cambios. Consulte la guía de migración para obtener más detalles.

Usando el script de actualización

Preparar

Antes de comenzar, asegúrese de que TensorlFlow 2.0 esté instalado.

import tensorflow as tf

print(tf.__version__)
2.3.0

Clone el repositorio de git de tensorflow / models para que tenga algo de código para probar:

git clone --branch r1.13.0 --depth 1 https://github.com/tensorflow/models
Cloning into 'models'...
remote: Enumerating objects: 2927, done.[K
remote: Counting objects: 100% (2927/2927), done.[K
remote: Compressing objects: 100% (2449/2449), done.[K
remote: Total 2927 (delta 509), reused 2036 (delta 403), pack-reused 0[K
Receiving objects: 100% (2927/2927), 369.04 MiB | 44.65 MiB/s, done.
Resolving deltas: 100% (509/509), done.
Checking out files: 100% (2768/2768), done.

Leer la ayuda

La secuencia de comandos debe instalarse con TensorFlow. Aquí está la ayuda incorporada:

tf_upgrade_v2 -h
2020-09-10 01:42:59.274658: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
usage: tf_upgrade_v2 [-h] [--infile INPUT_FILE] [--outfile OUTPUT_FILE]
                     [--intree INPUT_TREE] [--outtree OUTPUT_TREE]
                     [--copyotherfiles COPY_OTHER_FILES] [--inplace]
                     [--no_import_rename] [--no_upgrade_compat_v1_import]
                     [--reportfile REPORT_FILENAME] [--mode {DEFAULT,SAFETY}]
                     [--print_all]

Convert a TensorFlow Python file from 1.x to 2.0

Simple usage:
  tf_upgrade_v2.py --infile foo.py --outfile bar.py
  tf_upgrade_v2.py --infile foo.ipynb --outfile bar.ipynb
  tf_upgrade_v2.py --intree ~/code/old --outtree ~/code/new

optional arguments:
  -h, --help            show this help message and exit
  --infile INPUT_FILE   If converting a single file, the name of the file to
                        convert
  --outfile OUTPUT_FILE
                        If converting a single file, the output filename.
  --intree INPUT_TREE   If converting a whole tree of files, the directory to
                        read from (relative or absolute).
  --outtree OUTPUT_TREE
                        If converting a whole tree of files, the output
                        directory (relative or absolute).
  --copyotherfiles COPY_OTHER_FILES
                        If converting a whole tree of files, whether to copy
                        the other files.
  --inplace             If converting a set of files, whether to allow the
                        conversion to be performed on the input files.
  --no_import_rename    Not to rename import to compat.v2 explicitly.
  --no_upgrade_compat_v1_import
                        If specified, don't upgrade explicit imports of
                        `tensorflow.compat.v1 as tf` to the v2 apis.
                        Otherwise, explicit imports of the form
                        `tensorflow.compat.v1 as tf` will be upgraded.
  --reportfile REPORT_FILENAME
                        The name of the file where the report log is
                        stored.(default: report.txt)
  --mode {DEFAULT,SAFETY}
                        Upgrade script mode. Supported modes: DEFAULT: Perform
                        only straightforward conversions to upgrade to 2.0. In
                        more difficult cases, switch to use compat.v1. SAFETY:
                        Keep 1.* code intact and import compat.v1 module.
  --print_all           Print full log to stdout instead of just printing
                        errors

Ejemplo de código TF1

Aquí hay una secuencia de comandos simple de TensorFlow 1.0:

head -n 65 models/samples/cookbook/regression/custom_regression.py | tail -n 10
  # Calculate loss using mean squared error
  average_loss = tf.losses.mean_squared_error(labels, predictions)

  # Pre-made estimators use the total_loss instead of the average,
  # so report total_loss for compatibility.
  batch_size = tf.shape(labels)[0]
  total_loss = tf.to_float(batch_size) * average_loss

  if mode == tf.estimator.ModeKeys.TRAIN:
    optimizer = params.get("optimizer", tf.train.AdamOptimizer)

Con TensorFlow 2.0 instalado, no se ejecuta:

(cd models/samples/cookbook/regression && python custom_regression.py)
2020-09-10 01:43:01.613673: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
Traceback (most recent call last):
  File "custom_regression.py", line 162, in <module>
    tf.logging.set_verbosity(tf.logging.INFO)
AttributeError: module 'tensorflow' has no attribute 'logging'

Fila india

La secuencia de comandos de actualización se puede ejecutar en un solo archivo de Python:

!tf_upgrade_v2 \
  --infile models/samples/cookbook/regression/custom_regression.py \
  --outfile /tmp/custom_regression_v2.py
2020-09-10 01:43:03.844314: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
INFO line 38:8: Renamed 'tf.feature_column.input_layer' to 'tf.compat.v1.feature_column.input_layer'
INFO line 43:10: Renamed 'tf.layers.dense' to 'tf.compat.v1.layers.dense'
INFO line 46:17: Renamed 'tf.layers.dense' to 'tf.compat.v1.layers.dense'
INFO line 57:17: tf.losses.mean_squared_error requires manual check. tf.losses have been replaced with object oriented versions in TF 2.0 and after. The loss function calls have been converted to compat.v1 for backward compatibility. Please update these calls to the TF 2.0 versions.
INFO line 57:17: Renamed 'tf.losses.mean_squared_error' to 'tf.compat.v1.losses.mean_squared_error'
INFO line 61:15: Added keywords to args of function 'tf.shape'
INFO line 62:15: Changed tf.to_float call to tf.cast(..., dtype=tf.float32).
INFO line 65:40: Renamed 'tf.train.AdamOptimizer' to 'tf.compat.v1.train.AdamOptimizer'
INFO line 68:39: Renamed 'tf.train.get_global_step' to 'tf.compat.v1.train.get_global_step'
INFO line 83:9: tf.metrics.root_mean_squared_error requires manual check. tf.metrics have been replaced with object oriented versions in TF 2.0 and after. The metric function calls have been converted to compat.v1 for backward compatibility. Please update these calls to the TF 2.0 versions.
INFO line 83:9: Renamed 'tf.metrics.root_mean_squared_error' to 'tf.compat.v1.metrics.root_mean_squared_error'
INFO line 142:23: Renamed 'tf.train.AdamOptimizer' to 'tf.compat.v1.train.AdamOptimizer'
INFO line 162:2: Renamed 'tf.logging.set_verbosity' to 'tf.compat.v1.logging.set_verbosity'
INFO line 162:27: Renamed 'tf.logging.INFO' to 'tf.compat.v1.logging.INFO'
INFO line 163:2: Renamed 'tf.app.run' to 'tf.compat.v1.app.run'
TensorFlow 2.0 Upgrade Script
-----------------------------
Converted 1 files
Detected 0 issues that require attention
--------------------------------------------------------------------------------


Make sure to read the detailed log 'report.txt'


El script imprimirá errores si no puede encontrar una solución para el código.

Árbol de directorio

Los proyectos típicos, incluido este sencillo ejemplo, utilizarán mucho más de un archivo. Por lo general, desea actualizar un paquete completo, por lo que el script también se puede ejecutar en un árbol de directorios:

# upgrade the .py files and copy all the other files to the outtree
!tf_upgrade_v2 \
    --intree models/samples/cookbook/regression/ \
    --outtree regression_v2/ \
    --reportfile tree_report.txt
2020-09-10 01:43:06.108169: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
INFO line 82:10: tf.estimator.LinearRegressor: Default value of loss_reduction has been changed to SUM_OVER_BATCH_SIZE; inserting old default value tf.keras.losses.Reduction.SUM.

INFO line 105:2: Renamed 'tf.logging.set_verbosity' to 'tf.compat.v1.logging.set_verbosity'
INFO line 105:27: Renamed 'tf.logging.INFO' to 'tf.compat.v1.logging.INFO'
INFO line 106:2: Renamed 'tf.app.run' to 'tf.compat.v1.app.run'
INFO line 58:10: tf.estimator.LinearRegressor: Default value of loss_reduction has been changed to SUM_OVER_BATCH_SIZE; inserting old default value tf.keras.losses.Reduction.SUM.

INFO line 101:2: Renamed 'tf.logging.set_verbosity' to 'tf.compat.v1.logging.set_verbosity'
INFO line 101:27: Renamed 'tf.logging.INFO' to 'tf.compat.v1.logging.INFO'
INFO line 102:2: Renamed 'tf.app.run' to 'tf.compat.v1.app.run'
WARNING line 125:15: Changing dataset.make_one_shot_iterator() to tf.compat.v1.data.make_one_shot_iterator(dataset). Please check this transformation.

INFO line 72:10: tf.estimator.DNNRegressor: Default value of loss_reduction has been changed to SUM_OVER_BATCH_SIZE; inserting old default value tf.keras.losses.Reduction.SUM.

INFO line 96:2: Renamed 'tf.logging.set_verbosity' to 'tf.compat.v1.logging.set_verbosity'
INFO line 96:27: Renamed 'tf.logging.INFO' to 'tf.compat.v1.logging.INFO'
INFO line 97:2: Renamed 'tf.app.run' to 'tf.compat.v1.app.run'
INFO line 38:8: Renamed 'tf.feature_column.input_layer' to 'tf.compat.v1.feature_column.input_layer'
INFO line 43:10: Renamed 'tf.layers.dense' to 'tf.compat.v1.layers.dense'
INFO line 46:17: Renamed 'tf.layers.dense' to 'tf.compat.v1.layers.dense'
INFO line 57:17: tf.losses.mean_squared_error requires manual check. tf.losses have been replaced with object oriented versions in TF 2.0 and after. The loss function calls have been converted to compat.v1 for backward compatibility. Please update these calls to the TF 2.0 versions.
INFO line 57:17: Renamed 'tf.losses.mean_squared_error' to 'tf.compat.v1.losses.mean_squared_error'
INFO line 61:15: Added keywords to args of function 'tf.shape'
INFO line 62:15: Changed tf.to_float call to tf.cast(..., dtype=tf.float32).
INFO line 65:40: Renamed 'tf.train.AdamOptimizer' to 'tf.compat.v1.train.AdamOptimizer'
INFO line 68:39: Renamed 'tf.train.get_global_step' to 'tf.compat.v1.train.get_global_step'
INFO line 83:9: tf.metrics.root_mean_squared_error requires manual check. tf.metrics have been replaced with object oriented versions in TF 2.0 and after. The metric function calls have been converted to compat.v1 for backward compatibility. Please update these calls to the TF 2.0 versions.
INFO line 83:9: Renamed 'tf.metrics.root_mean_squared_error' to 'tf.compat.v1.metrics.root_mean_squared_error'
INFO line 142:23: Renamed 'tf.train.AdamOptimizer' to 'tf.compat.v1.train.AdamOptimizer'
INFO line 162:2: Renamed 'tf.logging.set_verbosity' to 'tf.compat.v1.logging.set_verbosity'
INFO line 162:27: Renamed 'tf.logging.INFO' to 'tf.compat.v1.logging.INFO'
INFO line 163:2: Renamed 'tf.app.run' to 'tf.compat.v1.app.run'
INFO line 40:7: Renamed 'tf.test.mock' to 'tf.compat.v1.test.mock'
TensorFlow 2.0 Upgrade Script
-----------------------------
Converted 7 files
Detected 1 issues that require attention
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
File: models/samples/cookbook/regression/automobile_data.py
--------------------------------------------------------------------------------
models/samples/cookbook/regression/automobile_data.py:125:15: WARNING: Changing dataset.make_one_shot_iterator() to tf.compat.v1.data.make_one_shot_iterator(dataset). Please check this transformation.



Make sure to read the detailed log 'tree_report.txt'


Tenga en cuenta la única advertencia sobre la función dataset.make_one_shot_iterator .

Ahora el script funciona con TensorFlow 2.0:

Tenga en cuenta que debido al módulo tf.compat.v1 , la secuencia de comandos convertida también se ejecutará en TensorFlow 1.14.

(cd regression_v2 && python custom_regression.py 2>&1) | tail
    data = raw_dataframe()
  File "/tmpfs/src/temp/site/en/guide/regression_v2/automobile_data.py", line 67, in raw_dataframe
    dtype=COLUMN_TYPES, na_values="?")
  File "/home/kbuilder/.local/lib/python3.6/site-packages/pandas/io/parsers.py", line 686, in read_csv
    return _read(filepath_or_buffer, kwds)
  File "/home/kbuilder/.local/lib/python3.6/site-packages/pandas/io/parsers.py", line 449, in _read
    _validate_names(kwds.get("names", None))
  File "/home/kbuilder/.local/lib/python3.6/site-packages/pandas/io/parsers.py", line 417, in _validate_names
    raise ValueError("Names should be an ordered collection.")
ValueError: Names should be an ordered collection.

Reporte detallado

El guión también informa una lista de cambios detallados. En este ejemplo, encontró una transformación posiblemente insegura e incluyó una advertencia en la parte superior del archivo:

head -n 20 tree_report.txt
TensorFlow 2.0 Upgrade Script
-----------------------------
Converted 7 files
Detected 1 issues that require attention
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
File: models/samples/cookbook/regression/automobile_data.py
--------------------------------------------------------------------------------
models/samples/cookbook/regression/automobile_data.py:125:15: WARNING: Changing dataset.make_one_shot_iterator() to tf.compat.v1.data.make_one_shot_iterator(dataset). Please check this transformation.

================================================================================
Detailed log follows:

================================================================================
================================================================================
Input tree: 'models/samples/cookbook/regression/'
================================================================================
--------------------------------------------------------------------------------
Processing file 'models/samples/cookbook/regression/linear_regression_categorical.py'
 outputting to 'regression_v2/linear_regression_categorical.py'

Note nuevamente la advertencia sobre la Dataset.make_one_shot_iterator function .

En otros casos, la salida explicará el razonamiento de los cambios no triviales:

%%writefile dropout.py
import tensorflow as tf

d = tf.nn.dropout(tf.range(10), 0.2)
z = tf.zeros_like(d, optimize=False)
Writing dropout.py

!tf_upgrade_v2 \
  --infile dropout.py \
  --outfile dropout_v2.py \
  --reportfile dropout_report.txt > /dev/null
2020-09-10 01:43:10.977249: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1

cat dropout_report.txt
TensorFlow 2.0 Upgrade Script
-----------------------------
Converted 1 files
Detected 0 issues that require attention
--------------------------------------------------------------------------------
================================================================================
Detailed log follows:

================================================================================
--------------------------------------------------------------------------------
Processing file 'dropout.py'
 outputting to 'dropout_v2.py'
--------------------------------------------------------------------------------

3:4: INFO: Changing keep_prob arg of tf.nn.dropout to rate, and recomputing value.

4:4: INFO: Renaming tf.zeros_like to tf.compat.v1.zeros_like because argument optimize is present. tf.zeros_like no longer takes an optimize argument, and behaves as if optimize=True. This call site specifies something other than optimize=True, so it was converted to compat.v1.
--------------------------------------------------------------------------------


Aquí está el contenido del archivo modificado, observe cómo el script agrega nombres de argumentos para tratar los argumentos movidos y renombrados:

cat dropout_v2.py
import tensorflow as tf

d = tf.nn.dropout(tf.range(10), 1 - (0.2))
z = tf.compat.v1.zeros_like(d, optimize=False)

Un proyecto más grande puede contener algunos errores. Por ejemplo, convierta el modelo deeplab:

!tf_upgrade_v2 \
    --intree models/research/deeplab \
    --outtree deeplab_v2 \
    --reportfile deeplab_report.txt > /dev/null
2020-09-10 01:43:13.488610: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1

Produjo los archivos de salida:

ls deeplab_v2
README.md   datasets        input_preprocess.py        train.py
__init__.py deeplab_demo.ipynb  local_test.sh          utils
common.py   eval.py         local_test_mobilenetv2.sh  vis.py
common_test.py  export_model.py     model.py
core        g3doc           model_test.py

Pero hubo errores. El informe le ayudará a identificar lo que necesita corregir antes de que se ejecute. Aquí están los primeros tres errores:

cat deeplab_report.txt | grep -i models/research/deeplab | grep -i error | head -n 3
models/research/deeplab/export_model.py:25:7: ERROR: Using member tf.contrib.slim in deprecated module tf.contrib. tf.contrib.slim cannot be converted automatically. tf.contrib will not be distributed with TensorFlow 2.0, please consider an alternative in non-contrib TensorFlow, a community-maintained repository such as tensorflow/addons, or fork the required code.
models/research/deeplab/eval.py:28:7: ERROR: Using member tf.contrib.slim in deprecated module tf.contrib. tf.contrib.slim cannot be converted automatically. tf.contrib will not be distributed with TensorFlow 2.0, please consider an alternative in non-contrib TensorFlow, a community-maintained repository such as tensorflow/addons, or fork the required code.
models/research/deeplab/eval.py:146:8: ERROR: Using member tf.contrib.metrics.aggregate_metric_map in deprecated module tf.contrib. tf.contrib.metrics.aggregate_metric_map cannot be converted automatically. tf.contrib will not be distributed with TensorFlow 2.0, please consider an alternative in non-contrib TensorFlow, a community-maintained repository such as tensorflow/addons, or fork the required code.

"Modo seguro

El script de conversión también tiene un modo SAFETY menos invasivo que simplemente cambia las importaciones para usar el módulo tensorflow.compat.v1 :

cat dropout.py
import tensorflow as tf

d = tf.nn.dropout(tf.range(10), 0.2)
z = tf.zeros_like(d, optimize=False)

tf_upgrade_v2 --mode SAFETY --infile dropout.py --outfile dropout_v2_safe.py > /dev/null
2020-09-10 01:43:17.892207: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1

cat dropout_v2_safe.py
import tensorflow.compat.v1 as tf

d = tf.nn.dropout(tf.range(10), 0.2)
z = tf.zeros_like(d, optimize=False)

Como puede ver, esto no actualiza su código, pero permite que el código de TensorFlow 1 se ejecute en TensorFlow 2

Advertencias

  • No actualice partes de su código manualmente antes de ejecutar este script. En particular, las funciones que han tenido argumentos reordenados como tf.argmax o tf.batch_to_space hacen que el script agregue incorrectamente argumentos de palabras clave que no coinciden con su código existente.

  • El script asume que tensorflow se importa usando import tensorflow as tf .

  • Este script no reordena los argumentos. En su lugar, el script agrega argumentos de palabras clave a las funciones cuyos argumentos se han reordenado.

  • Consulte tf2up.ml para obtener una herramienta conveniente para actualizar los cuadernos de Jupyter y los archivos de Python en un repositorio de GitHub.

Para informar errores de script de actualización o realizar solicitudes de funciones, presente un problema en GitHub . Y si está probando TensorFlow 2.0, ¡queremos saberlo! Únase a la comunidad de TF 2.0 Testing y envíe preguntas y debates a testing@tensorflow.org .