Посмотреть на TensorFlow.org | Запустить в Google Colab | Посмотреть исходный код на GitHub | Скачать блокнот |
TensorFlow 2.x включает в себя множество изменений API по сравнению с TF 1.x и API tf.compat.v1
, таких как изменение порядка аргументов, переименование символов и изменение значений по умолчанию для параметров. Вручную выполнять все эти модификации было бы утомительно и подвержено ошибкам. Чтобы упростить изменения и сделать ваш переход на TF 2.x как можно более плавным, команда tf_upgrade_v2
утилиту 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 не могут быть автоматически перенесены. Он также не может полностью сделать ваш код совместимым с поведением и API TF2. Итак, это только часть вашего миграционного пути.
Модули совместимости
Некоторые символы API нельзя обновить, просто заменив строку. Те, которые не могут быть обновлены автоматически, будут сопоставлены с их расположением в модуле compat.v1
. Этот модуль заменяет символы TF 1.x, такие как tf.foo
, на эквивалентную ссылку tf.compat.v1.foo
. Если вы уже используете API-интерфейсы compat.v1
, импортировав TF через import tensorflow.compat.v1 as tf
, скрипт tf_upgrade_v2
попытается преобразовать эти использования в несовместимые API, где это возможно. Обратите внимание, что хотя некоторые API compat.v1
совместимы с поведением TF2.x, многие — нет. Поэтому мы рекомендуем вам вручную вычитывать замены и как можно быстрее переносить их на новые API в пространстве имен tf.*
вместо пространства имен tf.compat.v1
.
Из-за устаревания модуля TensorFlow 2.x (например, tf.flags
и tf.contrib
) некоторые изменения нельзя обойти, переключившись на compat.v1
. Для обновления этого кода может потребоваться использование дополнительной библиотеки (например, absl.flags
) или переход на пакет в tensorflow/addons .
Рекомендуемый процесс обновления
В оставшейся части этого руководства показано, как использовать скрипт перезаписи символов. Хотя сценарий прост в использовании, настоятельно рекомендуется использовать его как часть следующего процесса:
Модульный тест : убедитесь, что код, который вы обновляете, имеет набор модульных тестов с разумным покрытием. Это код Python, поэтому язык не защитит вас от многих классов ошибок. Также убедитесь, что все ваши зависимости уже обновлены для совместимости с TensorFlow 2.x.
Установите TensorFlow 1.15 : обновите TensorFlow до последней версии TensorFlow 1.x, не ниже 1.15. Сюда входит окончательный API TensorFlow 2.0 в
tf.compat.v2
.Test With 1.15 : Убедитесь, что ваши модульные тесты проходят на этом этапе. Вы будете запускать их неоднократно по мере обновления, поэтому важно начинать с зеленого.
Запустите сценарий обновления : запустите
tf_upgrade_v2
для всего исходного дерева, включая тесты. Это обновит ваш код до формата, в котором используются только символы, доступные в TensorFlow 2.0. Доступ к устаревшим символам будет осуществляться черезtf.compat.v1
. В конечном итоге они потребуют ручного вмешательства, но не сразу.Запустите преобразованные тесты с помощью TensorFlow 1.15 : ваш код по-прежнему должен нормально работать в TensorFlow 1.15. Запустите модульные тесты еще раз. Любая ошибка в ваших тестах означает, что в сценарии обновления есть ошибка. Пожалуйста, дайте нам знать .
Проверьте отчет об обновлении на наличие предупреждений и ошибок . Сценарий записывает файл отчета, в котором объясняются все преобразования, которые вы должны перепроверить, или любые действия, которые необходимо выполнить вручную. Например: все оставшиеся экземпляры contrib потребуют удаления вручную. Пожалуйста, обратитесь к RFC для получения дополнительных инструкций .
Установите TensorFlow 2.x : на этом этапе должно быть безопасно переключиться на двоичные файлы TensorFlow 2.x, даже если вы работаете с устаревшим поведением.
Тест с
v1.disable_v2_behavior
: повторный запуск ваших тестов сv1.disable_v2_behavior()
в основной функции тестов должен дать те же результаты, что и при работе в версии 1.15.Включить поведение V2 : теперь, когда ваши тесты работают с использованием двоичных файлов TF2, вы можете приступить к переносу своего кода, чтобы избежать
tf.estimator
и использовать только поддерживаемые поведения TF2 (без отключения поведения TF2). Подробнее см. в руководствах по миграции .
Использование скрипта tf_upgrade_v2
для перезаписи символов
Настраивать
Прежде чем начать, убедитесь, что TensorFlow 2.x установлен.
import tensorflow as tf
print(tf.__version__)
2.6.0
Клонируйте git-репозиторий tensorflow/models , чтобы у вас был код для тестирования:
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 504), reused 2113 (delta 424), pack-reused 0[K Receiving objects: 100% (2927/2927), 369.04 MiB | 27.58 MiB/s, done. Resolving deltas: 100% (504/504), 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] [--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.x он не запускается:
(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'
Сценарий будет печатать ошибки, если не сможет найти исправление кода.
Дерево каталогов
Типичные проекты, включая этот простой пример, будут использовать гораздо больше одного файла. Обычно требуется обновить весь пакет, поэтому скрипт также можно запустить в дереве каталогов:
# 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
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 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 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.x:
Обратите внимание: поскольку модуль tf.compat.v1
включен в TF 1.15, преобразованный скрипт также будет работать в TensorFlow 1.15.
(cd regression_v2 && python custom_regression.py 2>&1) | tail
I0922 22:16:42.778216 140254758430528 estimator.py:2074] Saving dict for global step 1000: global_step = 1000, loss = 651.5428, rmse = 3.684265 INFO:tensorflow:Saving 'checkpoint_path' summary for global step 1000: /tmp/tmpk2_4r192/model.ckpt-1000 I0922 22:16:42.817190 140254758430528 estimator.py:2135] Saving 'checkpoint_path' summary for global step 1000: /tmp/tmpk2_4r192/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: $3684
Детальный отчет
Скрипт также сообщает список подробных изменений. В этом примере он обнаружил одно, возможно, небезопасное преобразование и включил предупреждение в начало файла:
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/__init__.py' outputting to 'regression_v2/__init__.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), rate=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/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. 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
:
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 2.x!
Предостережения
Не обновляйте части своего кода вручную перед запуском этого скрипта. В частности, функции с измененным порядком аргументов, такие как
tf.argmax
илиtf.batch_to_space
заставляют сценарий неправильно добавлять аргументы ключевого слова, которые не соответствуют существующему коду.Сценарий предполагает, что
tensorflow
импортируется с помощьюimport tensorflow as tf
илиimport tensorflow.compat.v1 as tf
.Этот сценарий не переупорядочивает аргументы. Вместо этого сценарий добавляет аргументы ключевого слова к функциям, у которых переупорядочены аргументы.
Ознакомьтесь с tf2up.ml , чтобы найти удобный инструмент для обновления блокнотов Jupyter и файлов Python в репозитории GitHub.
Чтобы сообщить об ошибках сценария обновления или сделать запрос на добавление функций, отправьте сообщение о проблеме на GitHub .