不能。TensorFlow 2.x 已移除 tf.summary.FileWriter,须改用 tf.summary.create_file_writer,且需配合 with writer.as_default() 和 tf.summary.scalar 等在 eager 模式下正确写入日志。

TensorFlow 1.x 中 FileWriter 能不能直接用在 2.x?
不能。TensorFlow 2.x 默认启用 eager execution,tf.summary.FileWriter 在 2.0+ 已被移除,强行 import 会报 AttributeError: module 'tensorflow' has no attribute 'summary' 或类似错误。如果你看到旧教程里写 tf.summary.FileWriter('./logs'),那基本是为 1.x 写的,直接套用会卡在第一步。
正确路径是改用 tf.summary.create_file_writer,且必须配合 @tf.function 或显式进入 graph mode(不推荐),否则 scalar/image 等写入操作不会触发。
- 2.x 下所有 summary 写入必须发生在
tf.summary.record_if(True)上下文或tf.summary.trace_on()后的 trace 区域内 - 日志目录路径需为字符串,不能是
Path对象,否则create_file_writer会静默失败 - 写入前确保目录可写,Windows 下注意反斜杠转义问题(建议统一用正斜杠或
os.path.join)
怎么用 tf.summary.create_file_writer 记录 loss 和 accuracy?
核心是:创建 writer → 在训练 step 中用 with writer.as_default() → 调用 tf.summary.scalar。注意它不自动绑定到某个 session,也不依赖 global_step 参数(那是 1.x 的写法)。
import tensorflow as tf
<p>writer = tf.summary.create_file_writer('./logs/train')
model = tf.keras.Sequential([...])
optimizer = tf.keras.optimizers.Adam()</p><p>@tf.function
def train_step(x, y):
with tf.GradientTape() as tape:
logits = model(x, training=True)
loss = tf.keras.losses.sparse_categorical_crossentropy(y, logits, from_logits=True)
loss = tf.reduce_mean(loss)</p><pre class="brush:php;toolbar:false;">grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
# 关键:必须在 as_default 上下文中写入
with writer.as_default():
tf.summary.scalar('loss', loss, step=optimizer.iterations)
# step 用 optimizer.iterations 或自定义 step counter,不能传 int 常量
return loss
-
step参数必须是tf.Variable或tf.Tensor,传int会报ValueError: step must be an integer - 多个指标要分别调用
tf.summary.scalar,不能打包成 dict 一次性写 - 如果用
tf.keras.Model.fit(),更推荐用tf.keras.callbacks.TensorBoard回调,它内部已封装好 writer 生命周期
FileWriter 日志写进去了,但 TensorBoard 打不开或没数据?
常见不是代码问题,而是启动方式或路径错位。TensorBoard 读取的是 event 文件,不是 logs 目录本身——它需要找到形如 events.out.tfevents.* 的文件。
- 确认 logs 目录下确实生成了 event 文件(用
ls ./logs/train或资源管理器刷新查看) - 启动 TensorBoard 时路径必须指向 logs 的父级,例如日志在
./logs/train,就该运行tensorboard --logdir=./logs,而不是--logdir=./logs/train(除非你只打算看这一个 run) - Windows 用户遇到 “address already in use”,先
netstat -ano | findstr :6006查 PID,再taskkill /PID xxx /F杀掉旧进程 - Chrome 浏览器缓存可能导致页面不更新,试试
Ctrl+Shift+R强刷,或换 Edge / Firefox 验证
想同时记录训练和验证指标,该怎么组织日志目录?
靠子目录区分是最稳妥的做法。TensorBoard 的 --logdir 支持多路径别名语法:--logdir=train:./logs/train,valid:./logs/valid,这样左侧边栏就会显示两个可切换的 run。
代码上只需创建两个独立 writer:
train_writer = tf.summary.create_file_writer('./logs/train')
valid_writer = tf.summary.create_file_writer('./logs/valid')
<h1>训练循环中</h1><p>with train_writer.as_default():
tf.summary.scalar('loss', train_loss, step=step)</p><h1>验证阶段</h1><p>with valid_writer.as_default():
tf.summary.scalar('val_accuracy', val_acc, step=step)
</p>
- 两个 writer 可共用同一个
step值(比如全局 step),也可以各自计数(如train_step和valid_step),TensorBoard 会按时间轴对齐 - 避免把 train/valid 写进同一个 writer,否则指标混在一起无法分离,filter 功能也失效
- 如果用 Keras fit + TensorBoard 回调,它默认自动建
train和validation子目录,无需手动干预
TensorBoard 日志本质是异步写入的,flush() 不常调用,但训练结束时最好显式 writer.close(),否则最后几十步数据可能丢失;另外,频繁调用 as_default() 嵌套过深容易引发 context 错误,建议每个 step 只进一次 writer 上下文。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











