我对TensorFlow 1.x非常熟悉,正在考虑为即将到来的项目切换到TensorFlow 2。我在理解如何在启用即时执行模式下使用自定义训练循环将标量写入TensorBoard日志时遇到了一些麻烦,可以参考自定义训练循环的教程。
问题描述
在tf1中,您会创建一些摘要操作(每个您想要存储的内容创建一个操作),然后将这些操作合并成一个单一的操作,在会话中运行该合并操作,然后使用FileWriter对象将其写入文件。假设sess
是我们的tf.Session()
,以下是一个示例代码,展示了这是如何工作的:
# 在定义我们的计算图时,定义摘要操作:# ... 一些操作 ...tf.summary.scalar('scalar_1', scalar_1)# ... 更多操作 ...tf.summary.scalar('scalar_2', scalar_2)# ... 等等# 将所有这些摘要合并成一个单一操作:merged = tf.summary.merge_all()# 定义一个FileWriter(即一个将摘要写入文件的对象):writer = tf.summary.FileWriter(log_dir, sess.graph)# 在训练循环中运行操作并将结果写入文件:for i in range(num_iters): summary, ... = sess.run([merged, ...], ...) writer.add_summary(summary, i)
问题在于tf2中不再存在会话,我更希望不禁用即时执行来使其工作。官方文档是为tf1编写的,我能找到的所有参考资料都建议使用TensorBoard的keras回调。然而,据我所知,这仅在您通过model.fit(...)
训练模型时有效,而不适用于自定义训练循环。
我尝试过的方法
- 在会话之外使用tf1版本的
tf.summary
函数。显然,这些函数的任何组合都会失败,因为FileWriters、merge_ops等在tf2中甚至不存在。 - 这篇Medium文章指出,TensorFlow的一些API(包括
tf.summary()
)进行了“清理”。他们建议使用from tensorflow.python.ops.summary_ops_v2
,但这似乎不起作用。这暗示使用record_summaries_every_n_global_steps
;稍后会详细讨论。 - 一系列其他文章1, 2, 3,建议使用
tf.contrib.summary
和tf.contrib.FileWriter
。然而,tf.contrib
已从TensorFlow核心仓库和构建过程中移除。 - 来自官方仓库的TensorFlow v2展示,再次使用了
tf.contrib
摘要以及之前提到的record_summaries_every_n_global_steps
。我也没能让这个工作(即使不使用contrib库)。
简而言之
我的问题是:
- 在TensorFlow 2中是否有正确使用
tf.summary
的方法? - 如果没有,在使用自定义训练循环(不是
model.fit()
)时,有没有其他方法可以在TensorFlow 2中写入TensorBoard日志?
回答:
是的,有一个更简单、更优雅的方法可以在TensorFlow v2中使用摘要。
首先,创建一个存储日志的文件写入器(例如,在名为log_dir
的目录中):
writer = tf.summary.create_file_writer(log_dir)
在任何你想将内容写入日志文件的地方(例如,一个标量),使用writer创建的上下文中使用你熟悉的tf.summary.scalar
。假设你想为步骤i
存储scalar_1
的值:
with writer.as_default(): tf.summary.scalar('scalar_1', scalar_1, step=i)
你可以在训练循环内外随意打开多个这样的上下文。
示例:
# 创建文件写入器对象writer = tf.summary.create_file_writer(log_dir)for i, (x, y) in enumerate(train_set): with tf.GradientTape() as tape: y_ = model(x) loss = loss_func(y, y_) grads = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) # 写入损失值 with writer.as_default(): tf.summary.scalar('training loss', loss, step=i+1)