可视化模块(三): wandb

本文目录

  • wandb安装
  • loss曲线记录
    • 1. step记录
    • 2. custom x-axis
      • 方法一(推荐)
      • 方法二
  • Image记录
    • 1. 单张Image
    • 2. 多张Image
      • 方法一(推荐)
      • 方法二
    • 3. Image拼接
  • distribute注意事项

wandb是一个可视化库,他有visdom实时查看的优点以及能够永久的记录到云端

wandb安装

登陆https://wandb.ai注册一个wandb账号,然后运行下面命令安装wandb。使用时在终端输入wandb login按照提示输入即可

pip install wandb

使用手册

对于PyTorch:Quick start
Document:使用手册

loss曲线记录

1. step记录

wandb默认的是按照step记录的,也就是说每执行一次命令,就记录一次step,下面举个例子说明

注意:下面例子均需要修改wandb.init内部的值,自己写个简单的demo修改即可

''' parser '''
parser = argparse.ArgumentParser(description='your description')
parser.add_argument('--xx', default=xx)
opt = parser.parse_args()

''' init wandb '''
wandb.init(project="project nmae", entity="your account", config=opt)

# 添加了loss曲线
for epoch in range(1, 20):
	wandb.log({"train loss": 10/(3*epoch)})
	wandb.log({"test loss": 10/(2*epoch)})

运行结果如下,横坐标为step,从0开始,每运行一次wandb.log命令step+1,也就是说train loss的曲线横坐标为[0, 2, 4, …],test loss的曲线横坐标为[1, 3, 5, …],在训练网络的时候我们需要将横坐标改为epoch或者其他我们需要的值,怎么操作呢?看第二步

可视化模块(三): wandb_第1张图片

2. custom x-axis

这里提供两种自定义x轴的方法,其中第一种较为简单(推荐),第二种也可以学习一下

方法一(推荐)

只需要在wandb.log中多记录一条epoch即可,代码如下

for epoch in range(1, 20):
    wandb.log({"train loss": 10/(3*epoch), 'epoch':epoch})
    wandb.log({"test loss": 10/(2*epoch), 'epoch':epoch})

运行后结果如下,多了一条epoch曲线,但是loss曲线并没有变化啊,别急,看第二幅图,只需要点击右上角的x从step改变为epoch即可

可视化模块(三): wandb_第2张图片

改变后的曲线如下

可视化模块(三): wandb_第3张图片

方法二

此方法要使用wandb.define_metric方法,具体使用直接看例子就很容易明白,函数内的step_metric意思是将custom_epoch添加到train loss的横坐标当中去

''' init wandb '''
wandb.init(project="project nmae", entity="your account", config=opt)
wandb.define_metric("custom_epoch")
wandb.define_metric("train loss", step_metric='custom_epoch')

# 添加了loss曲线
for epoch in range(1, 20):
    wandb.log({"custom_epoch": epoch})
	wandb.log({"train loss": 10/(3*epoch)})
	wandb.log({"test loss": 10/(2*epoch)})

运行结果如下,运行完后需要点击train loss右上角的小笔,把他的x轴改为custom_epoch不然不会生效

可视化模块(三): wandb_第4张图片

Image记录

官方教程:https://docs.wandb.ai/guides/track/log/media

1. 单张Image

这里numpy为uint8、[0, 255]、HWC类型,使用wandb.Image将其转化为wandb能够记录的图片,其中caption为图片的标题,即图片的名字,然后用wandb.log记录即可

''' init wandb '''
wandb.init(project="project nmae", entity="your account", config=opt)

img = np.arange(1, 301).reshape(10, 10, 3)
Img = wandb.Image(img, caption="I am an image")
wandb.log({"log an image": Img})

效果如下,不同于曲线,图片记录在Media模块下

可视化模块(三): wandb_第5张图片

2. 多张Image

如果我们想记录多张image怎么办呢?例如我们需要记录每个epoch的图片并查看他的变化

还记得loss曲线中讨论的step吗,wandb.log每运行一次step就会加1,对于曲线的绘制我们可以改变它的横坐标,但是图片的横坐标改变不了(我尝试过,怎么也改不了)。如果我们记录了100张图片,我们很难知道他们是哪个epoch的结果,需要从头数,这样很麻烦

下面依然给出两个解决方案

方法一(推荐)

先直接给出代码看效果,我们在记录图片的同时运行了wandb.log记录loss,当我们运行到epoch=10时,我们的step到了27(如下图),图片的索引(即step)没法修改为epoch,所以我们在存储图片的时候直接修改caption即可知道是哪个epoch的图片了

''' init wandb '''
wandb.init(project="project nmae", entity="your account", config=opt)

for epoch in range(1, 20):
    img = np.arange(1, 301).reshape(10, 10, 3)
    Img = wandb.Image(img, caption="epoch:{}".format(epoch))  # attention!!!
    wandb.log({"loglog": Img})
    wandb.log({"train loss": 10/(3*epoch)})
    wandb.log({"test loss": 10/(2*epoch)})

可视化模块(三): wandb_第6张图片

方法二

这个方法比较简单粗暴。。就是把所有的图片都记录下来。。这样会有很多个框框,直接看代码和运行结果吧,有多少个epoch,在media下就有多少张图片,会显得比较冗杂

for epoch in range(1, 20):
    img = np.arange(1, 301).reshape(10, 10, 3)
    Img = wandb.Image(img, caption="I am an image")  
    wandb.log({"loglog{}".format(epoch): Img})							# attention!!!
    wandb.log({"train loss": 10/(3*epoch)})
    wandb.log({"test loss": 10/(2*epoch)})

可视化模块(三): wandb_第7张图片

两个方法对比

其实这两个方法就是命名略有不同,一个是命名在图片备注上,一个是明明在log中

''' 方法一 '''
Img = wandb.Image(img, caption="epoch:{}".format(epoch))  # here!!!
wandb.log({"loglog": Img})
''' 方法二 '''
Img = wandb.Image(img, caption="I am an image")  
wandb.log({"loglog{}".format(epoch): Img})			      # here!!!

3. Image拼接

一般来说我们在一个epoch的时候想看看GT与Rec的区别,这就需要将两张图或者更多图拼接,效果基本上如下所示,直接给出代码

转化为Numpy [255, unit8, RGB]

# 将tensor转为cpu
img, gt = img[0].detach().cpu(), gt[0].detach().cpu()
# 如果获取数据时用了-mean/var操作,后续需要在调回去
img = img*0.5+0.5
gt  = gt*0.5+0.5
# concat并转为numpy 255 uint8
ori_bgc = np.concatenate([img, gt], axis=2)
ori_bgc = np.transpose(ori_bgc, (1, 2, 0))
ori_bgc = Image.fromarray(np.clip(ori_bgc * 255.0, 0, 255.0).astype('uint8'))
# caption and log info
LtoH    = wandb.Image(ori_bgc, caption="epoch{}: results".format(epoch))
wandb.log({"LtoR: Origin BGColor Results": LtoH})

可视化模块(三): wandb_第8张图片

distribute注意事项

注意在分布式训练中我们一般只记录一个GPU上的内容,也就是说如果我们将images进行记录并不会记录所有的图片。举个例子:我们验证集一共有24张,我们用了6张卡,在数据分配的时候每张卡分配了4个数据,在进行验证记录每个epoch结果的时候一般来说我们只将标号为0的那张卡进行记录,所以只记录了4幅图,并不会记录所有的24张

那么如果我们想记录所有的图怎么办?那就让所有的卡(0,1,2,3,4,5)都去记录,这样的一个缺点是最后会在project下生成6个记录,而不是一个

你可能感兴趣的:(可视化,深度学习,pytorch,wandb,可视化)