午前9時PSTでMLシンポジウム、この10月19日(火曜日)の最初の女性の中にチューン今すぐ登録

コードを TensorFlow 2 に自動的にアップグレードする

TensorFlow.orgで表示 Google Colabで実行 GitHubでソースを表示 ノートブックをダウンロード

TensorFlow 2.0には引数の並べ替え、シンボル名の変更、パラメータのデフォルト値の変更など、多くのAPIの変更が含まれています。これらの変更をすべて手動で実行するのは退屈で、エラーが発生しやすくなります。変更を合理化し、可能な限りシームレスに TF 2.0 に移行できるよう、TensorFlow チームはレガシーコードの新しい API への移行を支援する tf_upgrade_v2 ユーティリティを作成しています。

注意: tf_upgrade_v2 は TensorFlow 1.13 以降(すべての TF 2.0 ビルドを含む)に自動的にインストールされています。

一般的な使用方法は以下のとおりです。

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.compat.v1 名前空間ではなく tf.* 名前空間の新しい 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 でのテスト: テストの main 関数で v1.disable_v2_behavior() を使用してテストをもう一度実行すると、1.14 で実行した場合と同じ結果になるはずです。

  9. V2の動作を有効化: テストが v2 API を使用して動作するようになったため、v2 の動作をオンにすることを検討し始めることができます。コードの記述方法によっては、若干の変更が必要になる場合があります。詳細については、移行ガイドを参照してください。

アップグレードスクリプトの使用

セットアップ

始める前に、TensorlFlow 2.0 がインストールされていることを確認してください。

import tensorflow as tf

print(tf.__version__)
2.4.1

テスト対象のコードがある 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% (2428/2428), done.[K
remote: Total 2927 (delta 505), reused 2108 (delta 424), pack-reused 0[K
Receiving objects: 100% (2927/2927), 369.04 MiB | 41.57 MiB/s, done.
Resolving deltas: 100% (505/505), done.
Checking out files: 100% (2768/2768), done.

ヘルプを読む

スクリプトは TensorFlow と共にインストールされています。組み込みのヘルプは次のとおりです。

tf_upgrade_v2 -h
2021-04-07 19:59:44.464974: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
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

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)
/bin/bash: -c: line 0: syntax error near unexpected token `;&'
/bin/bash: -c: line 0: `(cd models/samples/cookbook/regression && python custom_regression.py)'

単一ファイル

アップグレードスクリプトは単体の Python ファイルに対して実行できます。

!tf_upgrade_v2 \
  --infile models/samples/cookbook/regression/custom_regression.py \
  --outfile /tmp/custom_regression_v2.py
2021-04-07 19:59:46.898804: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
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
2021-04-07 19:59:49.061857: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
INFO line 40:7: Renamed 'tf.test.mock' to 'tf.compat.v1.test.mock'
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 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 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'
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'
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 関数に関して警告が 1 つ表示されていることに注意してください。

これで、スクリプトが TensorFlow 2.0 で動作するようになりました。

tf.compat.v1 モジュールのため、変換後のスクリプトは TensorFlow 1.14 でも実行されることに注意してください。

(cd regression_v2 && python custom_regression.py 2>&1) | tail
I0407 19:59:59.827209 140544197162816 estimator.py:2066] Saving dict for global step 1000: global_step = 1000, loss = 1279.7684, rmse = 5.163511
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1000: /tmp/tmpzpm9qhwm/model.ckpt-1000
I0407 19:59:59.872012 140544197162816 estimator.py:2127] Saving 'checkpoint_path' summary for global step 1000: /tmp/tmpzpm9qhwm/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: $5164

詳細レポート

このスクリプトは、詳細な変更のリストも報告します。この例では安全でない可能性のある変換が 1 つ検出され、ファイルの先頭で警告が表示されています。

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

再度 Dataset.make_one_shot_iterator function に関して警告が 1 つ表示されていることに注意してください。

その他の場合、重要な変更の根拠が出力されます。

%%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
2021-04-07 20:00:01.571539: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
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
2021-04-07 20:00:03.971225: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0

次のような出力ファイルが生成されました。

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

しかし、エラーが発生していました。レポートは、実行前に修正する必要があるものを正確に把握するのに役立ちます。最初の 3 つのエラーは次のとおりです。

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

"Safety" モード

この変換スクリプトには tensorflow.compat.v1 モジュールを使用するようにインポートを変更するだけの侵襲性の低い SAFETY モードもあります。

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
2021-04-07 20:00:08.139851: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
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 などの引数の順序が変更された関数により、既存コードを誤ってマッピングするキーワード引数が不正に追加されてしまいます。

  • このスクリプトは tensorflowimport tensorflow as tf を使用してインポートされていることを前提としています。

  • このスクリプトは引数の順序を変更しません。その代わり、キーワード引数を引数の順序が変更された関数に追加します。

  • GitHub リポジトリ内の Jupyter ノートブックと Python ファイルをアップグレードするための便利なツールについては、tf2up.ml をチェックしてください。

アップグレードスクリプトのバグの報告または機能リクエストを行うには、GitHub で課題を報告してください。また、TensorFlow 2.0 をテストしている場合は結果をお聞かせください!TF 2.0 テストコミュニティに参加し、質問や議論を testing@tensorflow.org 宛に投稿してください。