931 字
5 分钟
Weights & Biases 初探:给 MNIST CNN 加个实验追踪

起因#

昨天偶然接触到一个使用 wandb 的项目。打开官网看了看介绍,发现这东西还挺有意思的。

Weights & Biases(简称 wandb)是一个机器学习实验追踪平台。它能自动记录你训练过程中的各种指标、超参数、模型权重,甚至是 git commit 信息。官方宣传的卖点是”几行代码集成,永久保存实验记录”。

听起来很美好。于是今天决定亲自试一试。

实验设置#

让 Codex 写了一个简单的 MNIST CNN,然后用 wandb 进行可视化追踪。整个过程确实挺顺滑的——wandb.init() 初始化项目,wandb.log() 记录指标,wandb.watch() 追踪梯度。setup 一次,后面基本不用管。

主要代码如下:

def train(config):
device = get_device()
print(f"Using device: {device}")
wandb.init(project=config.project, config=config, mode=config.wandb_mode)
model = SimpleCNN().to(device)
wandb.watch(model, log="gradients", log_freq=100)
train_loader, val_loader = get_dataloaders(config.batch_size)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=config.lr)
for epoch in range(1, config.epochs + 1):
model.train()
running_loss = 0.0
correct = 0
total = 0
for batch_idx, (images, labels) in enumerate(train_loader, start=1):
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item() * images.size(0)
_, predicted = torch.max(outputs, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
train_loss = running_loss / total
train_acc = correct / total
val_loss, val_acc = evaluate(model, val_loader, device)
log_data = {
"epoch": epoch,
"train/loss": train_loss,
"train/accuracy": train_acc,
"val/loss": val_loss,
"val/accuracy": val_acc,
}
if config.log_samples:
sample_images, sample_labels = next(iter(val_loader))
sample_images = sample_images.to(device)
with torch.no_grad():
preds = model(sample_images).argmax(dim=1)
log_data["val/sample_predictions"] = log_sample_predictions(
sample_images[:16].cpu(), sample_labels[:16], preds[:16].cpu()
)
wandb.log(log_data)
print(
f"Epoch {epoch}/{config.epochs} "
f"- train_loss: {train_loss:.4f}, train_acc: {train_acc:.4f} "
f"- val_loss: {val_loss:.4f}, val_acc: {val_acc:.4f}"
)
wandb.finish()
return model

代码结构很直白。wandb.init() 创建一个 run,wandb.watch() 让它自动记录模型梯度,然后每个 epoch 结束后用 wandb.log() 把 loss 和 accuracy 推上去。

使用体验#

好的部分:

  • 集成简单:确实是几行代码的事。不需要自己写 TensorBoard 那套 SummaryWriter 逻辑。
  • 自动同步:训练跑着,网页上实时就能看到曲线。比赛或者调参的时候盯着看还挺爽的。
  • 历史记录:所有 run 都存在云端。回头想对比不同实验,直接拉出来就行。

踩坑:Panel Expression#

然后就遇到一个让人头疼的问题。

wandb 的网页端有可视化 panel,可以自定义显示的指标。我想看 accuracy 的变化,但是训练后期 accuracy 接近 1,曲线基本是一条直线,看不出细节。

自然想到用 log scale。但 wandb 的 log scale 默认下界是 0,对于接近 1 的值来说没什么帮助。

于是想翻转一下,显示 1 - accuracy,这样误差率越小,值越小,用 log scale 就能看清变化了。

在 expression 那里写了 1 - ${train/accuracy}

不显示。

没有报错,就是不显示。整得我一脸懵。

WARNING

wandb panel 的 expression 语法文档写得不太清楚。很多操作看起来应该能用,实际上就是不工作,也没有有意义的错误提示。

最后的(部分)解决方案是用 ${train/accuracy}**100 来放大显示。虽然不是真正的 log scale 翻转,但至少能看到一些变化了。

如果有人知道正确的写法,欢迎告诉我。我真的很想知道。

代码仓库#

本次实验的完整代码放在这里:

StevenLi-phoenix
/
wandbTestCNN
Waiting for api.github.com...
00K
0K
0K
Waiting...

README 没写。但是代码就这样吧。能跑就行。(躺平)

后面又稍微补了一个前端:

小结#

wandb 作为实验追踪工具,核心功能确实好用。setup 简单,自动同步,历史记录完整。对于需要频繁调参、对比实验的场景,比手动记 Excel 强太多了。

但 panel 的自定义 expression 功能体验不太好。语法不直观,报错信息缺失。希望后续能改进吧。

总体来说,值得一试。


Works Cited#

“Experiments.” Weights & Biases Documentation, docs.wandb.ai/models/track. Accessed 4 June 2025.

“Track Experiments.” Weights & Biases Documentation, docs.wandb.ai/tutorials/experiments/. Accessed 4 June 2025.

[!quote] Be here now. Be someplace else later. Is that so complicated? — David Bader

Weights & Biases 初探:给 MNIST CNN 加个实验追踪
https://blog.lishuyu.top/posts/wandb/
作者
猫猫魔女
发布于
2025-12-04
许可协议
CC BY-NC-SA 4.0