• 可视化工具Visdom的使用


    Visdom介绍

    ​ Visdom是Facebook专为PyTorch开发的实时可视化工具包,其作用相当于TensorFlow中的Tensorboard,灵活高效且界面美观。如果想更多了解关于Visdom的使用可以参考官方文档

    安装

    打开cmd窗口,输入命令即可

    pip install visdom
    
    • 1

    使用

    要是用Visdom,需要在终端先开启监控命令,根据显示在浏览器中输入: http://localhost:8097 。监控命令有两种方式:

    '''方式1'''
    python -m visdom.server
    '''方式2'''
    直接visdom
    
    • 1
    • 2
    • 3
    • 4

    界面

    preview

    1. env被保存在$HOME/.visdom/ 这里,里面保存的是.json文件,如果json被删除,相应保存的env也就没了。
    2. 浏览器界面中environment右边可以选择env,默认是main,点击哪个env就会显示对应的绘制。
    3. clear旁边的可以保存env,再右边哪个manage只能保存view,为了将数据保存到本地,只能使用clear旁边将env保存下来

    Visdom可视化函数及其参数一览

    visdom基本可视化函数

    vis.image : #图片
    vis.line: #曲线
    vis.images : #图片列表
    vis.text : #抽象HTML 输出文字
    vis.properties : #属性网格
    vis.audio : #音频
    vis.video : #视频
    vis.svg : #SVG对象
    vis.matplot : #matplotlib图
    vis.save : #序列化状态服务端
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    上述函数参数

    • 注意opt的参数都可以用python字典的格式传入
    opts.title : #图标题
    win:#窗口名称
    opts.width : #图宽
    opts.height : #图高
    opts.showlegend : #显示图例 (true or false)
    opts.xtype : #x轴的类型 ('linear' or 'log')
    opts.xlabel : #x轴的标签
    opts.xtick : #显示x轴上的刻度 (boolean)
    opts.xtickmin : #指定x轴上的第一个刻度 (number)
    opts.xtickmax : #指定x轴上的最后一个刻度 (number)
    opts.xtickvals : #x轴上刻度的位置(table of numbers)
    opts.xticklabels : #在x轴上标记标签 (table of strings)
    opts.xtickstep : #x轴上刻度之间的距离 (number)
    opts.xtickfont :#x轴标签的字体 (dict of font information)
    opts.ytype : #type of y-axis ('linear' or 'log')
    opts.ylabel : #label of y-axis
    opts.ytick : #show ticks on y-axis (boolean)
    opts.ytickmin : #first tick on y-axis (number)
    opts.ytickmax : #last tick on y-axis (number)
    opts.ytickvals : #locations of ticks on y-axis (table of numbers)
    opts.yticklabels : #ticks labels on y-axis (table of strings)
    opts.ytickstep : #distances between ticks on y-axis (number)
    opts.ytickfont : #font for y-axis labels (dict of font information)
    opts.marginleft : #左边框 (in pixels)
    opts.marginright :#右边框 (in pixels)
    opts.margintop : #上边框 (in pixels)
    opts.marginbottom: #下边框 (in pixels)
    opts.lagent=['']#显示图标
    
    • 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

    应用

    实时曲线绘制

    • 方法:起始点+数据点更新
    from Visdom import Visdom
    vis = Visdom()   #初始化visdom类。
    #括号内可以添加参数,如使用“env = ‘环境名称’ ”对绘图环境进行命名。此时在可视化界面需在上方的 Environment中勾选相应的环境名称才可以将图片显示出来。如果没有env,则默认环境名称为main
    '''起点'''
    vis.line([0.],     #第一个点的Y坐标
             [0.],     #第一个点的X坐标
             win='train loss',  #窗口名称
             opts=dict(title = 'train_loss',xlabel='episodes',ylabel='loss') #图标题、x轴和Y轴标签
             ) #设置起点
    '''模型数据'''
    vis.line([1.],[1.],       #下一点的Y坐标及X坐标
             win='train loss',  ## 窗口名称 与上个窗口同名表示显示在同一个表格里
             update='append')  # 添加到上一个点的后面
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    image-20210308110503160

    从上图中可以看出:

    1. 窗口名称显示在图片的右上角;
    2. 右下角有一个Edit,点击进去,可以对图片类型等进行修改,甚至可以保存数据;
    '''多条曲线绘制 实际上就是传入y值时为一个向量'''
    vis = Visdom(env='my wind') # 环境名称为'my wind'
     #设置起始点
    vis.line([[0.0,0.0]],    ## Y的起始点
              [0.],    ## X的起始点
             win="test loss",    ##窗口名称
             opts=dict(title='test_loss')  ## 图像标例
            )
    '''模型数据'''
    vis.line([[1.1,1.5]],   ## Y的下一个点
            [1.],   ## X的下一个点
            win="test loss", ## 窗口名称
            update='append'   ## 添加到上一个点后面
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    image-20210308110902555

    实际应用

    '''
    导入库文件
    '''
    
    import  torch
    import  torch.nn as nn
    import  torch.nn.functional as F
    import  torch.optim as optim
    from    torchvision import datasets, transforms
    from visdom import Visdom
    import numpy as np
    '''
    构建简单的模型:简单线性层+Relu函数的多层感知机
    '''
    class MLP(nn.Module):
    
       def __init__(self):
        super(MLP, self).__init__()
            self.model = nn.Sequential(
                nn.Linear(784, 200),
                nn.ReLU(inplace=True),
                nn.Linear(200, 200),
                nn.ReLU(inplace=True),
                nn.Linear(200, 10),
                nn.ReLU(inplace=True))
        def forward(self, x):
            x = self.model(x)
    
            return x
    batch_size = 128
    earning_rate = 0.01
    epochs = 10
    train_loader = torch.utils.data.DataLoader(datasets.MNIST(
        'D:/data/MNIST', # 
        train=True,
       download=True,
        transform=transforms.Compose(
            [transforms.ToTensor(),
             transforms.Normalize((0.1307, ), (0.3081, ))])),
                                               batch_size=batch_size,
                                               shuffle=True)
    test_loader = torch.utils.data.DataLoader(datasets.MNIST(
        'D:/Jupyter/工作准备/data/MNIST',
        train=False,
        transform=transforms.Compose(
            [transforms.ToTensor(),
             transforms.Normalize((0.1307, ), (0.3081, ))])),
                                              batch_size=batch_size,
                                              shuffle=True)
    
    # 注意此处初始化visdom类
    viz = Visdom()
    # 绘制起点
    viz.line([0.], [0.], win="train loss", opts=dict(title='train_loss'))
    device = torch.device('cuda:0')
    net = MLP().to(device)
    optimizer = optim.SGD(net.parameters(), lr=learning_rate)
    criteon = nn.CrossEntropyLoss().to(device)
    
    for epoch in range(epochs):
    
        for batch_idx, (data, target) in enumerate(train_loader):
            data = data.view(-1, 28 * 28)
            data, target = data.to(device), target.cuda()
            logits = net(data)
            loss = criteon(logits, target)
    
          optimizer.zero_grad()
            loss.backward()
            # print(w1.grad.norm(), w2.grad.norm())
            optimizer.step()
           if batch_idx % 100 == 0:
                print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                  epoch, batch_idx * len(data), len(train_loader.dataset),
                    100. * batch_idx / len(train_loader), loss.item()))
    
       test_loss = 0
        correct = 0
        for data, target in test_loader:
            data = data.view(-1, 28 * 28)
           data, target = data.to(device), target.cuda()
           logits = net(data)
           test_loss += criteon(logits, target).item()
    
            pred = logits.argmax(dim=1)
           correct += pred.eq(target).float().sum().item()
    
        test_loss /= len(test_loader.dataset)
        # 绘制epoch以及对应的测试集损失loss
      	viz.line([test_loss], [epoch], win="train loss", update='append') # win是必须的 
       	print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
       	test_loss, correct, len(test_loader.dataset), correct / len(test_loader.dataset)))
    
    • 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

    远程显示服务器上的代码结果

    1. 在xshell上运行visdom
    2. 通过浏览器访问远程服务器地址的8097(默认)端口来远程观察模型的训练情况
      • 假设服务器ip为192.168.1.2
      • 在本地浏览器上打开192.168.1.2:8097即可观察到训练结果

    暂停与恢复

    经常需要的一个功能是,train到一个阶段,暂停/终止训练,下次训练想从断点处继续。因为visdom正常会用新图覆盖原来的图,所以要在这里读取以前的数据,然后接着绘制数据。

    第一步需要保存env,env被保存在$HOME/.visdom/ 这里,里面保存的是.json文件,如果json被删除,相应保存的env也就没了。

    保存方式如下:

    浏览器中的界面,点击manage environment——设置环境名——fork——save(这里的fork意指保存json文件,即保存在$HOME/.visdom/ 这里)。保存完并没有什么提示,而且保存界面不会消失,很奇怪,为了保险反正每次点完等一小会吧。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NNH1RBiU-1659922203818)(https://cdn.jsdelivr.net/gh/Yicen-y/Markdown_image@main/images/20210402213453.png)]

    保存完之后,从代码中获取visdom保存的数据。使用如下代码可以获得之前保存下来的数据

    vis=Visdom(port=8888)
    print(vis.get_env_list())
    # 可以得到保存的env list
    print(vis.win_exists(win="train",env="main1.0"))
    # 可以查看指定win是否存在,此处win不是保存的view的名字,可是代码中指定的win
    win_data=vis.get_window_data(win="train",env="main1.0")
    # 可以获得指定win数据,即我们想恢复的数据,但是要指定号win和env要不然会是None
    # 返回的是str数据,但是其实可以使用json来处理,因为数据本来就是储存在json中的
    pre_data= json.loads(win_data)
    # 这样就将str转换回dict,可以更方便的处理了
    xdata=pre_data["content"]["data"][0]["x"]
    ydata=pre_data["content"]["data"][0]["y"]
    # 得到横纵轴的数据,是float数据的list
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 将旧数据与新数据拼接在一起,共同绘制。。在保存在本地中的json中读取数据继续绘制。
     with open("$HOME/.visdom/main1.0.json","r") as f:predata=json.load(f)
    # 当然此处地址不能直接写$HOME,应该用正确的地址,剩下的就和上面的处理一样了
    
    • 1
    • 2
    1. 数据拼接
    ydata.append(0.5)
    vis.line(
           X=np.arange(len(ydata)),
           Y=np.array(ydata),
           opts=dict(title="try"),
           win="little"
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 配合matplotlib画折线
    import matplotlib.pyplot as plt
    from visdom import Visdom
       
    viz=Visdom(port=8888)   #(需要先在cmd中激活python -m visdom.server -port 8888)
    plt.plot([1,2,3,4])  #默认给定的是y轴数据,x轴会自动从0补全
    plt.plot([10,20,30,40])  #默认给定的是y轴数据,x轴会自动从0补全
    #plt.axis([0,1,0,3]) 可以使用这个分别指定x轴的起始终止、y轴的起始终止
    plt.title("折线")
    viz.matplot(plt)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    参考

    1. 轻松学 Pytorch–Visdom 可视化
    2. Pytorch中文网
    3. Visdom官方Github指南
    4. Visdom PyTorch可视化工具(https://www.cnblogs.com/luckforefforts/p/13736158.html#visdom-pytorch可视化工具)https://www.cnblogs.com/luckforefforts/p/13736158.html (这个帖子讲了环境的保存和重新载入)
  • 相关阅读:
    【微服务】微服务学习笔记一:微服务技术栈介绍
    当发布/订阅模式遇上.NET
    介绍两个好用又好玩的大模型工具
    开源数据库 OpenGauss 的 SQL 解析源码分析
    Word控件Aspose.Words for .NET.更新至最新v22.6,更多功能增强及漏洞修复
    7.1-卷积神经网络
    Tomcat开发配置教程
    QT_C++_数据库
    【无标题】
    windows11安装wsl
  • 原文地址:https://blog.csdn.net/weixin_44769214/article/details/126221421