Questa pagina è stata tradotta dall'API Cloud Translation.
Switch to English

Aggiorna automaticamente il codice a TensorFlow 2

Visualizza su TensorFlow.org Esegui in Google Colab Visualizza sorgente su GitHub Scarica notebook

TensorFlow 2.0 include molte modifiche API, come il riordino degli argomenti, la ridenominazione dei simboli e la modifica dei valori predefiniti per i parametri. Eseguire manualmente tutte queste modifiche sarebbe noioso e soggetto a errori. Per semplificare le modifiche e per rendere la transizione a TF 2.0 il più semplice possibile, il team di TensorFlow ha creato l'utilità tf_upgrade_v2 per facilitare la transizione del codice legacy alla nuova API.

L'utilizzo tipico è così:

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

Accelererà il processo di aggiornamento convertendo gli script Python TensorFlow 1.x esistenti in TensorFlow 2.0.

Lo script di conversione si automatizza il più possibile, ma ci sono ancora modifiche sintattiche e stilistiche che non possono essere eseguite dallo script.

Moduli di compatibilità

Alcuni simboli API non possono essere aggiornati semplicemente utilizzando una sostituzione di stringa. Per garantire che il codice sia ancora supportato in TensorFlow 2.0, lo script di aggiornamento include un modulo compat.v1 . Questo modulo sostituisce i simboli TF 1.x come tf.foo con l'equivalente riferimento tf.compat.v1.foo . Sebbene il modulo di compatibilità sia carino, ti consigliamo di rileggere manualmente le sostituzioni e di tf.compat.v1 a nuove API nello spazio dei nomi tf.* Invece che tf.compat.v1 spazio dei nomi tf.compat.v1 più rapidamente possibile.

A causa delle deprecazioni del modulo TensorFlow 2.x (ad esempio, tf.flags e tf.contrib ), alcune modifiche non possono essere compat.v1 passando a compat.v1 . L'aggiornamento di questo codice potrebbe richiedere l'utilizzo di una libreria aggiuntiva (ad esempio, absl.flags ) o il passaggio a un pacchetto in tensorflow / addons .

Il resto di questa guida mostra come utilizzare lo script di aggiornamento. Sebbene lo script di aggiornamento sia facile da usare, si consiglia vivamente di utilizzare lo script come parte del seguente processo:

  1. Unit test : assicurati che il codice che stai aggiornando abbia una suite di unit test con una copertura ragionevole. Questo è codice Python, quindi il linguaggio non ti proteggerà da molte classi di errori. Assicurati inoltre che tutte le dipendenze di cui disponi siano già state aggiornate per essere compatibili con TensorFlow 2.0.

  2. Installa TensorFlow 1.14 : aggiorna il tuo TensorFlow all'ultima versione di TensorFlow 1.x, almeno 1.14. Ciò include l'API TensorFlow 2.0 finale in tf.compat.v2 .

  3. Test con 1.14 : assicurati che i tuoi unit test siano passati a questo punto. Li eseguirai ripetutamente durante l'aggiornamento, quindi iniziare dal verde è importante.

  4. Esegui lo script di aggiornamento : esegui tf_upgrade_v2 sull'intero albero dei sorgenti, test inclusi. In questo modo il codice verrà aggiornato a un formato in cui utilizza solo i simboli disponibili in TensorFlow 2.0. Si accederà ai simboli tf.compat.v1 con tf.compat.v1 . Questi alla fine richiederanno attenzione manuale, ma non immediatamente.

  5. Esegui i test convertiti con TensorFlow 1.14 : il tuo codice dovrebbe comunque funzionare correttamente in TensorFlow 1.14. Esegui di nuovo i tuoi unit test. Qualsiasi errore nei tuoi test qui significa che c'è un bug nello script di aggiornamento. Fatecelo sapere .

  6. Controlla il rapporto di aggiornamento per avvisi ed errori : lo script scrive un file di rapporto che spiega le conversioni che dovresti ricontrollare o qualsiasi azione manuale che devi eseguire. Ad esempio: qualsiasi istanza rimanente di contrib richiederà un'azione manuale per la rimozione. Si prega di consultare la RFC per ulteriori istruzioni .

  7. Installa TensorFlow 2.0 : a questo punto dovrebbe essere sicuro passare a TensorFlow 2.0

  8. Test con v1.disable_v2_behavior : rieseguire i test con al v1.disable_v2_behavior() nella funzione principale dei test dovrebbe dare gli stessi risultati di quelli eseguiti sotto 1.14.

  9. Abilita comportamento V2 : ora che i tuoi test funzionano utilizzando l'API v2, puoi iniziare a cercare di attivare il comportamento v2. A seconda di come è scritto il codice, potrebbero essere necessarie alcune modifiche. Vedere la Guida alla migrazione per i dettagli.

Utilizzando lo script di aggiornamento

Impostare

Prima di iniziare, assicurati che TensorlFlow 2.0 sia installato.

import tensorflow as tf

print(tf.__version__)
2.3.0

Clona il repository git tensorflow / models in modo da avere del codice su cui testare:

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 | 44.65 MiB/s, done.
Resolving deltas: 100% (509/509), done.
Checking out files: 100% (2768/2768), done.

Leggi la guida

Lo script dovrebbe essere installato con TensorFlow. Ecco la guida incorporata:

tf_upgrade_v2 -h
2020-09-10 01:42:59.274658: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
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

Codice TF1 di esempio

Ecco un semplice script 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)

Con TensorFlow 2.0 installato, non viene eseguito:

(cd models/samples/cookbook/regression && python custom_regression.py)
2020-09-10 01:43:01.613673: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
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'

File singolo

Lo script di aggiornamento può essere eseguito su un singolo file Python:

!tf_upgrade_v2 \
  --infile models/samples/cookbook/regression/custom_regression.py \
  --outfile /tmp/custom_regression_v2.py
2020-09-10 01:43:03.844314: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
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'


Lo script stamperà gli errori se non riesce a trovare una correzione per il codice.

Albero delle directory

I progetti tipici, incluso questo semplice esempio, utilizzeranno molto più di un file. In genere si desidera aggiornare un intero pacchetto, quindi lo script può essere eseguito anche su un albero di directory:

# 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
2020-09-10 01:43:06.108169: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
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 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'
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 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 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'


Nota l'unico avvertimento sulla funzione dataset.make_one_shot_iterator .

Ora lo script funziona con TensorFlow 2.0:

Tieni presente che, poiché il modulo tf.compat.v1 , lo script convertito verrà eseguito anche in TensorFlow 1.14.

(cd regression_v2 && python custom_regression.py 2>&1) | tail
    data = raw_dataframe()
  File "/tmpfs/src/temp/site/en/guide/regression_v2/automobile_data.py", line 67, in raw_dataframe
    dtype=COLUMN_TYPES, na_values="?")
  File "/home/kbuilder/.local/lib/python3.6/site-packages/pandas/io/parsers.py", line 686, in read_csv
    return _read(filepath_or_buffer, kwds)
  File "/home/kbuilder/.local/lib/python3.6/site-packages/pandas/io/parsers.py", line 449, in _read
    _validate_names(kwds.get("names", None))
  File "/home/kbuilder/.local/lib/python3.6/site-packages/pandas/io/parsers.py", line 417, in _validate_names
    raise ValueError("Names should be an ordered collection.")
ValueError: Names should be an ordered collection.

Rapporto dettagliato

Lo script riporta anche un elenco di modifiche dettagliate. In questo esempio ha trovato una trasformazione forse non sicura e ha incluso un avviso nella parte superiore del file:

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

Notare di nuovo l'unico avvertimento sulla Dataset.make_one_shot_iterator function .

In altri casi l'output spiegherà il ragionamento per modifiche non banali:

%%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
2020-09-10 01:43:10.977249: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1

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


Ecco il contenuto del file modificato, nota come lo script aggiunge i nomi degli argomenti per gestire gli argomenti spostati e rinominati:

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)

Un progetto più ampio potrebbe contenere alcuni errori. Ad esempio, converti il ​​modello deeplab:

!tf_upgrade_v2 \
    --intree models/research/deeplab \
    --outtree deeplab_v2 \
    --reportfile deeplab_report.txt > /dev/null
2020-09-10 01:43:13.488610: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1

Ha prodotto i file di output:

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

Ma c'erano degli errori. Il rapporto ti aiuterà a individuare ciò che devi correggere prima che venga eseguito. Ecco i primi tre errori:

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

Modalità "sicurezza"

Lo script di conversione ha anche una modalità SAFETY meno invasiva che modifica semplicemente le importazioni per utilizzare il modulo 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
2020-09-10 01:43:17.892207: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1

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)

Come puoi vedere, questo non aggiorna il tuo codice, ma consente l'esecuzione del codice TensorFlow 1 in TensorFlow 2

Avvertenze

  • Non aggiornare manualmente parti del codice prima di eseguire questo script. In particolare, le funzioni che hanno avuto argomenti riordinati come tf.argmax o tf.batch_to_space sì che lo script aggiunga in modo errato argomenti di parole chiave che mappano male il codice esistente.

  • Lo script presume che tensorflow venga importato utilizzando import tensorflow as tf .

  • Questo script non riordina gli argomenti. Invece, lo script aggiunge argomenti di parole chiave alle funzioni i cui argomenti sono stati riordinati.

  • Dai un'occhiata a tf2up.ml per uno strumento conveniente per aggiornare i notebook Jupyter e i file Python in un repository GitHub.

Per segnalare bug di script di aggiornamento o effettuare richieste di funzionalità, invia un problema su GitHub . E se stai testando TensorFlow 2.0, vogliamo saperne di più! Unisciti alla comunità di test TF 2.0 e invia domande e discussioni a testing@tensorflow.org .