[Перевод] Автоматическое обновление кода до TensorFlow 2

w1vywabsezrkx__ioop_tklrcic.png

В материале предоставлен перевод руководства по автоматическом обновлению кода с TensorFlow 1.x до Tensorflow 2 с помощью скрипта обновления tf_upgrade_v2.
TensorFlow 2.0 включает много изменений API, таких как изменение порядка аргументов, переименование символов и изменение значений по умолчанию для параметров. Ручное исправление всех этих модификаций утомительно и подвержено ошибкам. Чтобы упростить изменения и сделать ваш переход на TF 2.0 как можно более плавным, команда TensorFlow создала утилиту tf_upgrade_v2, помогающую перейти от legacy кода к новому API.

Примечание: 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 1.x, такие как tf.foo, на эквивалентную ссылку tf.compat.v1.foo. Хотя модуль совместимости хорош, мы рекомендуем вам вручную вычитать замены и перенести их на новые API в пространстве имен tf. * вместо пространства имен tf.compat.v1 как можно быстрее.

Из-за депрекации модулей TensorFlow 2.x (например, tf.flags и tf.contrib) некоторые изменения не могут быть обойдены путем переключения на compat.v1. Обновление такого кода может потребовать использования дополнительной библиотеки (например, absl.flags или переключения на пакет в tenorflow/addons.

Рекомендуемый процесс обновления


Эта часть руководства демонстрирует использование скрипта обновления. Хоть скрипт обновления прост в использовании, очень рекомендуем вам использовать скрипт в рамках следующего процесса:

  1. Юнит-тесты: убедитесь, что в обновляемом коде имеется набор юнит-тестов с разумным охватом. Это код Python, поэтому язык не защитит вас от многих классов ошибок. Также убедитесь, что все ваши зависимости были обновлены до совместимых с TensorFlow 2.0.
  2. Установите TensorFlow 1.14: Обновите ваш TensorFlow до последней версии TensorFlow 1.x, как минимум 1.14. Она включает финальный API TensorFlow 2.0 в tf.compat.v2.
  3. Протестируйте код с 1.14: Убедитесь, что ваши модульные тесты проходят на этом этапе. Вы будете повторно запускать их в процессе обновления поэтому важно начать с зеленого цвета.
  4. Запустите скрипт обновления: Запустите tf_upgrade_v2 на всем дереве исходного кода включая тесты. Это обновит ваш код до формата в котором он использует только символы доступные в TensorFlow 2.0. Устаревшие символы будут доступны с tf.compat.v1. Они впоследствии потребуют ручной обработки.\n»,
  5. Запустите конвертированные тесты с TensorFlow 1.14: Ваш код должен все еще запускаться правильно в TensorFlow 1.14. Запустите снова модульные тесты. Любая ошибка в ваших тестах на этом этапе значит, что в скрипте обновления есть ошибка.
  6. Проверьте отчет обновления на наличие предупреждений и ошибок: Скрипт пишет файл отчета объясняющий все конвертации которые вам нужно перепроверить, или все действия которые нужно совершить вручную. Например: Любые оставшиеся экземпляры contrib требуют ручного удаления.
  7. Установите TensorFlow 2.0: В этом месте переключение на TensorFlow 2.0 должно быть безопасно.
  8. Протестируйте код с v1.disable_v2_behavior: Перезапустите ваши тесты с v1.disable_v2_behavior() в основной функции тестов результаты должны быть те же, что и при запуске под 1.14.
  9. Включите V2 Behavior: Сейчас, когда ваши тесты работают с использованием API v2, вы можете начать смотреть включение v2 behavior. В зависимости от того, как написан ваш код, это может потребовать некоторых изменений.


Использование скрипта обновления


Установка

from __future__ import absolute_import, division, print_function, unicode_literals
try:
  import tensorflow.compat.v2 as tf
except Exception:
  pass

tf.enable_v2_behavior()

print(tf.__version__)


Склонируйте репозиторий tensorflow/models чтобы у вас был какой-нибудь код для экспериментов:

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


Прочитайте help


Скрипт должен быть установлен с TensorFlow. Встроенная помощь вызывается так:

!tf_upgrade_v2 -h


Пример кода TF1


Вот простой скрипт TensorFlow 1.0 который не запускается на TensorFlow 2.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)


выдавая следующую ошибку:

Traceback (most recent call last):
  File "custom_regression.py", line 162, in 
    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'


Дерево каталогов


Типичные проекты, включая этот простой пример, используют более одного файла. Обычно хочется обновить весь пакет, поэтому скрипт может быть также запущен на дереве каталогов:

# обновить файлы .py и скопировать остальные файлы в outtree
!tf_upgrade_v2 \
    --intree models/samples/cookbook/regression/ \
    --outtree regression_v2/ \
    --reportfile tree_report.txt


Обратите внимание на одно замечание по поводу функции

dataset.make_one_shot_iterator

.

Сейчас скрипт уже работает с TensorFlow 2.0.

Обратите внимание, что из-за модуля `tf.compat.v1`, сконвертированный скрипт также будет запускаться в TensorFlow 1.14.

Детальный отчет


Скрипт также публикует подробный список изменений. В этом примере он нашел одну возможно небезопасную трансформацию и добавил предупреждение в начало файла:

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


Обратите внимание вновь на одно замечание о Dataset.make_one_shot_iterator function.

«Безопасный» режим


У скрипт конвертации есть также менее инвазивный «БЕЗОПАСНЫЙ» режим который просто меняет импорты для использования модуля tensorflow.compat.v1.

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


Например код:

import tensorflow as tf

d = tf.nn.dropout(tf.range(10), 0.2)
z = tf.zeros_like(d, optimize=False)

в таком режиме преобразуется в следующий:

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

d = tf.nn.dropout(tf.range(10), 0.2)
z = tf.zeros_like(d, optimize=False)


Как вы можете видеть ваш код не обновился, но теперь код TensorFlow 1 запускается в TensorFlow 2.

Предостережения


  • Не обновляйте части вашего кода вручную перед запуском скрипта. В частности, функции с переупорядоченными аргументами, такие как tf.argmax или tf.batch_to_space, вынудят скрипт неправильно добавить аргументы ключевых слов, что запутает ваш существующий код.
  • Скрипт предполагает, что tensorflow импортирован с использованием import tensorflow as tf
  • Скрипт не переупорядочивает аргументы. Вместо этого скрипт добавляет ключевые слова аргументов к функциям у которых аргументы поменяли порядок.


После проверки перевод появится также на сайте Tensorflow.org. Если вы хотите поучаствовать в переводе документации сайта Tensorflow.org на русский, обращайтесь в личку или комментарии. Любые исправления и замечания приветствуются.

© Habrahabr.ru