Secara otomatis mengupgrade kode ke TensorFlow 2

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan

TensorFlow 2.0 menyertakan banyak perubahan API, seperti menyusun ulang argumen, mengganti nama simbol, dan mengubah nilai default untuk parameter. Melakukan semua modifikasi ini secara manual akan membosankan dan rentan kesalahan. Untuk menyederhanakan perubahan, dan membuat transisi Anda ke TF 2.0 berjalan lancar, tim TensorFlow telah membuat utilitas tf_upgrade_v2 untuk membantu mentransisikan kode lama ke API baru.

Penggunaan tipikal seperti ini:

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

Ini akan mempercepat proses upgrade Anda dengan mengonversi skrip Python TensorFlow 1.x yang ada ke TensorFlow 2.0.

Skrip konversi mengotomatiskan sebanyak mungkin, tetapi masih ada perubahan sintaksis dan gaya yang tidak dapat dilakukan oleh skrip.

Modul kompatibilitas

Simbol API tertentu tidak dapat ditingkatkan hanya dengan menggunakan pengganti string. Untuk memastikan kode Anda masih didukung di TensorFlow 2.0, skrip upgrade menyertakan modul compat.v1 . Modul ini menggantikan simbol TF 1.x seperti tf.foo dengan referensi tf.compat.v1.foo setara. Meskipun modul kompatibilitasnya bagus, kami menyarankan Anda untuk mengoreksi penggantian secara manual dan memigrasikannya ke API baru di namespace tf.* Alih- tf.compat.v1 namespace tf.compat.v1 secepat mungkin.

Karena modul TensorFlow 2.x tidak digunakan lagi (misalnya, tf.flags dan tf.contrib ), beberapa perubahan tidak dapat diatasi dengan beralih ke compat.v1 . Meningkatkan kode ini mungkin memerlukan penggunaan pustaka tambahan (misalnya, absl.flags ) atau beralih ke paket di tensorflow / addons .

Bagian lain dari panduan ini menunjukkan cara menggunakan skrip peningkatan. Meskipun skrip pemutakhiran mudah digunakan, sangat disarankan agar Anda menggunakan skrip sebagai bagian dari proses berikut:

  1. Uji Unit : Pastikan kode yang Anda tingkatkan memiliki rangkaian pengujian unit dengan cakupan yang wajar. Ini adalah kode Python, jadi bahasanya tidak akan melindungi Anda dari banyak kelas kesalahan. Pastikan juga bahwa semua dependensi yang Anda telah diupgrade agar kompatibel dengan TensorFlow 2.0.

  2. Instal TensorFlow 1.14 : Upgrade TensorFlow Anda ke TensorFlow versi 1.x terbaru, setidaknya 1.14. Ini termasuk API TensorFlow 2.0 final di tf.compat.v2 .

  3. Uji Dengan 1.14 : Pastikan pengujian unit Anda lulus pada titik ini. Anda akan menjalankannya berulang kali saat Anda meningkatkan, jadi memulai dari hijau itu penting.

  4. Jalankan skrip peningkatan : Jalankan tf_upgrade_v2 di seluruh pohon sumber Anda, termasuk pengujian. Ini akan mengupgrade kode Anda ke format yang hanya menggunakan simbol yang tersedia di TensorFlow 2.0. Simbol yang tidak digunakan lagi akan diakses dengan tf.compat.v1 . Ini pada akhirnya akan membutuhkan perhatian manual, tetapi tidak segera.

  5. Jalankan pengujian yang dikonversi dengan TensorFlow 1.14 : Kode Anda harus tetap berfungsi dengan baik di TensorFlow 1.14. Jalankan pengujian unit Anda lagi. Setiap kesalahan dalam pengujian Anda di sini berarti ada bug dalam skrip peningkatan. Tolong beritahu kami .

  6. Periksa laporan peningkatan untuk peringatan dan kesalahan : Skrip menulis file laporan yang menjelaskan setiap konversi yang harus Anda periksa ulang, atau tindakan manual yang perlu Anda lakukan. Misalnya: Setiap kejadian kontrib yang tersisa akan membutuhkan tindakan manual untuk menghapusnya. Silakan berkonsultasi dengan RFC untuk instruksi lebih lanjut .

  7. Instal TensorFlow 2.0 : Pada tahap ini, Anda harus beralih ke TensorFlow 2.0 dengan aman

  8. Uji dengan v1.disable_v2_behavior : Menjalankan kembali pengujian Anda dengan al v1.disable_v2_behavior() di fungsi utama pengujian akan memberikan hasil yang sama seperti menjalankan di bawah 1.14.

  9. Aktifkan Perilaku V2 : Setelah pengujian Anda bekerja menggunakan API v2, Anda dapat mulai mencari cara untuk mengaktifkan perilaku v2. Bergantung pada bagaimana kode Anda ditulis, ini mungkin memerlukan beberapa perubahan. Lihat Panduan migrasi untuk detailnya.

Menggunakan skrip peningkatan

Mendirikan

Sebelum memulai, pastikan TensorlFlow 2.0 telah diinstal.

import tensorflow as tf

print(tf.__version__)
2.3.0

Gandakan repositori git tensorflow / model sehingga Anda memiliki beberapa kode untuk diuji:

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.

Baca bantuannya

Skrip harus diinstal dengan TensorFlow. Berikut adalah bantuan bawaan:

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

Contoh kode TF1

Berikut ini skrip TensorFlow 1.0 sederhana:

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)

Dengan menginstal TensorFlow 2.0, itu tidak berjalan:

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

Skrip pemutakhiran dapat dijalankan pada satu 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'

Skrip akan mencetak kesalahan jika tidak dapat menemukan perbaikan untuk kode tersebut.

Pohon direktori

Proyek tipikal, termasuk contoh sederhana ini, akan menggunakan lebih dari satu file. Biasanya ingin memutakhirkan seluruh paket, sehingga skrip juga dapat dijalankan pada pohon direktori:

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

Perhatikan satu peringatan tentang fungsi dataset.make_one_shot_iterator .

Sekarang skrip berfungsi dengan TensorFlow 2.0:

Perhatikan bahwa karena modul tf.compat.v1 , skrip yang dikonversi juga akan berjalan di 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.

Laporan rinci

Skrip juga melaporkan daftar perubahan mendetail. Dalam contoh ini, ia menemukan satu transformasi yang mungkin tidak aman dan menyertakan peringatan di bagian atas 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'

Perhatikan lagi satu peringatan tentang Dataset.make_one_shot_iterator function .

Dalam kasus lain, output akan menjelaskan alasan perubahan non-sepele:

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

Berikut adalah konten file yang dimodifikasi, perhatikan bagaimana skrip menambahkan nama argumen untuk menangani argumen yang dipindahkan dan diganti namanya:

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)

Proyek yang lebih besar mungkin mengandung beberapa kesalahan. Misalnya mengonversi model 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

Ini menghasilkan file keluaran:

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

Tapi ada kesalahan. Laporan tersebut akan membantu Anda menunjukkan dengan tepat apa yang perlu Anda perbaiki sebelum ini berjalan. Berikut tiga kesalahan pertama:

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.

Mode "Keamanan"

Skrip konversi juga memiliki mode SAFETY yang tidak terlalu invasif yang hanya mengubah impor untuk menggunakan modul 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)

Seperti yang Anda lihat, ini tidak mengupgrade kode Anda, tetapi memungkinkan kode TensorFlow 1 berjalan di TensorFlow 2

Peringatan

  • Jangan perbarui bagian kode Anda secara manual sebelum menjalankan skrip ini. Secara khusus, fungsi yang memiliki argumen tf.argmax ulang seperti tf.argmax atau tf.batch_to_space menyebabkan skrip salah menambahkan argumen kata kunci yang membuat kode Anda tidak sesuai.

  • Skrip mengasumsikan bahwa tensorflow diimpor menggunakan import tensorflow as tf .

  • Skrip ini tidak menyusun ulang argumen. Sebaliknya, skrip menambahkan argumen kata kunci ke fungsi yang argumennya diurutkan ulang.

  • Lihat tf2up.ml untuk alat yang nyaman untuk mengupgrade notebook Jupyter dan file Python di repositori GitHub.

Untuk melaporkan bug upgrade script atau membuat permintaan fitur, harap ajukan masalah di GitHub . Dan jika Anda menguji TensorFlow 2.0, kami ingin mendengarnya! Bergabunglah dengan komunitas Pengujian TF 2.0 dan kirim pertanyaan dan diskusi ke testing@tensorflow.org .