Migrasi penggunaan tf.summary ke TF 2.x

Lihat di TensorFlow.org Jalankan di Google Colab Lihat sumber di GitHub Unduh buku catatan
import tensorflow as tf

TensorFlow 2.x termasuk perubahan yang signifikan terhadap tf.summary API digunakan untuk data ringkasan menulis untuk visualisasi di TensorBoard.

Apa yang berubah?

Ini berguna untuk memikirkan tf.summary API sebagai dua sub-API:

Dalam TF 1.x

Kedua bagian harus secara manual kabel bersama-sama - dengan mengambil ringkasan op output melalui Session.run() dan memanggil FileWriter.add_summary(output, step) . The v1.summary.merge_all() op membuat ini lebih mudah dengan menggunakan koleksi grafik untuk mengumpulkan semua Ringkasan op output, namun pendekatan ini masih bekerja buruk untuk eksekusi bersemangat dan aliran kontrol, sehingga sangat tidak cocok untuk TF 2.x.

Dalam TF 2.X

Dua bagian yang terintegrasi, dan sekarang individu tf.summary ops menulis data mereka dengan segera ketika dijalankan. Menggunakan API dari kode model Anda seharusnya masih terlihat familier, tetapi sekarang ramah untuk eksekusi yang bersemangat sambil tetap kompatibel dengan mode grafik. Mengintegrasikan kedua bagian dari sarana API summary.FileWriter sekarang merupakan bagian dari konteks eksekusi TensorFlow dan akan diakses secara langsung oleh tf.summary ops, sehingga mengkonfigurasi penulis adalah bagian utama yang terlihat berbeda.

Contoh penggunaan dengan eksekusi bersemangat, default di TF 2.x:

writer = tf.summary.create_file_writer("/tmp/mylogs/eager")

with writer.as_default():
  for step in range(100):
    # other model code would go here
    tf.summary.scalar("my_metric", 0.5, step=step)
    writer.flush()
ls /tmp/mylogs/eager
events.out.tfevents.1633086727.kokoro-gcp-ubuntu-prod-1386032077.31590.0.v2

Contoh penggunaan dengan eksekusi grafik tf.function:

writer = tf.summary.create_file_writer("/tmp/mylogs/tf_function")

@tf.function
def my_func(step):
  with writer.as_default():
    # other model code would go here
    tf.summary.scalar("my_metric", 0.5, step=step)

for step in tf.range(100, dtype=tf.int64):
  my_func(step)
  writer.flush()
ls /tmp/mylogs/tf_function
events.out.tfevents.1633086728.kokoro-gcp-ubuntu-prod-1386032077.31590.1.v2

Contoh penggunaan dengan eksekusi grafik TF 1.x lawas:

g = tf.compat.v1.Graph()
with g.as_default():
  step = tf.Variable(0, dtype=tf.int64)
  step_update = step.assign_add(1)
  writer = tf.summary.create_file_writer("/tmp/mylogs/session")
  with writer.as_default():
    tf.summary.scalar("my_metric", 0.5, step=step)
  all_summary_ops = tf.compat.v1.summary.all_v2_summary_ops()
  writer_flush = writer.flush()


with tf.compat.v1.Session(graph=g) as sess:
  sess.run([writer.init(), step.initializer])

  for i in range(100):
    sess.run(all_summary_ops)
    sess.run(step_update)
    sess.run(writer_flush)
ls /tmp/mylogs/session
events.out.tfevents.1633086728.kokoro-gcp-ubuntu-prod-1386032077.31590.2.v2

Mengonversi kode Anda

Konversi yang ada tf.summary penggunaan ke TF 2.x API tidak dapat dipercaya otomatis, sehingga tf_upgrade_v2 naskah hanya menuliskannya kembali semua untuk tf.compat.v1.summary . Untuk bermigrasi ke TF 2.x, Anda harus menyesuaikan kode Anda sebagai berikut:

  1. Seorang penulis set default via .as_default() harus hadir untuk digunakan ops Ringkasan

    • Ini berarti menjalankan ops dengan penuh semangat atau menggunakan ops dalam konstruksi grafik
    • Tanpa penulis default, operasi ringkasan menjadi tanpa operasi senyap
    • Penulis bawaan tidak (belum) propagate melintasi @tf.function batas eksekusi - mereka hanya terdeteksi ketika fungsi ini ditelusuri - sehingga praktek terbaik adalah untuk memanggil writer.as_default() dalam fungsi tubuh, dan untuk memastikan bahwa penulis objek terus ada selama @tf.function sedang digunakan
  2. "Langkah" nilai harus dilalui dalam setiap op melalui para step argumen

    • TensorBoard memerlukan nilai langkah untuk merender data sebagai deret waktu
    • Passing eksplisit diperlukan karena langkah global dari TF 1.x telah dihapus, sehingga setiap op harus mengetahui variabel langkah yang diinginkan untuk dibaca
    • Untuk mengurangi boilerplate, dukungan eksperimental untuk mendaftarkan nilai langkah standar tersedia sebagai tf.summary.experimental.set_step() , tapi ini adalah fungsi sementara yang dapat berubah tanpa pemberitahuan
  3. Tanda tangan fungsi dari operasi ringkasan individu telah berubah

    • Nilai pengembalian sekarang menjadi boolean (menunjukkan jika ringkasan benar-benar ditulis)
    • Nama parameter kedua (jika digunakan) telah berubah dari tensor untuk data
    • The collections parameter telah dihapus; koleksi hanya TF 1.x
    • The family parameter telah dihapus; hanya menggunakan tf.name_scope()
  4. [Hanya untuk mode grafik lama/pengguna eksekusi sesi]

    • Pertama menginisialisasi penulis dengan v1.Session.run(writer.init())

    • Gunakan v1.summary.all_v2_summary_ops() untuk mendapatkan semua ops Ringkasan TF 2.x untuk grafik saat ini, misalnya untuk mengeksekusi mereka melalui Session.run()

    • Siram penulis dengan v1.Session.run(writer.flush()) dan juga untuk close()

Jika kode 1.x TF Anda malah menggunakan tf.contrib.summary API, itu jauh lebih mirip dengan TF 2.x API, sehingga tf_upgrade_v2 naskah akan mengotomatisasi sebagian besar langkah-langkah migrasi (dan memancarkan peringatan atau kesalahan untuk penggunaan setiap yang tidak bisa bermigrasi sepenuhnya). Untuk sebagian besar itu hanya menulis ulang panggilan API untuk tf.compat.v2.summary ; jika Anda hanya perlu kompatibilitas dengan TF 2.x Anda bisa drop compat.v2 dan hanya referensi sebagai tf.summary .

Tips tambahan

Selain area kritis di atas, beberapa aspek bantu juga mengalami perubahan:

  • Rekaman bersyarat (seperti "log setiap 100 langkah") memiliki tampilan baru

    • Untuk ops kontrol dan kode terkait, membungkus mereka dalam biasa jika pernyataan (yang bekerja dalam modus bersemangat dan di @tf.function melalui tanda tangan ) atau tf.cond
    • Untuk mengontrol hanya ringkasan, menggunakan baru tf.summary.record_if() manajer konteks, dan menyebarkannya kondisi boolean yang Anda pilih
    • Ini menggantikan pola TF 1.x:

      if condition:
        writer.add_summary()
      
  • Ada tulisan langsung tf.compat.v1.Graph - bukan fungsi penggunaan jejak

  • Tidak ada penulis yang lebih global caching per LogDir dengan tf.summary.FileWriterCache

    • Pengguna harus baik menerapkan caching mereka sendiri / berbagi penulis benda, atau hanya menggunakan penulis yang terpisah (dukungan TensorBoard untuk yang terakhir ini berlangsung )
  • Representasi biner file acara telah berubah

    • TensorBoard 1.x sudah mendukung format baru; perbedaan ini hanya memengaruhi pengguna yang secara manual menguraikan data ringkasan dari file acara
    • Data ringkasan sekarang disimpan sebagai byte tensor; Anda dapat menggunakan tf.make_ndarray(event.summary.value[0].tensor) untuk mengubahnya menjadi numpy