Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Automatycznie uaktualnij kod do TensorFlow 2

Zobacz na TensorFlow.org Uruchom w Google Colab Wyświetl źródło na GitHub Pobierz notatnik

TensorFlow 2.0 zawiera wiele zmian API, takich jak zmiana kolejności argumentów, zmiana nazw symboli i zmiana domyślnych wartości parametrów. Ręczne wykonywanie wszystkich tych modyfikacji byłoby żmudne i podatne na błędy. Aby usprawnić zmiany i uczynić przejście na TF 2.0 tak płynnym, jak to tylko możliwe, zespół TensorFlow stworzył narzędzie tf_upgrade_v2 , aby pomóc w przeniesieniu starszego kodu do nowego interfejsu API.

Typowe użycie jest takie:

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

Przyspieszy proces aktualizacji poprzez konwersję istniejących skryptów TensorFlow 1.x Python do TensorFlow 2.0.

Skrypt konwersji automatyzuje w największym możliwym stopniu, ale nadal istnieją zmiany składniowe i stylistyczne, których nie może wykonać skrypt.

Moduły zgodności

Niektórych symboli API nie można zaktualizować po prostu za pomocą zamiany ciągu. Aby upewnić się, że Twój kod jest nadal obsługiwany w TensorFlow 2.0, skrypt aktualizacji zawiera moduł compat.v1 . Ten moduł zastępuje symbole TF 1.x, takie jak tf.foo odpowiednikiem odniesienia tf.compat.v1.foo . Chociaż moduł kompatybilności jest fajny, zalecamy, abyś ręcznie sprawdzał zamienniki i migrował je do nowych API w przestrzeni nazw tf.* Zamiast przestrzeni nazw tf.compat.v1 tak szybko, jak to możliwe.

Z powodu przestarzałych modułów TensorFlow 2.x (na przykład tf.flags i tf.contrib ), niektórych zmian nie można obejść, przełączając się na compat.v1 . Aktualizacja tego kodu może wymagać użycia dodatkowej biblioteki (na przykład absl.flags ) lub przełączenia się na pakiet w tensorflow / addons .

W pozostałej części tego przewodnika pokazano, jak używać skryptu aktualizacji. Chociaż skrypt aktualizacji jest łatwy w użyciu, zdecydowanie zaleca się używanie go w ramach następującego procesu:

  1. Test jednostkowy : upewnij się, że uaktualniany kod ma zestaw testów jednostkowych z rozsądnym pokryciem. To jest kod Pythona, więc język nie ochroni Cię przed wieloma klasami błędów. Upewnij się również, że wszelkie zależności, które zostały już zaktualizowane, są zgodne z TensorFlow 2.0.

  2. Zainstaluj TensorFlow 1.14 : Zaktualizuj TensorFlow do najnowszej wersji TensorFlow 1.x, co najmniej 1.14. Obejmuje to ostateczny interfejs API TensorFlow 2.0 w tf.compat.v2 .

  3. Testuj z wersją 1.14 : Upewnij się, że testy jednostkowe kończą się w tym momencie. Będziesz je uruchamiać wielokrotnie podczas aktualizacji, więc ważne jest, aby zacząć od zielonego.

  4. Uruchom skrypt aktualizacji : Uruchom tf_upgrade_v2 na całym drzewie źródłowym, łącznie z testami. Spowoduje to uaktualnienie kodu do formatu, w którym używa tylko symboli dostępnych w TensorFlow 2.0. Przestarzałe symbole będą dostępne za pomocą tf.compat.v1 . Będą one ostatecznie wymagały ręcznej uwagi, ale nie natychmiast.

  5. Uruchom przekonwertowane testy za pomocą TensorFlow 1.14 : Twój kod powinien nadal działać poprawnie w TensorFlow 1.14. Uruchom ponownie testy jednostkowe. Każdy błąd w twoich testach oznacza błąd w skrypcie aktualizacji. Daj nam znać .

  6. Sprawdź raport aktualizacji pod kątem ostrzeżeń i błędów : skrypt zapisuje plik raportu, który wyjaśnia wszelkie konwersje, które należy dokładnie sprawdzić, lub wszelkie ręczne działania, które należy podjąć. Na przykład: usunięcie wszelkich pozostałych wystąpień Contrib będzie wymagać ręcznego działania. Więcej instrukcji można znaleźć w dokumencie RFC .

  7. Zainstaluj TensorFlow 2.0 : W tym momencie przejście na TensorFlow 2.0 powinno być bezpieczne

  8. Testuj z v1.disable_v2_behavior : Ponowne uruchomienie testów z al v1.disable_v2_behavior() w głównej funkcji testów powinno dać takie same wyniki, jak uruchomienie pod 1.14.

  9. Włącz zachowanie w wersji 2 : Teraz, gdy testy działają przy użyciu interfejsu API w wersji 2, możesz zacząć rozważać włączenie zachowania w wersji 2. W zależności od tego, jak jest napisany kod, może to wymagać pewnych zmian. Szczegółowe informacje można znaleźć w przewodniku po migracji .

Korzystanie ze skryptu aktualizacji

Ustawiać

Przed rozpoczęciem upewnij się, że jest zainstalowany TensorlFlow 2.0.

 import tensorflow as tf

print(tf.__version__)
 
2.2.0

Sklonuj repozytorium git tensorflow / models, aby mieć trochę kodu do przetestowania:

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.

Przeczytaj pomoc

Skrypt należy zainstalować razem z TensorFlow. Oto wbudowana pomoc:

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

Przykładowy kod TF1

Oto prosty skrypt 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)

Po zainstalowaniu TensorFlow 2.0 nie działa:

(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'

Pojedynczy plik

Skrypt aktualizacji można uruchomić na jednym pliku w języku 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'


Skrypt wypisze błędy, jeśli nie może znaleźć poprawki dla kodu.

Drzewo katalogów

Typowe projekty, w tym ten prosty przykład, będą używać znacznie więcej niż jednego pliku. Zwykle chcesz zaktualizować cały pakiet, więc skrypt można również uruchomić w drzewie katalogów:

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


Zwróć uwagę na jedno ostrzeżenie dotyczące funkcji dataset.make_one_shot_iterator .

Teraz skrypt współpracuje z TensorFlow 2.0:

Zauważ, że ponieważ moduł tf.compat.v1 , przekonwertowany skrypt będzie działał również w 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


Szczegółowy raport

Skrypt zgłasza również listę szczegółowych zmian. W tym przykładzie znalazł jedną potencjalnie niebezpieczną transformację i umieścił ostrzeżenie w górnej części pliku:

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'

Zwróć uwagę ponownie na jedno ostrzeżenie dotyczące Dataset.make_one_shot_iterator function .

W innych przypadkach wynik wyjaśni uzasadnienie nietrywialnych zmian:

 %%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.
--------------------------------------------------------------------------------


Oto zmodyfikowana zawartość pliku, zwróć uwagę, jak skrypt dodaje nazwy argumentów, aby poradzić sobie z przeniesionymi i zmienionymi nazwami argumentów:

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)

Większy projekt może zawierać kilka błędów. Na przykład przekonwertuj model deeplab:

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

Stworzyło pliki wyjściowe:

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

Ale były błędy. Raport pomoże Ci określić, co musisz naprawić, zanim to się uruchomi. Oto pierwsze trzy błędy:

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.

Tryb „bezpieczny”

Skrypt konwersji ma również mniej inwazyjny tryb SAFETY , który po prostu zmienia import tak, aby używał modułu 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)

Jak widać, nie powoduje to aktualizacji kodu, ale umożliwia uruchamianie kodu TensorFlow 1 w TensorFlow 2

Ostrzeżenia

  • Nie aktualizuj ręcznie części kodu przed uruchomieniem tego skryptu. W szczególności funkcje, które tf.argmax kolejność argumentów, takie jak tf.argmax lub tf.batch_to_space powodują, że skrypt niepoprawnie dodaje argumenty słów kluczowych, które nie pasują do istniejącego kodu.

  • Skrypt zakłada, że tensorflow jest importowany przy użyciu funkcji import tensorflow as tf .

  • Ten skrypt nie zmienia kolejności argumentów. Zamiast tego skrypt dodaje argumenty słów kluczowych do funkcji, które mają zmienioną kolejność argumentów.

  • Sprawdź tf2up.ml, aby uzyskać wygodne narzędzie do aktualizacji notebooków Jupyter i plików Python w repozytorium GitHub.

Aby zgłosić błędy w skrypcie aktualizacji lub zgłosić żądanie funkcji, zgłoś problem na GitHub . A jeśli testujesz TensorFlow 2.0, chcemy o tym usłyszeć! Dołącz do społeczności testerów TF 2.0 i wyślij pytania i dyskusję na adres testing@tensorflow.org .