В настоящее время я работаю над чуть более крупным проектом TensorFlow и пытаюсь визуализировать определенные переменные моей сети, как обычно, т.е. выполнять этот рабочий процесс
tf.summary.scalar('loss', loss)
summary_op = tf.summary.merge_all()
writer = tf.summary.FileWriter('PATH')
и добавьте графs = sess.run(summary_op)
writer.add_summary(s, epoch)
Обычно это делает работу для меня. Но на этот раз я получил график, и когда я проверил файл-событие, я обнаружил, что он пуст. По совпадению я обнаружил, что кто-то предлагает использовать writer.flush()
после добавления моего резюме в качестве 6-го шага. Это решило мою проблему.
Как следствие, логический последующий вопрос: когда и как мне нужно использовать FileWriter.flush()
чтобы сделать shadoworflow работать правильно?
На самом деле вы можете называть flush
когда захотите. Это, вероятно, очевидно для вас, но на всякий случай (и для других читателей) FileWriter
не сразу записывает данные резюме на диск. Это связано с тем, что запись на диск относительно медленная, и если вы создаете очень частые сводки (т.е. каждая партия), это может повредить вашу производительность, поэтому FileWriter
сохраняет буфер событий, которые записываются только "каждый раз в то время" (и наконец, когда он закрыт). Однако это означает, что TensorBoard не увидит письменные сводки сразу. flush
чтобы заставить FileWriter
записывать на диск все, что у него есть в памяти.
Если вы делаете резюме с низкой частотой (например, каждые 100 партий), то, вероятно, хорошо просто вызвать flush
после add_summary
. Если вы постоянно создаете резюме, но не удовлетворены частотой синхронизации FileWriter
, вы можете иметь flush
например, каждый раз в десять раз или что-то в этом роде. Я имею в виду, вы также можете использовать его на каждой итерации, и это может не иметь такой большой разницы, но это не принесет вам такой большой пользы. Разумеется, любое потенциальное влияние на производительность будет зависеть от вашей проблемы и вашей инфраструктуры (это не то же самое сканирование протоколов, что и изображения, либо вход в локальный SSD-накопитель, чем в сетевое хранилище, или большие, медленные партии сотен элементов, чем крошечные, быстрые партии всего несколько).
В целом, однако, это редко является значительным фактором производительности. Для простых сценариев, предложение вы получили добавление flush
после add_summary
(один flush
, если у вас есть несколько вызовов add_summary
не flush
после каждой из них, только после последней), скорее всего, достаточно хорошо.
EDIT: tf.summary.FileWriter
самом деле предлагает параметр построения flush_secs
, который определяет, как часто писатель автоматически очищает отложенные события на диске. По умолчанию это две минуты. Существует также max_queue
, который определяет размер внутренней очереди событий (буфер событий).