此页面由 Cloud Translation API 翻译。
Switch to English

自动将代码升级到TensorFlow 2

在TensorFlow.org上查看 在Google Colab中运行 在GitHub上查看源代码 下载笔记本

TensorFlow 2.0包括许多API更改,例如重新排序参数,重命名符号以及更改参数的默认值。手动执行所有这些修改将很乏味并且容易出错。为了简化更改并尽可能无缝地过渡到TF 2.0,TensorFlow团队创建了tf_upgrade_v2实用程序来帮助将旧代码过渡到新API。

典型用法如下:

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

通过将现有的TensorFlow 1.x Python脚本转换为TensorFlow 2.0,它将加速您的升级过程。

转换脚本尽可能自动执行,但是仍然存在无法由脚本执行的语法和风格更改。

相容性模组

某些API符号不能仅通过使用字符串替换来升级。为确保TensorFlow 2.0中仍支持您的代码,升级脚本包括compat.v1模块。该模块将tf.foo之类的TF 1.x符号替换为等效的tf.compat.v1.foo参考。虽然兼容性模块不错,但我们建议您手动校对替换项,并尽快将其迁移到tf.*名称空间而不是tf.compat.v1名称空间中的新API。

由于TensorFlow 2.x模块的弃用(例如tf.flagstf.contrib ),某些更改无法通过切换到compat.v1compat.v1 。升级此代码可能需要使用其他库(例如absl.flags )或切换到tensorflow / addons中的软件包。

本指南的其余部分演示了如何使用升级脚本。虽然升级脚本易于使用,但强烈建议您将脚本用作以下过程的一部分:

  1. 单元测试 :确保要升级的代码具有覆盖范围合理的单元测试套件。这是Python代码,因此该语言不会保护您免受许多错误的困扰。还要确保您已经升级了与TensorFlow 2.0兼容的所有依赖项。

  2. 安装TensorFlow 1.14将TensorFlow升级到最新的TensorFlow 1.x版本,至少为1.14。这包括tf.compat.v2的最终TensorFlow 2.0 API。

  3. 使用1.14测试 :确保您的单元测试在这一点上通过。升级时会反复运行它们,因此从绿色开始很重要。

  4. 运行升级脚本 :在整个源代码树(包括测试)上运行tf_upgrade_v2 。这会将您的代码升级为仅使用TensorFlow 2.0中可用符号的格式。不推荐使用的符号将通过tf.compat.v1访问。这些最终将需要手动注意,但不是立即。

  5. 使用TensorFlow 1.14运行转换后的测试 :您的代码在TensorFlow 1.14中仍然可以正常运行。再次运行单元测试。您的测试中的任何错误均表示升级脚本中存在错误。 请让我们知道

  6. 检查升级报告中是否存在警告和错误 :脚本编写了一个报告文件,解释了您应仔细检查的所有转换或需要执行的任何手动操作。例如:任何其他contrib实例将需要手动操作才能删除。请查阅RFC了解更多说明

  7. 安装TensorFlow 2.0 :此时安全地切换到TensorFlow 2.0

  8. 使用v1.disable_v2_behavior测试 :在测试主函数中使用al v1.disable_v2_behavior()重新运行测试应该得到与在1.14下运行相同的结果。

  9. 启用V2行为 :现在您的测试使用v2 API进行了工作,您可以开始考虑启用v2行为了。根据您的代码编写方式,这可能需要进行一些更改。有关详细信息,请参见迁移指南

使用升级脚本

建立

在开始之前,请确保已安装TensorlFlow 2.0。

 import tensorflow as tf

print(tf.__version__)
 
2.2.0

克隆tensorflow / models git存储库,以便您可以测试以下代码:

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 | 21.01 MiB/s, done.
Resolving deltas: 100% (509/509), done.
Checking out files: 100% (2768/2768), done.

阅读帮助

该脚本应与TensorFlow一起安装。这是内置的帮助:

tf_upgrade_v2 -h
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] [--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 compact.v2 explicitly.
  --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

TF1代码示例

这是一个简单的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)

安装TensorFlow 2.0后,它不会运行:

(cd models/samples/cookbook/regression && python custom_regression.py)
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'

单文件

升级脚本可以在单个Python文件上运行:

 !tf_upgrade_v2 \
  --infile models/samples/cookbook/regression/custom_regression.py \
  --outfile /tmp/custom_regression_v2.py
 
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'


如果找不到该代码的修复程序,该脚本将打印错误。

目录树

包括此简单示例在内的典型项目将使用多个文件。通常要升级整个软件包,因此脚本也可以在目录树上运行:

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


注意有关dataset.make_one_shot_iterator函数的一个警告。

现在该脚本可用于TensorFlow 2.0:

请注意,由于使用tf.compat.v1模块,因此转换后的脚本也将在TensorFlow 1.14中运行。

(cd regression_v2 && python custom_regression.py 2>&1) | tail
I0723 01:38:37.875919 139960395478848 estimator.py:2066] Saving dict for global step 1000: global_step = 1000, loss = 309.0033, rmse = 2.5372365
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1000: /tmp/tmppypy65xc/model.ckpt-1000
I0723 01:38:37.917639 139960395478848 estimator.py:2127] Saving 'checkpoint_path' summary for global step 1000: /tmp/tmppypy65xc/model.ckpt-1000
Tensor("IteratorGetNext:25", shape=(None,), dtype=float64, device=/device:CPU:0)
Tensor("Squeeze:0", shape=(None,), dtype=float32)

********************************************************************************

RMS error for the test set: $2537


详细报告

该脚本还报告详细更改列表。在此示例中,它发现了一个可能不安全的转换,并在文件顶部包含一个警告:

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/automobile_data.py'
 outputting to 'regression_v2/automobile_data.py'

再次注意有关Dataset.make_one_shot_iterator function的一个警告。

在其他情况下,输出将说明不重要更改的原因:

 %%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
 
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.
--------------------------------------------------------------------------------


这是修改后的文件内容,请注意脚本如何添加参数名称来处理移动和重命名的参数:

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)

较大的项目可能包含一些错误。例如,转换deeplab模型:

 !tf_upgrade_v2 \
    --intree models/research/deeplab \
    --outtree deeplab_v2 \
    --reportfile deeplab_report.txt > /dev/null
 

它产生了输出文件:

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

但是有错误。该报告将帮助您在运行之前确定需要解决的问题。这是前三个错误:

cat deeplab_report.txt | grep -i models/research/deeplab | grep -i error | head -n 3
models/research/deeplab/vis.py:31: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/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/train.py:29: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.

“安全”模式

转换脚本还具有侵入性较小的SAFETY模式,可以简单地将导入更改为使用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
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)

如您所见,这不会升级您的代码,但确实允许TensorFlow 1代码在TensorFlow 2中运行

注意事项

  • 运行此脚本之前,请勿手动更新部分代码。特别是,对参数重新排序的函数(例如tf.argmaxtf.batch_to_space会导致脚本错误地添加错误映射现有代码的关键字参数。

  • 该脚本假定tensorflow是采用进口import tensorflow as tf

  • 该脚本不会对参数重新排序。相反,脚本会将关键字参数添加到对其参数重新排序的函数中。

  • 请查看tf2up.ml以获取便捷的工具,以升级GitHub存储库中的Jupyter笔记本和Python文件。

要报告升级脚本错误或提出功能请求,请在GitHub上发布问题。如果您正在测试TensorFlow 2.0,我们想听听它!加入TF 2.0测试社区 ,并将问题和讨论发送到testing@tensorflow.org