pytorch使用visdom可视化loss_visdom如何将txt文件中的损失可视化-程序员宅基地

技术标签: 深度学习  visdom  

介绍

visdom是Facebook专门为PyTorch开发的一款可视化工具,其开源于2017年3月。Visdom十分轻量级,但却支持非常丰富的功能,能胜任大多数的科学运算可视化任务。
Visdom可以创造、组织和共享多种数据的可视化,包括数值、图像、文本,甚至是视频,其支持PyTorch、Torch及Numpy。用户可通过编程组织可视化空间,或通过用户接口为生动数据打造仪表板,检查实验结果或调试代码。
注意,其不支持Python的int和float类型,所以需要先转换为ndarray或tensor。

Visdom核心概念

Visdom中有两个重要概念:

env:环境。不同环境的可视化结果相互隔离,互不影响,在使用时如果不指定env,默认使用main。不同用户、不同程序一般使用不同的env。
pane:窗格。窗格可用于可视化图像、数值或打印文本等,其可以拖动、缩放、保存和关闭。一个程序中可使用同一个env中的不同pane,每个pane可视化或记录某一信息。

使用时,先创建一个env,然后在env中创建pane。如下面的viz即创建的env对象,该env的名称为test2,之后通过viz的api可以在该test2的env中创建pane。如viz.text创建了一个pane即textwindow,其id随机产生。

viz=visdom.Visdom(env=u'test2')
textwindow=viz.text('Hello World!')

当然也可以手动给viz命名,通过win这个属性可以给pane命名,这样之后可以根据这个id对pane修改。
(没有主动命名id的话也可以将变量名当作id传给win,这样也能对上一个修改)

updatetextwindow = viz.text('Hello World! More text should be here')
viz.text('And here it is', win=updatetextwindow, append=True)
#设置了id的
viz.text("this pane has win id setted",win="new pane")
viz.text('new word',win="new pane",append=True)

结果:
在这里插入图片描述

visdom的操作

viz作为一个客户端对象,可以使用常见的画图函数,包括:

line:z类似Matlab中的plot操作,用于记录某些标量的变化,如损失、准确率等
image:可视化图片,可以是输入的图片,也可以是GAN生成的图片,还可以是卷积核的信息
text:用于记录日志等文字信息,支持html格式
histgram:可视化分布,主要是查看数据、参数的分布
scatter:绘制散点图
bar:绘制柱状图
pie:绘制饼状图
在这里插入图片描述

使用时直接viz.XXX(),然后传入参数即可。
更多操作可参考visdom的github主页
这里主要介绍深度学习中常见的line、image和text操作.

上述操作的参数一般不同,但有两个参数是绝大多数操作都具备的:

win:用于指定pane的名字,如果不指定,visdom将自动分配一个新的pane。如果两次操作指定的win名字一样,新的操作将覆盖当前pane的内容,因此建议每次操作都重新指定win。
opts:选项,接收一个字典,常见的option包括title、xlabel、ylabel、width等,主要用于设置pane的显示格式。
之前提到过,每次操作都会覆盖之前的数值,但往往我们在训练网络的过程中需不断更新数值,如损失值等,这时就需要指定参数update='append’来避免覆盖之前的数值。而除了使用update参数以外,还可以使用vis.updateTrace方法来更新图,但updateTrace不仅能在指定pane上新增一个和已有数据相互独立的Trace,还能像update='append’那样在同一条trace上追加数据。

viz.line的例子

这里的例子里一个pane里面画两条线 L 1 = 2 x + 1 L_1=2x+1 L1=2x+1 L 2 = 2 x 2 − x L_2=2x^2-x L2=2x2x,X和Y的shape要一样,都是N2,每条线N个点,一个点对应(X,Y),所以两条线就是N2。

viz=visdom.Visdom(env="demo")
L=np.array([[2*x+1,2*x**2-x] for x in np.arange(1,10)])
X=np.array([[x,x] for x in np.arange(1,10)])
viz.line(X=X,Y=L,win="lossdemo",opts=dict(
    xlabel="Iteration",
    ylabel="Loss",
    title="xxmodel",
    legend=["Loss1","Loss2"]
    
))

结果:
在这里插入图片描述

visdom在训练中可视化loss

这里给了一个demo展示如何在训练的过程中动态的展示loss 的变化,考虑到目标检测中的loss通常由两个组成(位置和分类损失),这里的给的demo是同时展示位置损失、分类损失和总损失3个变化,也就是3条线的案例,并且可以按照epoch和iteration变化呈现(分别在两个不同pane)。案例中将创建pane 的代码封装出来了,然后通过命令行的方式控制是否可视化。

这里给的demo中训练部分的代码是不完全的,如果需要的话后面再补充完全。*

创建pane和更新pane的函数

#create the vis,with initialized 0
def create_vis_plot(_xlabel, _ylabel, _title, _legend):
    return viz.line(
        X=torch.zeros((1,)).cpu(),
        Y=torch.zeros((1, 3)).cpu(),
        opts=dict(
            xlabel=_xlabel,
            ylabel=_ylabel,
            title=_title,
            legend=_legend
        )
    )

#update visdom plot
def update_vis_plot(iteration, loc, conf, window1, window2, update_type,
                    epoch_size=1):
    viz.line(
        X=torch.ones((1, 3)).cpu() * iteration,
        Y=torch.Tensor([loc, conf, loc + conf]).unsqueeze(0).cpu() / epoch_size,
        win=window1,
        update=update_type
    )
    # initialize epoch plot on first iteration
    if iteration == 0:
        viz.line(
            X=torch.zeros((1, 3)).cpu(),
            Y=torch.Tensor([loc, conf, loc + conf]).unsqueeze(0).cpu(),
            win=window2,
            update=True
        )
        

这里简化了训练的一些具体代码,只是大致写下流程

import argparse

# 解析
def str2bool(v):
    return v.lower() in ("yes", "true", "t", "1")
parser = argparse.ArgumentParser(
    description='Single Shot MultiBox Detector Training With Pytorch')
parser.parser.add_argument('--visdom', default=False, type=str2bool,
                    help='Use visdom for loss visualization')
 #这里还能输入其它可解析的参数
args = parser.parse_args()
# initialize
if args.visdom:
    import visdom
    viz = visdom.Visdom()
    vis_title = 'SSD.PyTorch on ' + dataset.name
    vis_legend = ['Loc Loss', 'Conf Loss', 'Total Loss']
    iter_plot = create_vis_plot('Iteration', 'Loss', vis_title, vis_legend)
    epoch_plot = create_vis_plot('Epoch', 'Loss', vis_title, vis_legend)
    
#初始化这些dataset,model,optimizer,lr_scheduler,loss_function,dataloader,device,
#epoch_size=len(dataset) // args.batch_size
model.train()
for epoch in total_epoch:
    loss_conf=0
    loss_loc=0
    for iteration, batch in enumerate(dataloader):
        ....
        if args.visdom and iteration != 0 and (iteration % epoch_size == 0):
            update_vis_plot(epoch, loc_loss, conf_loss, epoch_plot, None,
                            'append', epoch_size)        
        images,targets=batch[0],batch[1]
        with  torch.no_grad():
            #toTensor,and to(device)
            
        optimizer.zero_grad()
        output=model(output)
        
        lossc,lossl=loss_function(output,target)
        loss = loss_l + loss_c
        loss.backword()
        optimizer.step()
        loc_loss += loss_l.data[0]
        conf_loss += loss_c.data[0]
        if args.visdom:
            update_vis_plot(iteration, loss_l.data[0], loss_c.data[0],
                            iter_plot, epoch_plot, 'append')        
    torch.save(model.state_dict(),"path/to/save.pth")

写在最后:

关于命令行解析,可以参考Python官方源码:argparse — 命令行选项、参数和子命令解析器,默认添加的arg参数类型为str,但是如果需要其它类型如int就需要更改type,如果要改为bool类型则需要自己写个解析函数传到type中,如本例那样,因为它本身自带的转换bool的机制是空字符转换为False,其它为True。

关于visdom中的其它操作组,如散点图等,可以去看看其官网案例

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yanghao201607030101/article/details/112748898

智能推荐

以MapBox为核心构建Vue地图组件库教程_vue 省份 地图组件库-程序员宅基地

文章浏览阅读951次。不多废话直接讲干货,首先我们要清楚如何写一套组件库,类似于使用vue编写的elementui,使用react编写的antdesign等,我们现在要以GIS为核心写组件库,其实原理类似。一个是组件的主体vue文件,另一个是将组件局部暴露出去的index.js文件,当然你可以再此基础上增加你想要的其他的js文件和vue文件,上面讲的两个文件是必须的。这行命令可以将你写的组件库打包成压缩文件,一般是一个dist静态目录,在进行npm发布的时候也是将这个静态的dist发布在官网上。_vue 省份 地图组件库

【控制control】四足机器人弹簧加载倒立摆(SLIP)动力学模型_【控制control】四足机器人动力学模型-slip-程序员宅基地

文章浏览阅读4.9k次,点赞5次,收藏32次。系列文章目录提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加TODO:写完再整理文章目录系列文章目录前言1.动力学建模构型方法2.四足机器人动力学模型(1)多体动力学模型【针对躯干+脚建模】方法一:VMC( Virtual Model Controller)模型方法二:SLIP模型(2)浮基单体动力学模型【针对躯干建模】【用于MPC】前言认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对四足机器人动力学模型-VMC、SLIP和浮动机体模型做个简_【控制control】四足机器人动力学模型-slip

html5手指点击速度,CPS手速测试 - 鼠标点击速度测试插件-程序员宅基地

文章浏览阅读1.2w次。CPS手速测试插件背景简介为了刺激客户的消费很多购物平台都推出来秒杀抢购的活动,在这个活动中如果你的手速慢就抢不到商品,所以有时我们会需要锻炼一下自己的手速,那如何知道自己的手速是快还是慢呢,在世界平均范围中又处于何种地步,今天小编为大家推荐一款可以检测自己手速的插件CPS手速测试。CPS手速测试插件简介CPS手速测试插件是一款可以在线测试鼠标点击速度的检测工具,它可以是1/3/5/10/15/3..._测速度插件

VLAN以及三层交换机_核心交换机如何查询vlan-程序员宅基地

文章浏览阅读2k次,点赞2次,收藏7次。VLAN以及三层交换机1、VLAN概述与优势1.1vlan概述1.2vlan优势1.3VLAN的分类Trunk概述三层交换技术1、VLAN概述与优势1.1vlan概述VLAN(Virtual Local Area Network),中文称为虚拟局城网。是一组逻辑上隔离的设备和用户。这些设备和用户不受物理位置限制,可根据部门成组等进行灵活划分,保障信息安全。同时隔绝广播信息,提升网络效能,防止广播风暴的产生。1.2vlan优势1. 限制广播域。广播域被限制在一个VLAN内,提高了网络处理能力。 2_核心交换机如何查询vlan

clearTimeout无效_cleartimeout不生效-程序员宅基地

文章浏览阅读7.3k次。如图所示clearTimeout接受id作为参数,所以检查一下是否传入的不是id因为默认情况下setTimeout方法是会返回id但有时候会返回一个setTimeout对象比如使用vsCode 开发的同学在使用setTimeout时会自动引入timer对象,此时setTimeout就会返回Timeout对象,此时只需要将对应的id传入即可或者直接将引用注掉..._cleartimeout不生效

安卓发送post请求_android post-程序员宅基地

文章浏览阅读1.6k次。在HTTP通信中使用最多的就是GET和POST了,GET请求可以获取静态页面,也可以把参数放在URL字符串的后面,传递给服务器。本文将使用标准Java接口HttpURLConnection,以一个实例演示如何使用POST方式向服务器提交数据,并将服务器的响应结果显示在Android客户端。在Android中,提供了标准Java接口HttpURLConnection和Apache接口HttpClient,为客户端HTTP编程提供了丰富的支持。将提交的数据写入Log\Log.php文件中。_android post

随便推点

探索iOS转场动画_ios 转场动画-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏3次。iOS提供图像转场动画,可实现酷炫的转场特效。动画包括:溶解、折叠、复印机、闪烁、翻页、波纹、滑动等等。_ios 转场动画

Java 本地内存 & 直接内存 & 元空间_java 本地内存和直接内存-程序员宅基地

文章浏览阅读4.1k次,点赞7次,收藏26次。Java虚拟机在执行的时候会把管理的内存分配到不同的区域,这些区域称为虚拟机内存;同时对于虚拟机没有直接管理的物理内存,也会有一定的利用,这些被利用但不在虚拟机内存的地方称为本地内存。元空间不在虚拟机中,而是使用本地内存,JVM不会再出现方法区的内存溢出问题。..._java 本地内存和直接内存

C++静态库与动态库_c++的静态库 类一定是静态的吗?-程序员宅基地

文章浏览阅读158次。C++静态库与动态库这次分享的宗旨是——让大家学会创建与使用静态库、动态库,知道静态库与动态库的区别,知道使用的时候如何选择。这里不深入介绍静态库、动态库的底层格式,内存布局等,有兴趣的同学,推荐一本书《程序员的自我修养——链接、装载与库》。什么是库库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。本质..._c++的静态库 类一定是静态的吗?

快速上手JDBC_jdbc url用于标识一个被注册的驱动程序,驱动程序管理器通过与这个url选择正确-程序员宅基地

文章浏览阅读793次。目录一、步骤二、ORM思想三、如何获取连接1.Driver接口实现类2.URL3.用户名和密码4.代码示例四、如何实现CRUD操作1.PreparedStatement 与 Statement ​2.ResultSet与ResultSetMetaData3.增删改代码示例(通用)4.查询代码示例(通用)一、步骤1.导入所需数据库的jar包,(这里以mysql为例)2.获取连接3.连接后进行CRUD操作二、ORM思想..._jdbc url用于标识一个被注册的驱动程序,驱动程序管理器通过与这个url选择正确

【安卓学习之第三方库】 Rxpay学习:支付宝微信支付-程序员宅基地

文章浏览阅读990次。█ 【安卓学习之第三方库】 Rxpay学习:支付宝微信支付█ 相关文章:【安卓学习之第三方库】库的使用2-jar类库的使用(以dom4j为例)和升级(以极光推送为例)【安卓学习之第三方库】 消息推送之极光推送【安卓学习之第三方库】 消息推送之阿里云推送 █ 读前说明:本文通过学习别人写demo,学习一些课件,参考一些博客,’学习相关知识,如果涉及侵权请告知本文只简单罗列相关的代码实现过程涉及到的逻辑以及说明也只是简单介绍,主要当做笔记,了解过程而已下载demo█ 在An_rxpay

#671. 优美!最长上升子序列、#736. 上帝的集合_优美!最长上升子序列-程序员宅基地

这篇文章是关于一个优美的问题:如何找出给定数组中最长的递增子序列。文章提出了解决这个问题的方法,并给出了相应的代码实现。