自動重寫 TF 1.x 和 compat.v1 API 符號

在 TensorFlow.org 上檢視 在 Google Colab 中執行 在 GitHub 上檢視原始碼 下載筆記本

TensorFlow 2.x 包含許多與 TF 1.x 和 tf.compat.v1 API 不同的 API 變更,例如引數重新排序、符號重新命名,以及參數預設值變更。手動執行所有這些修改既繁瑣又容易出錯。為了簡化變更,並讓您儘可能順暢地轉換至 TF 2.x,TensorFlow 團隊建立了 tf_upgrade_v2 公用程式,以協助將舊版程式碼轉換為新的 API。

一般用法如下

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

它將現有的 TensorFlow 1.x Python 指令碼轉換為 TensorFlow 2.x,從而加速您的升級程序。

轉換指令碼會自動執行許多機械式的 API 轉換,但許多 API 無法自動遷移。它也無法完全讓您的程式碼與 TF2 行為和 API 相容。因此,它只是您遷移旅程的一部分。

相容性模組

某些 API 符號無法僅透過字串取代來升級。無法自動升級的符號將會對應到 compat.v1 模組中的位置。這個模組會將 TF 1.x 符號 (例如 tf.foo) 取代為對等的 tf.compat.v1.foo 參照。如果您已經透過 import tensorflow.compat.v1 as tf 匯入 TF 的方式使用 compat.v1 API,tf_upgrade_v2 指令碼會嘗試盡可能將這些用法轉換為非相容性 API。請注意,雖然部分 compat.v1 API 與 TF2.x 行為相容,但許多 API 並不相容。因此,建議您手動校對取代項目,並儘快將其遷移至 tf.* 命名空間中的新 API,而不是 tf.compat.v1 命名空間。

由於 TensorFlow 2.x 模組已淘汰 (例如 tf.flagstf.contrib),因此某些變更無法透過切換至 compat.v1 來解決。升級此程式碼可能需要使用額外的程式庫 (例如 absl.flags) 或切換至 tensorflow/addons 中的套件。

本指南的其餘部分將示範如何使用符號重寫指令碼。雖然指令碼很容易使用,但強烈建議您將指令碼作為以下程序的一部分使用

  1. 單元測試:確保您要升級的程式碼具有單元測試套件,且涵蓋範圍合理。這是 Python 程式碼,因此語言無法保護您免於許多類型的錯誤。另請確保您擁有的任何依附元件都已升級為與 TensorFlow 2.x 相容。

  2. 安裝 TensorFlow 1.15:將您的 TensorFlow 升級至最新的 TensorFlow 1.x 版本,至少 1.15。這包括 tf.compat.v2 中的最終 TensorFlow 2.0 API。

  3. 使用 1.15 進行測試:確保您的單元測試在此時通過。您會在升級時重複執行這些測試,因此從綠燈開始很重要。

  4. 執行升級指令碼:在您的整個來源樹 (包括測試) 上執行 tf_upgrade_v2。這會將您的程式碼升級為僅使用 TensorFlow 2.0 中可用的符號的格式。已淘汰的符號將會使用 tf.compat.v1 存取。這些最終需要手動處理,但不是立即需要。

  5. 使用 TensorFlow 1.15 執行轉換後的測試:您的程式碼在 TensorFlow 1.15 中仍應能正常執行。再次執行您的單元測試。此處測試中的任何錯誤都表示升級指令碼中存在錯誤。請告訴我們

  6. 檢查升級報告是否有警告和錯誤:指令碼會寫入報告檔案,說明您應複查的任何轉換,或您需要採取的任何手動動作。例如:任何剩餘的 contrib 執行個體都需要手動動作才能移除。請參閱 RFC 以取得更多指示

  7. 安裝 TensorFlow 2.x:此時,即使您使用舊版行為,切換至 TensorFlow 2.x 二進位檔也應該是安全的

  8. 使用 v1.disable_v2_behavior 進行測試:在測試的主要函式中使用 v1.disable_v2_behavior() 重新執行測試,應會得到與在 1.15 下執行相同的結果。

  9. 啟用 V2 行為:現在您的測試在使用 TF2 二進位檔的情況下可以運作了,您現在可以開始遷移您的程式碼,以避免使用 tf.estimators,並且僅使用支援的 TF2 行為 (不禁用 TF2 行為)。請參閱 遷移指南以取得詳細資訊。

使用符號重寫 tf_upgrade_v2 指令碼

設定

開始之前,請先確保已安裝 TensorFlow 2.x。

import tensorflow as tf

print(tf.__version__)

複製 tensorflow/models git 存放區,讓您有一些程式碼可以測試

git clone --branch r1.13.0 --depth 1 https://github.com/tensorflow/models

閱讀說明

指令碼應與 TensorFlow 一起安裝。以下是內建說明

tf_upgrade_v2 -h

範例 TF1 程式碼

以下是簡單的 TensorFlow 1.0 指令碼

head -n 65 models/samples/cookbook/regression/custom_regression.py | tail -n 10

安裝 TensorFlow 2.x 後,它無法執行

(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

如果指令碼找不到程式碼的修正,則會列印錯誤。

目錄樹狀結構

典型的專案 (包括這個簡單的範例) 會使用多個檔案。通常會想要更新整個套件,因此指令碼也可以在目錄樹狀結構上執行

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

請注意關於 dataset.make_one_shot_iterator 函式的警告。

現在指令碼可在 TensorFlow 2.x 中運作

請注意,由於 tf.compat.v1 模組包含在 TF 1.15 中,因此轉換後的指令碼也會在 TensorFlow 1.15 中執行。

(cd regression_v2 && python custom_regression.py 2>&1) | tail

詳細報告

指令碼也會報告詳細的變更清單。在這個範例中,它找到一個可能不安全的轉換,並在檔案頂端包含警告

head -n 20 tree_report.txt

再次注意關於 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)
!tf_upgrade_v2 \
  --infile dropout.py \
  --outfile dropout_v2.py \
  --reportfile dropout_report.txt > /dev/null
cat dropout_report.txt

以下是修改後的檔案內容,請注意指令碼如何新增引數名稱以處理已移動和重新命名的引數

cat dropout_v2.py

較大的專案可能包含一些錯誤。例如,轉換 deeplab 模型

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

它產生了輸出檔案

ls deeplab_v2

但有錯誤。報告將協助您找出在執行之前需要修正的項目。以下是前三個錯誤

cat deeplab_report.txt | grep -i models/research/deeplab | grep -i error | head -n 3

「安全」模式

轉換指令碼也具有侵入性較低的 SAFETY 模式,該模式只會變更匯入以使用 tensorflow.compat.v1 模組

cat dropout.py
tf_upgrade_v2 --mode SAFETY --infile dropout.py --outfile dropout_v2_safe.py > /dev/null
cat dropout_v2_safe.py

如您所見,這不會升級您的程式碼,但確實允許 TensorFlow 1 程式碼針對 TensorFlow 2 二進位檔執行。請注意,這並不表示您的程式碼正在執行支援的 TF 2.x 行為!

注意事項

  • 在執行此指令碼之前,請勿手動更新部分程式碼。特別是,具有重新排序引數的函式 (例如 tf.math.argmaxtf.batch_to_space) 會導致指令碼錯誤地新增關鍵字引數,進而錯誤對應您現有的程式碼。

  • 指令碼假設 tensorflow 是使用 import tensorflow as tfimport tensorflow.compat.v1 as tf 匯入的。

  • 此指令碼不會重新排序引數。而是指令碼會將關鍵字引數新增至引數已重新排序的函式。

  • 查看 tf2up.ml,以取得用於升級 GitHub 存放區中 Jupyter 筆記本和 Python 檔案的便利工具。

若要回報升級指令碼錯誤或提出功能要求,請在 GitHub 上提交問題。