第五节:基于Pytorch的相关可视化

第五节:基于Pytorch的相关可视化

在Pytorch发布后,网络及训练过程的可视化工具也相应的被开发出来来帮助用户监督所建立的模型的结构和训练过程

本章将讲解HiddenLayer库,HiddenLayer库是一个非常简单、已与扩展、可用于可视化深度学习训练过程及网络结构的、可以喝Jupyter Notebook完美兼容的库
HiddenLayer开发的初衷是对于小型的项目,没有必要使用TensorBoard这类复杂的高级工具来进行检测,所以HiddenLayer是一个轻量化、小型的可视化工具,除了对Pytorch的支持外,HiddenLayer还支持Keras、TensorFlow等高级工具

此外我们还会介绍PyTorchViz这个用于创建PyTorch执行图和跟踪的可视化图库,这个库非常的请谅解,我们可以使用其提供的make_dot函数来可视化网络结构

tensorboardX是PyTorch用于链接TensorFlow的tensorboard可视化工具的库,通过tensorboardX我们可以使用深度学习可视化神奇tensorboard来监督、查看PyTorch的深度学习网络的训练过程,并且tensorboardX库非常容易使用

最后我们会介绍Visdom库,Visdom库是FB为PyTorch专门开发的一款可视化工具,该库使用时较为灵活,可用于创建、组织和共享实时丰富数据的可视化图像,可以直接对Tensor进行操作,也可以直接操作Numpy库,能够胜任大部分数据可视化任务

通常来说我们以文本的形式来展示网络的结构是非常不利于理解的,因为层与层之间之间会具有联系,例如ResNet

想要直观的了解网络的结构需要求我们以图片的形式进行展示

此外我们能够直观的检测网络训练过程将会帮助我们更好的进行训练

因此我们接下来可视化分为两部分:可视化网络以及可视化训练过程

准备网络和数据

我们首先定义一个简单的CNN来对手写数字进行分类,我们接下来的可视化都将基于这个网络来进行

首先导包

import torch
import torch.nn as nn
import torchvision
import torchvision.utils as vutils
from torch.optim import SGD
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
import numpy as np

接下来导入数据集并进行加载

train_data=torchvision.datasets.MNIST(root='./data/MNIST/',
                                      train=True,
                                      transform=torchvision.transforms.ToTensor(),
                                      download=False)
train_loader=Data.DataLoader(dataset=train_data,shuffle=True,num_workers=2,batch_size=128)

test_data=torchvision.datasets.MNIST(root='./data/MNIST/',train=False,transform=torchvision.transforms.ToTensor(),
                                    download=False)
test_data_X=test_data.data.type(torch.FloatTensor) / 255.0
test_data_X=torch.unsqueeze(input=test_data_X,dim=1)
test_data_y=test_data.targets
for step,(batch_x,batch_y) in enumerate(train_loader):
    if step>0:
        break
print(len(train_loader))
print(batch_x.shape)
print(batch_y.shape)
print(test_data_X.shape)
print(test_data_y.shape)
>>>
469
torch.Size([128, 1, 28, 28])
torch.Size([128])
torch.Size([10000, 1, 28, 28])
torch.Size([10000])

接下来定义并实例化一个网络

class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet,self).__init__()
        self.conv1=nn.Sequential(\
                                nn.Conv2d(in_channels=1,out_channels=16,kernel_size=(3,3),stride=1,padding=1),
                                nn.ReLU(),
                                nn.AvgPool2d(kernel_size=(2,2),stride=2))
        self.conv2=nn.Sequential(\
                                nn.Conv2d(in_channels=16,out_channels=32,kernel_size=(3,3),stride=1,padding=1),
                                nn.ReLU(),
                                nn.MaxPool2d(kernel_size=(2,2),stride=2))
        self.fc=nn.Sequential(\
                              nn.Linear(in_features=32*7*7,out_features=128),
                              nn.ReLU(),
                              nn.Linear(in_features=128,out_features=64),
                              nn.ReLU())
        self.predict=nn.Linear(in_features=64,out_features=10)
        
    def forward(self,x):
        x=self.conv1(x)
        x=self.conv2(x)
        x=self.fc(x)
        output=self.predict(x)
        return x
    
MyConvNet=ConvNet()
print(MyConvNet)
>>>
ConvNet(
  (conv1): Sequential(
    (0): Conv2d(1, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU()
    (2): AvgPool2d(kernel_size=(2, 2), stride=2, padding=0)
  )
  (conv2): Sequential(
    (0): Conv2d(16, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=(2, 2), stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (fc): Sequential(
    (0): Linear(in_features=1568, out_features=128, bias=True)
    (1): ReLU()
    (2): Linear(in_features=128, out_features=64, bias=True)
    (3): ReLU()
  )
  (predict): Linear(in_features=64, out_features=10, bias=True)
)

可视化网络

HiddenLayer可视化网络

接下里我们使用HiddenLayer库来可视化网络

HiddenLayer库中包含一个build_graph函数可以方便的帮助我们进行可视化

HiddenLayer可视化的原理就是跟踪一个输入,然后绘制出该输入经过的结构,即网络的结构

 import hiddenlayer as hl
MyConvNet_graph=hl.build_graph(MyConvNet,torch.zeros(size=[1,1,28,28]))
MyConvNet_graph.theme=hl.graph.THEMES['blue'].copy()
MyConvNet_graph.save(path='./MyConvNetArchitect.png',format='png')

上面的程序中我们使用了Hidden、

Layer的build_graph函数,为其传入需要绘制结构的网络,接下来我们又传入了一个可用于网络计算的输入x来进行追踪

我们又设置需要绘制的图像的主题为蓝色

最后我们使用svae函数来保存绘制的图像,需要为save函数传入保存的路径和格式即可

得到的结构图如下

在这里插入图片描述

PyTorchViz可视化

除了使用HiddenLayer来可视化网络以外,我们还可以使用PyTorchViz来可视化网络

PyTorchViz主要使用make_dot函数来进行绘制,其原理和HiddenLayer相同,都是对输入进行追踪

不过不同的是HiddenLayer对输入的追踪集成到了函数内部,PyTorchViz则需要通过PyTorch来进行追踪

from torchviz import make_dot
x=torch.randn(size=(1,1,28,28)).requires_grad_(True)
y=MyConvNet(x)
MyConvNetVis=make_dot(y,params=dict(list(MyConvNet.named_parameters())+[('x',x)]))
MyConvNetVis.format='png'
MyConvNetVis.directory='./'
MyConvNetVis.view()

这里我们首先通过PyTorch初始化了一个输入x,并指明需要计算其梯度,接下来进行计算得到其输出

然后我们使用make_dot类进行绘图,我们需要指定输出和网络中所有的参数来帮助我们绘图,即这列的list(MyConvNet.named_parameters())+['x',x]

我们指定format属性来设置格式,指定directory来指定路径,最后使用view来显示图像

得到的效果如下

在这里插入图片描述

可视化训练过程

网络结构可视化主要帮助我们理解搭建的网络或者搭建网络时存在的错误

而对训练过程进行可视化则是为了监督训练过程、增加对网络的理解等等

接下来我们将使用tensorboardX和HiddenLayer库来可视化我们的训练过程

tensorboardX可视化训练过程

tensorboard是TensorFlow的可视化工具,能够帮助我们对TensorFlow搭建出的网络进行较好的可视化

而PyTorch本身却并没有自带的可视化工具,因此tensorboardX是基于tensorboard为PyTorch开发的,调用tensorboard的库

tensorboard可视化训练过程的基本思想是创建一个编写器来对每一次训练进行记录(Summary),我们每次向其中添加本次训练的参数即可

tensorboardX常用的库

tensorboardX库中常用的功能和调用方式如下

函数功能用法
SummaryWrite创建编写器,保存日志writer=SummaryWrite()
weiter.add_scalar()添加标量writer.add_scalar(‘myscalar’,value,iteration)
writer.add_image()添加图像writer.add_image(‘imresult’,x,iteration)
writer.addhistogram()添加直方图writer.add_histogram(‘hist’,array,iteration)
writer.add_graph()添加网络结构writer.add_graph(model,input_to_model=None)
writer.add_audio()添加音频writer.add_audio(tag,audio,iteration,sample_true)
writer.add_text()添加文本weiter.add_text(tag,text_string,global_step=None)

上面列举了常用的可视化方法,如在图像中添加标量,文本,音频,直方图等等

下面将使用上面的网络来进行可视化

tensorboardX进行可视化

from tensorboardX import SummaryWriter
SummaryWriter=SummaryWriter(log_dir='./log')
optimizer=torch.optim.Adam(params=MyConvNet.parameters(),lr=0.0003,betas=(0.9,0.999),eps=1e-8)
lossFunc=torch.nn.CrossEntropyLoss()
train_loss=0
print_step=100
for epoch in range(5):
    for step,(batch_x,batch_y) in enumerate(train_loader):
        output=MyConvNet(batch_x)
        loss=lossFunc(output,batch_y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        train_loss+=loss
        niter=epoch*len(train_loader)+step+1
        if niter % print_step ==0:
            SummaryWriter.add_scalar('train loss',train_loss.item()/niter,global_step=niter)
            output=MyConvNet(test_data_X)
            _,pre_lab=torch.max(output,1)
            acc=accuracy_score(test_data_y,pre_lab)
            SummaryWriter.add_scalar('test acc',acc.item(),niter)
            batch_x_image=vutils.make_grid(batch_x,nrow=12)
            SummaryWriter.add_image('train image sample',batch_x_image,niter)
            for name,param in MyConvNet.named_parameters():
                SummaryWriter.add_histogram(name,param.data)
        if niter%500==0:
            print('in training')

这里我们在训练的过程中每100轮训练进行一次记录,我们使用add_scalar记录需要保存的常数及其tag/标签

对于add_scalar函数,我们使用的时候需要指定保存的tag,保存的对象的值和当前值在全局的训练轮次

最后我们对数字进行了可视化,首先使用torchvision.utils中的make_grid生成了数字的网格图

然后使用add_image方法将图像添加到我们的编写器中

查看tensorboardX可视化的结果

接下来我们就需要查看可视化的结果,上面我们将日志保存到了log文件夹下

我们生成的是tensorboardX得到的编写器是一个需要使用tensorboard来读取的文件

在这里插入图片描述

我们在命令行中输入如下语句,就会得到一个保存了所有内容的本地网页

(pytorchlearning) jack@jack-Alienware-Area-51m:~/PytorchLearning$ tensorboard --logdir='./log/'
>>>
TensorBoard 1.13.1 at http://jack-Alienware-Area-51m:6006 (Press CTRL+C to quit)

打开这个网页其中就是我们可视化的结果

scalar栏目下就是我们记录的所有的常量

在这里插入图片描述

在这里插入图片描述

虽然tensorboard可视化训练过程的效果很强大,但是对于小型的网络进行可视化就很繁琐了

HiddenLayer可视化训练过程

下面我们将使用HiddenLayer库进行可视化,通常对于小型网络的可视化我们都是使用HiddenLayer进行的

使用HiddenLayer进行可视化实际上和使用tensorboard进行可视化的过程都是大同小异的

%%time
import hiddenlayer as hl
import time
MyConvNet=ConvNet()
optimzer=torch.optim.Adam(MyConvNet.parameters(),lr=0.0003)
lossFunc=nn.CrossEntropyLoss()
history1=hl.History()
canvas1=hl.Canvas()
print_step=100
for epoch in range(5):
    for step,(batch_x,batch_y) in enumerate(train_loader):
        output=MyConvNet(batch_x)
        loss=lossFunc(output,batch_y)
        optimzer.zero_grad()
        loss.backward()
        optimzer.step()
        if step%100==0:
            output=MyConvNet(test_data_X)
            _,pre_lab=torch.max(output,1)
            acc=accuracy_score(test_data_y,pre_lab)
            history1.log((epoch,step),train_loss=loss,test_acc=acc,hidden_weight=MyConvNet.fc[2].weight)
with canvas1:
    canvas1.draw_plot(history1['train_loss'])
    canvas1.draw_plot(history1['test_acc'])
    canvas1.draw_image(history1['hidden_weight'])
>>>
CPU times: user 4min 2s, sys: 20 s, total: 4min 22s
Wall time: 34.4 s

我们训练的过程都是大同小异的,不同之处在于我们一开始初始化了HiddenLayer的History对象来记录训练数据,以及初始化了Canvas对象来进行绘图,我们在训练的时候调用history对象的log方法来保存日志,最后调用canvas的draw_plot方法来绘制图像

在这里插入图片描述

Visdom可视化

Visdom是FB专门为PyTorch开发的可视化工具,这个库非常灵活,可以用于创建、组织和共享实时丰富数据的可视化

Visdom的可视化是基于网页实现的,能够让用户以多种方式来进行交互的可视化,从而对数据的可视化理解更加直观

可视化对象支持PyTorch中的tensor和Numpy的数组

Visdom中常用的可视化结构函数和功能如下

可视化函数功能
vis.image可视化图像
vis.images可视化一个batch的图像或一个图像列表
vis.text可视化文本
vis.video播放视频
vis.audio播放音频
vis.matplot可视化matplot中的图像
vis.scatter可视化散点图
vis.line可视化线图
vis.stem可视化茎叶图
vis.heatmap可视化热力图
vis.bar可视化条形图
vis.histogram可视化直方图
vis.boxplot可视化箱型图
vis.surf可视化曲面图
vis.contour可视化等高线图
vis.quiver可视化箭头图
vis.mesh可视化网格图

我们下面将使用鸢尾花数据集来进行讲解

我们首先导包

from visdom import Visdom
from sklearn.datasets import load_iris

此外,我们首先需要在命令行执行如下命令来开启visdom后台服务器,来实现实时绘图,绘图期间需要保持该命令行终端开启

我们执行命令后就会得到一个本地的地址,例如我这里是http://localhost:8097,我们在浏览器中打开就可以看到实时绘制的图像

python -m visdom.server
>>>
(pytorchlearning) jack@jack-Alienware-Area-51m:~$ python -m visdom.server
/home/jack/anaconda3/envs/pytorchlearning/lib/python3.7/site-packages/visdom/server.py:39: DeprecationWarning: zmq.eventloop.ioloop is deprecated in pyzmq 17. pyzmq now works with default tornado and asyncio eventloops.
  ioloop.install()  # Needs to happen before any tornado imports!
It's Alive!
INFO:root:Application Started
You can navigate to http://localhost:8097

绘制二维/三维散点图

我们使用Visdom绘图的时候首先需要实例化一个Visdom对象,接下来调用Visdom对象的scatter方法来进行绘图

需要注意的是,scatter方法能够自动的识别我们传入的是二维数据还是三维数据,从而自动的生成二维点与三维点

vis = Visdom()
vis.scatter(iris_x[:,0:2],Y=iris_y+1,win='windows1',env='main')
vis.scatter(iris_x[:,0:3],Y=iris_y+1,win='3D 散点图',env='main',opts=dict(markersize=4,xlabel='特征1',ylabe='特征2'))

需要注意的是,Visdom将一个网页分为了多个windows和environment,我们在绘制图像的时候还需要指定对应的窗口和环境,此外我们在绘制三维散点图的时候指定opts参数来设定点的格式

执行后打开网页就会看到实时渲染的图片,我们能够看到上方的选项卡中有环境的选择,而我们的两个图片都在各自的窗口中,我们使用鼠标就可以进行交互

在这里插入图片描述

绘制折线图

下面我们将绘制折线图,绘制折线图主要使用的是visdom对象的line方法

Sigmoid=nn.Sigmoid()
ReLu=nn.ReLU()
Tanh=nn.Tanh()
x=torch.linspace(start=-6,end=6,steps=100).view((-1,1))
plot_y=torch.cat((Sigmoid(x),ReLu(x),Tanh(x)),dim=1)
plot_x=torch.cat((x,x,x),dim=1)
vis.line(Y=plot_y,X=plot_x,win="line plot",env='new',
        opts=dict(dash=np.array(['soild','dash','dashshot']),
                 legend=['Sigmoid','ReLu','Tanh']))

这里我们指定图像绘制在新环境new中,同事指定线条样式和图例

在这里插入图片描述

绘制茎叶图

下面我们使用visdom对象的stem方法绘制一个茎叶图

x=torch.linspace(-6,6,300).view((-1,1))
y1=torch.sin(x)
y2=torch.cos(x)
plot_x=torch.cat((x,x),dim=1)
plot_y=torch.cat((y1,y2),dim=1)
vis.stem(X=plot_y,Y=plot_x,win='stem plot',env='stem',
        opts=dict(legend=['sin','cos'],title='茎叶图'))

需要注意的是吗,这里有一个坑就是我们的stem函数中X是我们要绘制的图像的输入,我们需要输入plot_y,Y则是我们需要输入的ploy_x

0可视化的结果如下

在这里插入图片描述

绘制热力图

我们调用heatmap来绘制热力图

iris_corr=torch.from_numpy(np.corrcoef(iris_x,rowvar=False))
vis.heatmap(X=iris_corr,win='new',env='heatmap',
           opts=dict(rownames=['x1','x2','x3','x4'],
                    columnnames=['x1','x2','x3','x4'],
                    title='热力图'))

我们首先使用numpy的corrcoef函数来求出输入的相关系数矩阵,接下来使用heatmap来进行可视化

在这里插入图片描述

可视化图像

我们下面分别使用image和images两个接口来可视化单张图像和一个batch的图像

vis.image(batch_x[0,:,:,:],win='one image',env='Image',
         opts=dict(title='单张图像'))
vis.images(batch_x,win='many images',env='Image',
          nrow=16,opts=dict(title='多张图像'))

可视化结果如下

在这里插入图片描述

可视化文本

我们使用text接口来可视化文本

texts='A flexible tool for creating, organizaing, and sharing visualization of live, rich data. Supports Torch and Numpu'
vis.text(texts,win='texts plot',env='Text',opts=dict(title='可视化文本'))

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值