本頁面由 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.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