Посмотреть на TensorFlow.org | Запускаем в Google Colab | Посмотреть исходный код на GitHub | Скачать блокнот |
import tensorflow as tf
TensorFlow 2.x включает в себя значительные изменения в tf.summary
API , используемый для записи данных кратких для визуализации в TensorBoard.
Что изменилось
Это полезно думать о tf.summary
API как два суб-API:
- Набор опс для записи отдельных резюме -
summary.scalar()
,summary.histogram()
,summary.image()
,summary.audio()
, иsummary.text()
- которые называются рядным из вашего кода модели. - Написание логики, которая собирает эти отдельные сводки и записывает их в специально отформатированный файл журнала (который затем TensorBoard считывает для создания визуализаций).
В TF 1.x
Две половинки должны были быть вручную соединены вместе - путем выборки сводной оп выходами через Session.run()
и вызов FileWriter.add_summary(output, step)
. v1.summary.merge_all()
оп сделало это проще с помощью коллекции графа агрегировать все опы Резюме результатов, но этот подход все еще работает плохо для нетерпеливого исполнения и потока управления, что делает его особенно плохо подходит для 2.x. TF
В TF 2.X
Обе половины тесно интегрированы, и теперь отдельные tf.summary
ОПС писать свои данные сразу при выполнении. Использование API из кода вашей модели все еще должно выглядеть знакомо, но теперь он удобен для активного выполнения, оставаясь совместимым с графическим режимом. Интегрируя обе половины средств API summary.FileWriter
теперь является частью контекста выполнения TensorFlow и получает доступ непосредственно tf.summary
опса, поэтому настройка писателей является основной частью , которая выглядит по- другому.
Пример использования с нетерпеливым исполнением, по умолчанию в 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
Пример использования с выполнением графа 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
Пример использования с выполнением устаревшего графа TF 1.x:
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
Преобразование вашего кода
Преобразование существующего tf.summary
использования в 2.x TF API не может быть надежно автоматизирован, поэтому tf_upgrade_v2
скрипт просто переписывает все это tf.compat.v1.summary
. Для перехода на TF 2.x вам необходимо адаптировать код следующим образом:
Набор писателя по умолчанию с помощью
.as_default()
должен присутствовать , чтобы использовать сводный опс- Это означает активное выполнение операций или использование операций при построении графа.
- Без средства записи по умолчанию сводные операции становятся беззвучными.
- По умолчанию писателей не (пока) распространяются через
@tf.function
границы выполнения - они обнаруживаются только тогда , когда функция прослеживается - так что лучше практика называтьwriter.as_default()
внутри тела функции, а также для того, чтобы объект писателя продолжает существовать до тех пор , как@tf.function
используется
Значение «шаг» должно быть передано в каждый оп через
step
аргумент- TensorBoard требует значение шага для рендеринга данных в виде временного ряда.
- Явная передача необходима, потому что глобальный шаг из TF 1.x был удален, поэтому каждая операция должна знать желаемую переменную шага для чтения
- Для снижения шаблонного, экспериментальная поддержка регистрации значения шага по умолчанию доступна как
tf.summary.experimental.set_step()
, но это предварительная функциональность , которая может быть изменена без предварительного уведомления
Сигнатуры функций отдельных сводных операций изменены
- Возвращаемое значение теперь является логическим (указывает, действительно ли было написано резюме)
- Второе имя параметра (если используется) изменился с
tensor
кdata
-
collections
параметр был удален; коллекции только TF 1.x -
family
параметр был удален; просто использоватьtf.name_scope()
[Только для устаревшего режима графа / пользователей, выполняющих сеанс]
Во- первых инициализацию писатель с
v1.Session.run(writer.init())
Используйте
v1.summary.all_v2_summary_ops()
, чтобы получить все сводные 2.x TF опа для текущего графика, например , чтобы выполнить их с помощьюSession.run()
Промойте писатель с
v1.Session.run(writer.flush())
, а также дляclose()
Если TF код 1.x был используя вместо tf.contrib.summary
API, это гораздо больше похоже на 2.x TF API, поэтому tf_upgrade_v2
скрипт позволит автоматизировать большинство этапов миграции (и испускают предупреждения или ошибки для любого использования , которые не могут быть полностью перенесенным). По большей части он просто переписывает API вызовы к tf.compat.v2.summary
; если вам нужно только совместимость с 2.x TF вы можете уронить compat.v2
и просто ссылаться на него , как tf.summary
.
Дополнительные советы
Помимо вышеперечисленных критических областей, изменились и некоторые вспомогательные аспекты:
Условная запись (например, «журнал каждые 100 шагов») получила новый вид.
- Для управления операциями и связанными с ними кода, завернуть их в правильной , если заявление (которое работает в нетерпеливом режиме и в
@tf.function
через автографа ) илиtf.cond
- Для того, чтобы контролировать только их резюме, используйте новый
tf.summary.record_if()
менеджера контекста, и передать его логическое состояние вашего выбора Они заменяют шаблон TF 1.x:
if condition: writer.add_summary()
- Для управления операциями и связанными с ними кода, завернуть их в правильной , если заявление (которое работает в нетерпеливом режиме и в
Нет прямого написания
tf.compat.v1.Graph
- вместо использования трассировки функции- Выполнение графика в 2.x TF использования
@tf.function
вместо явного Graph - В 2.x ТФА использовать API , новая трассировку стиле
tf.summary.trace_on()
иtf.summary.trace_export()
для записи выполняемых функций графики
- Выполнение графика в 2.x TF использования
Не более глобального кэширования писателей в LogDir с
tf.summary.FileWriterCache
- Пользователи должны либо реализовать свое собственное кэширование / обмен объектов писателя, или просто используйте отдельные автор (поддержку TensorBoard последним является в процессе )
Изменилось двоичное представление файла событий.
- TensorBoard 1.x уже поддерживает новый формат; это различие влияет только на пользователей, которые вручную анализируют сводные данные из файлов событий.
- Сводные данные теперь хранятся в виде тензорных байтов; Вы можете использовать
tf.make_ndarray(event.summary.value[0].tensor)
, чтобы преобразовать его в NumPy