ترجمت واجهة Cloud Translation API‏ هذه الصفحة.
Switch to English

ترقية الرمز تلقائيًا إلى TensorFlow 2

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تنزيل دفتر الملاحظات

يتضمن TensorFlow 2.0 العديد من تغييرات واجهة برمجة التطبيقات ، مثل إعادة ترتيب الوسيطات وإعادة تسمية الرموز وتغيير القيم الافتراضية للمعلمات. إن إجراء كل هذه التعديلات يدويًا سيكون مملاً وعرضة للخطأ. لتبسيط التغييرات ولجعل الانتقال إلى TF 2.0 سلسًا قدر الإمكان ، أنشأ فريق tf_upgrade_v2 الأداة المساعدة tf_upgrade_v2 للمساعدة في نقل التعليمات البرمجية القديمة إلى واجهة برمجة التطبيقات الجديدة.

الاستخدام النموذجي مثل هذا:

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 وحدة نمطية compat.v1 . تستبدل هذه الوحدة رموز TF 1.x مثل tf.foo مكافئ tf.compat.v1.foo . على الرغم من أن وحدة التوافق جيدة ، فإننا نوصيك بإجراء تدقيق لاستبدال البدائل يدويًا وترحيلها إلى واجهات برمجة التطبيقات الجديدة في مساحة الاسم tf.* بدلاً من مساحة الاسم tf.compat.v1 أسرع وقت ممكن.

بسبب عمليات إيقاف الوحدة النمطية TensorFlow 2.x (على سبيل المثال ، tf.flags و tf.contrib ) ، لا يمكن tf.contrib بعض التغييرات عن طريق التبديل إلى compat.v1 مع compat.v1 . قد تتطلب ترقية هذا الرمز استخدام مكتبة إضافية (على سبيل المثال ، absl.flags ) أو التبديل إلى حزمة في tensorflow / addons .

يوضح باقي هذا الدليل كيفية استخدام البرنامج النصي للترقية. على الرغم من سهولة استخدام البرنامج النصي للترقية ، إلا أننا نوصي بشدة باستخدام البرنامج النصي كجزء من العملية التالية:

  1. اختبار الوحدة : تأكد من أن الكود الذي تقوم بترقيته يحتوي على مجموعة اختبار الوحدة مع تغطية معقولة. هذا هو رمز Python ، لذلك لن تحميك اللغة من العديد من فئات الأخطاء. تأكد أيضًا من أن أي تبعية قد تمت ترقيتها بالفعل لتكون متوافقة مع TensorFlow 2.0.

  2. قم بتثبيت TensorFlow 1.14 : قم بترقية TensorFlow إلى أحدث إصدار من TensorFlow 1.x ، على الأقل 1.14. يتضمن هذا TensorFlow 2.0 API النهائي في tf.compat.v2 .

  3. الاختبار باستخدام 1.14 : تأكد من اجتياز اختبارات الوحدة عند هذه النقطة. ستقوم بتشغيلها بشكل متكرر أثناء الترقية ، لذا من المهم البدء من اللون الأخضر.

  4. قم بتشغيل البرنامج النصي للترقية : تشغيل tf_upgrade_v2 على شجرة المصدر بأكملها ، بما في ذلك الاختبارات. سيؤدي هذا إلى ترقية الرمز الخاص بك إلى تنسيق حيث يستخدم فقط الرموز المتاحة في TensorFlow 2.0. سيتم الوصول إلى الرموز tf.compat.v1 باستخدام tf.compat.v1 . سيتطلب ذلك في النهاية انتباهًا يدويًا ، ولكن ليس على الفور.

  5. شغّل الاختبارات المحولة باستخدام TensorFlow 1.14 : يجب أن يظل كودك يعمل بشكل جيد في TensorFlow 1.14. قم بإجراء اختبارات وحدتك مرة أخرى. أي خطأ في اختباراتك هنا يعني وجود خطأ في البرنامج النصي للترقية. يرجى إعلامنا .

  6. تحقق من تقرير الترقية عن التحذيرات والأخطاء : يكتب البرنامج النصي ملف تقرير يشرح أي تحويلات يجب عليك التحقق منها ، أو أي إجراء يدوي تحتاج إلى اتخاذه. على سبيل المثال: ستتطلب أي مثيلات متبقية من المساهمة إجراءً يدويًا للإزالة. يرجى استشارة RFC لمزيد من التعليمات .

  7. قم بتثبيت TensorFlow 2.0 : في هذه المرحلة ، من الآمن التبديل إلى TensorFlow 2.0

  8. الاختبار باستخدام v1.disable_v2_behavior : إعادة تشغيل الاختبارات باستخدام al v1.disable_v2_behavior() في الوظيفة الرئيسية للاختبارات يجب أن تعطي نفس النتائج مثل التشغيل تحت 1.14.

  9. تمكين سلوك V2 : الآن بعد أن عملت اختباراتك باستخدام v2 API ، يمكنك البدء في تفعيل سلوك v2. اعتمادًا على كيفية كتابة الرمز الخاص بك ، قد يتطلب هذا بعض التغييرات. راجع دليل الترحيل للحصول على التفاصيل.

باستخدام البرنامج النصي للترقية

اقامة

قبل البدء ، تأكد من تثبيت TensorlFlow 2.0.

 import tensorflow as tf

print(tf.__version__)
 
2.2.0

قم باستنساخ مستودع بوابة tensorflow / النماذج بحيث يكون لديك بعض التعليمات البرمجية لاختبارها:

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.

اقرأ المساعدة

يجب تثبيت البرنامج النصي مع 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] [--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

مثال على رمز 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.0 لا يعمل:

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


سيطبع البرنامج النصي أخطاء إذا لم يتمكن من العثور على إصلاح للرمز.

شجرة الدليل

ستستخدم المشاريع النموذجية ، بما في ذلك هذا المثال البسيط ، أكثر من ملف واحد. عادة ما ترغب في ترقية حزمة كاملة ، بحيث يمكن تشغيل البرنامج النصي أيضًا على شجرة دليل:

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


لاحظ التحذير الوحيد حول وظيفة dataset.make_one_shot_iterator .

يعمل البرنامج النصي الآن مع TensorFlow 2.0:

لاحظ أنه نظرًا لأن الوحدة النمطية tf.compat.v1 ، سيتم تشغيل البرنامج النصي المحول أيضًا في 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


تقرير مفصل

يقدم البرنامج النصي أيضًا قائمة بالتغييرات التفصيلية. في هذا المثال ، وجد تحولا غير آمن وربما تضمن تحذيرا في أعلى الملف:

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'

لاحظ مرة أخرى التحذير حول 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), 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/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.

"وضع الامان

يحتوي البرنامج النصي للتحويل أيضًا على وضع 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.argmax ترتيب الحجج مثل tf.argmax أو tf.batch_to_space النص البرمجي إلى إضافة وسيطات الكلمات الرئيسية التي تتعارض مع التعليمات البرمجية الحالية بشكل غير صحيح.

  • يفترض السيناريو الذي tensorflow يتم استيرادها باستخدام import tensorflow as tf .

  • هذا البرنامج النصي لا يعيد ترتيب الحجج. بدلاً من ذلك ، يضيف البرنامج النصي وسيطات الكلمات الرئيسية إلى الدوال التي تمت إعادة ترتيب وسيطاتها.

  • تحقق من tf2up.ml للحصول على أداة ملائمة لترقية دفاتر Jupyter وملفات Python في مستودع GitHub.

للإبلاغ عن أخطاء البرنامج النصي للترقية أو تقديم طلبات الميزات ، يرجى تقديم مشكلة على GitHub . وإذا كنت تختبر TensorFlow 2.0 ، فنحن نريد أن نسمع عنه! انضم إلى مجتمع اختبار TF 2.0 وأرسل الأسئلة والمناقشة إلى testing@tensorflow.org .