使用wandb可视化

wandb

wandb是 Weights & Biases 的缩写,这款工具能够帮助跟踪你的机器学习项目。 它能够自动记录模型训练过程中的超参数和输出指标,然后可视化和比较结果,并快速与同事共享结果。

官网文档:What is Weights & Biases? | Weights & Biases Documentation (wandb.ai)

简单使用操作

0. 注册wandb账号,并获取api key

  • 在官网注册账号:Weights & Biases (wandb.ai) (github账号即可注册)
  • 获取api key(按照官网引导即可)
    • api key后续要用到

1. set up

  • pip安装

    1
    pip install wandb
  • 登录wandb

    1
    wandb login

    会提示输入api key。如果已经登录过了,想要重新登录,则使用relogin

2. 在代码中配置

  • 导入

    1
    import wandb
  • 初始化新的 W&B 运行

    1
    2
    3
    import wandb
    config = {} #实验设置,如lr等。wandb.init传入conifg,实际上只是用于显示标识自己设置的参数。
    wandb.init(project="project_name",config= config)
  • 跟踪指标

    train_acc为代码epoch中实际的变量。通过该命令,可以绘制出指标变化图像。也可以记录自己想要的参数。

    1
    wandb.log({'accuracy': train_acc, 'loss': train_loss})
  • 关于权重梯度等的显示

​ 一行简单的命令即可:

1
wandb.watch(model, log='all')

​ 加载模型定义完之后。

  • 最后

    1
    wandb.finish()

    jupyter book必须加,其他可选。

3.运行代码

  • 运行自己的代码

  • 控制台会显示结果可视化在云端的哪个链接。每次run都会保留一个log在本地。

4. 可视化结果展示

进入project下对应run的链接

  • charts为前面通过log命令跟踪的指标

  • 通过watch我们可以看到梯度和权重!

完整代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# !usr/bin/env python3
# -*- coding:UTF-8 -*-

# @Author:
# @File:wandb_gra.py
# @Time:2023-03-20 13:51
"""
文件说明:

"""
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
import wandb
from tqdm import *
from model import CNN_Net



def train(model, device, train_loader, optimizer, epoch):
model.train()

n_ex = len(train_loader)

for batch_idx, (data, target) in tqdm(enumerate(train_loader), total=n_ex):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()


def test(model, device, test_loader):
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
output = model(data)
test_loss += F.nll_loss(output, target, reduction='sum').item()
pred = output.argmax(dim=1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()

test_loss /= len(test_loader.dataset)

tqdm.write('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))

##注意
wandb.log({'test_loss': test_loss,
'accuracy': correct / len(test_loader.dataset)})


def main():
config = {
'BATCH_SIZE': 64,
'TEST_BATCH_SIZE': 1000,
'EPOCHS': 10,
'LR': 0.01,
'MOMENTUM': 0,
'SEED': 17,

}
##注意
wandb.init(project='explore-gradients', reinit=True, config=config)

use_cuda = torch.cuda.is_available()

torch.manual_seed(config['SEED'])

device = torch.device("cuda" if use_cuda else "cpu")

kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=config['BATCH_SIZE'], shuffle=True, **kwargs)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data', train=False, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=config['TEST_BATCH_SIZE'], shuffle=True, **kwargs)

model = CNN_Net().to(device)

##注意
wandb.watch(model, log='all')

optimizer = optim.SGD(model.parameters(),
lr=config['LR'],
momentum=config['MOMENTUM'])

for epoch in range(1, config['EPOCHS'] + 1):
train(model, device, train_loader, optimizer, epoch)
test(model, device, test_loader)

if __name__ == '__main__':

main()

bug记录

  • 如果出现process communicating error:
1
wandb.init(project='project_name', reinit=True, config=config,setting=wandb.Settings(start_method=("fork")))

特定版本以上:

1
wandb.init(project='explore-gradients', reinit=True, config=config,setting=wandb.Settings(start_method=("thread")))