Di chuyển mức sử dụng tf.summary sang TF 2.x

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải xuống sổ ghi chép
import tensorflow as tf

TensorFlow 2.x bao gồm những thay đổi đáng kể cho tf.summary API được sử dụng để dữ liệu tóm tắt ghi để hiển thị trong TensorBoard.

Có gì thay đổi

Nó rất hữu ích để suy nghĩ của tf.summary API như hai tiểu API:

  • Một tập hợp các ops để ghi tóm tắt cá nhân - summary.scalar() , summary.histogram() , summary.image() , summary.audio() , và summary.text() - được gọi là inline từ mã mô hình của bạn.
  • Viết logic thu thập các bản tóm tắt riêng lẻ này và ghi chúng vào một tệp nhật ký được định dạng đặc biệt (sau đó TensorBoard sẽ đọc để tạo hình ảnh trực quan).

Trong TF 1.x

Hai nửa phải được tự nối với nhau - bằng cách lấy các kết quả đầu ra tóm tắt op qua Session.run() và gọi FileWriter.add_summary(output, step) . Các v1.summary.merge_all() op làm điều này bằng cách sử dụng một bộ sưu tập đồ thị để tổng hợp tất cả các kết quả đầu ra tóm tắt op dễ dàng hơn, nhưng phương pháp này vẫn còn làm việc kém để thực hiện háo hức và kiểm soát dòng chảy, làm cho nó đặc biệt là bệnh phù hợp cho TF 2.x.

Trong TF 2.X

Hai nửa được tích hợp chặt chẽ, và bây giờ cá nhân tf.summary ops ghi dữ liệu của họ ngay lập tức khi thực thi. Sử dụng API từ mã mô hình của bạn trông vẫn quen thuộc, nhưng giờ đây nó thân thiện với việc thực thi mong muốn trong khi vẫn tương thích với chế độ đồ thị. Lồng ghép cả hai nửa của phương tiện API summary.FileWriter hiện là một phần của bối cảnh thực hiện TensorFlow và được truy cập trực tiếp bởi tf.summary ops, vì vậy cấu hình nhà văn là phần chính mà vẻ bề ngoài khác nhau.

Ví dụ sử dụng với thực thi háo hức, mặc định trong 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

Cách sử dụng ví dụ với thực thi đồ thị hàm tf.

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

Ví dụ về cách sử dụng với thực thi đồ thị TF 1.x cũ:

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

Chuyển đổi mã của bạn

Chuyển đổi hiện tf.summary sử dụng API TF 2.x không thể chắc chắn tự động, do đó tf_upgrade_v2 kịch bản chỉ ghi đè nó tất cả để tf.compat.v1.summary . Để chuyển sang TF 2.x, bạn cần điều chỉnh mã của mình như sau:

  1. Một tập nhà văn mặc định qua .as_default() phải có mặt để ops tóm tắt sử dụng

    • Điều này có nghĩa là thực hiện các hoạt động một cách hăng hái hoặc sử dụng các hoạt động trong xây dựng biểu đồ
    • Không có người viết mặc định, các hoạt động tóm tắt trở thành các hoạt động không hoạt động im lặng
    • Nhà văn mặc định không (chưa) Tuyên truyền qua @tf.function thực hiện ranh giới - họ chỉ được phát hiện khi hàm được bắt nguồn từ - vì vậy tốt nhất là gọi writer.as_default() trong cơ thể chức năng, và để đảm bảo rằng các đối tượng nhà văn tiếp tục tồn tại chừng nào @tf.function đang được sử dụng
  2. Những "bước" giá trị phải được thông qua vào mỗi op qua các step lập luận

    • TensorBoard yêu cầu giá trị bước để hiển thị dữ liệu dưới dạng chuỗi thời gian
    • Chuyển rõ ràng là cần thiết vì bước tổng thể từ TF 1.x đã bị xóa, vì vậy mỗi op phải biết biến bước mong muốn để đọc
    • Để giảm soạn sẵn, hỗ trợ thử nghiệm cho đăng ký một giá trị bước mặc định có sẵn như là tf.summary.experimental.set_step() , nhưng đây là chức năng tạm thời có thể được thay đổi mà không cần báo
  3. Chữ ký chức năng của các hoạt động tóm tắt riêng lẻ đã thay đổi

    • Giá trị trả về bây giờ là một boolean (cho biết liệu bản tóm tắt có thực sự được viết hay không)
    • Tên tham số thứ hai (nếu đã qua sử dụng) đã thay đổi từ tensor để data
    • Các collections tham số đã được loại bỏ; bộ sưu tập chỉ là TF 1.x
    • Các family tham số đã được loại bỏ; chỉ sử dụng tf.name_scope()
  4. [Chỉ dành cho người dùng thực thi phiên / chế độ biểu đồ kế thừa]

    • Đầu tiên khởi người viết với v1.Session.run(writer.init())

    • Sử dụng v1.summary.all_v2_summary_ops() để có được tất cả các ops tóm tắt TF 2.x dành cho đồ thị hiện tại, ví dụ như để thực hiện chúng qua Session.run()

    • Tuôn nhà văn với v1.Session.run(writer.flush()) và tương tự như vậy cho close()

Nếu mã 1.x TF của bạn đã được thay vì sử dụng tf.contrib.summary API, nó là nhiều hơn nữa tương tự như API TF 2.x, vì vậy tf_upgrade_v2 kịch bản sẽ tự động hầu hết các bước di cư (và phát ra cảnh báo hoặc lỗi cho bất kỳ việc sử dụng đó không thể được di chuyển hoàn toàn). Đối với hầu hết các phần nó chỉ viết lại các cuộc gọi API để tf.compat.v2.summary ; nếu bạn chỉ cần tương thích với TF 2.x bạn có thể thả compat.v2 và chỉ cần tham khảo nó như tf.summary .

Lời khuyên bổ sung

Ngoài các khu vực quan trọng ở trên, một số khía cạnh phụ trợ cũng đã thay đổi:

  • Ghi có điều kiện (như "ghi mỗi 100 bước") có giao diện mới

    • Để ops kiểm soát và mã liên quan, quấn chúng trong một định kỳ câu lệnh if (trong đó hoạt động trong chế độ háo hức và trong @tf.function qua chữ ký ) hoặc một tf.cond
    • Để kiểm soát chỉ tóm tắt, sử dụng mới tf.summary.record_if() quản lý bối cảnh, và vượt qua nó với điều kiện boolean lựa chọn của bạn
    • Chúng thay thế mẫu TF 1.x:

      if condition:
        writer.add_summary()
      
  • Không viết trực tiếp của tf.compat.v1.Graph - thay vì chức năng sử dụng dấu vết

  • Không bộ nhớ đệm nhà văn toàn cầu nhiều hơn mỗi logdir với tf.summary.FileWriterCache

    • Người dùng một trong hai nên thực hiện bộ nhớ đệm của mình / chia sẻ của các đối tượng nhà văn, hoặc chỉ sử dụng nhà văn riêng biệt (hỗ trợ TensorBoard cho sau này là cơ bản dở dang )
  • Biểu diễn nhị phân tệp sự kiện đã thay đổi

    • TensorBoard 1.x đã hỗ trợ định dạng mới; sự khác biệt này chỉ ảnh hưởng đến những người dùng đang phân tích dữ liệu tóm tắt theo cách thủ công từ các tệp sự kiện
    • Dữ liệu tóm tắt hiện được lưu trữ dưới dạng tensor byte; bạn có thể sử dụng tf.make_ndarray(event.summary.value[0].tensor) để chuyển đổi nó để NumPy