pytroch实战12:基于pytorch的网络结构可视化

基于pytorch的网络结构可视化

前言

​ 之前实现了一些常见的网络架构,但是有些网络架构并没有细说,并且网络传输过程中shape的变化也很少谈及过。

​ 除此之外,前面的实现很少涉及到可视化的内容,比如损失值的可视化、网络结构的可视化。

​ 所以本期博客就是补充一下这几点。

目录结构

文章目录

    • 基于pytorch的网络结构可视化
      • 1. 安装:
      • 2. summary使用方法:
      • 3. tensorboardX使用方法:
      • 4. 总结

1. 安装:

安装tensorboardX

​ 安装可视化库:

pip install tensorboardX

​ 当然建议指定镜像源:

pip install tensorboardX -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

安装torchkeras

​ 如果你想要使用tensorflow库的summary,可以安装这个库:

pip install torchkeras -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

2. summary使用方法:

​ 还记得LeNet5这个网络架构吗,我下面演示的代码都是基于这个代码来的,不清楚的可以看这篇文章。

​ 首先导入库:

from torchkeras import summary

​ 当然,其它的代码,比如创建模型、定义优化器等我们不说。只说如何使用这个方法。

​ summary使用很简单,直接按照下面的格式使用即可:

# 打印summary值
print(summary(model,input_shape=(1,28,28)))

注意:

  • 第一个参数值为模型对象
  • 第二个参数值input_shape为输入的shape大小,比如这里用的MNIST数据集,所以shape=[1,28,28]
  • 需要保证model和input_shape在同一设备中,比如上面model不能放入GPU中,或者要么将input_shape改为GPU中的变量

​ 打印的结果值:

--------------------------------------------------------------------------
Layer (type)                            Output Shape              Param #
==========================================================================
Conv2d-1                             [-1, 6, 28, 28]                  156
Sigmoid-2                            [-1, 6, 28, 28]                    0
MaxPool2d-3                          [-1, 6, 14, 14]                    0
Conv2d-4                            [-1, 16, 10, 10]                2,416
Sigmoid-5                           [-1, 16, 10, 10]                    0
MaxPool2d-6                           [-1, 16, 5, 5]                    0
Linear-7                                   [-1, 120]               48,120
Sigmoid-8                                  [-1, 120]                    0
Linear-9                                    [-1, 84]               10,164
Sigmoid-10                                  [-1, 84]                    0
Linear-11                                   [-1, 10]                  850
==========================================================================
Total params: 61,706
Trainable params: 61,706
Non-trainable params: 0
--------------------------------------------------------------------------
Input size (MB): 0.002991
Forward/backward pass size (MB): 0.111404
Params size (MB): 0.235390
Estimated Total Size (MB): 0.349785
--------------------------------------------------------------------------
--------------------------------------------------------------------------
Layer (type)                            Output Shape              Param #
==========================================================================
Conv2d-1                             [-1, 6, 28, 28]                  156
Sigmoid-2                            [-1, 6, 28, 28]                    0
MaxPool2d-3                          [-1, 6, 14, 14]                    0
Conv2d-4                            [-1, 16, 10, 10]                2,416
Sigmoid-5                           [-1, 16, 10, 10]                    0
MaxPool2d-6                           [-1, 16, 5, 5]                    0
Linear-7                                   [-1, 120]               48,120
Sigmoid-8                                  [-1, 120]                    0
Linear-9                                    [-1, 84]               10,164
Sigmoid-10                                  [-1, 84]                    0
Linear-11                                   [-1, 10]                  850
==========================================================================
Total params: 61,706
Trainable params: 61,706
Non-trainable params: 0
--------------------------------------------------------------------------
Input size (MB): 0.002991
Forward/backward pass size (MB): 0.111404
Params size (MB): 0.235390
Estimated Total Size (MB): 0.349785
--------------------------------------------------------------------------

3. tensorboardX使用方法:

​ 相比于summary,我个人觉得tensorboardX更好用,因为它可以将结果可视化,并且操作也十分简单。

代码中使用流程与举例

​ 首先,标准的使用流程为:

# 1. 导入库
from tensorboardX import SummaryWriter

# 2. 创建对象,
writer = SummaryWriter() 
	# 路径一般默认,不过也可以指定
	# 指定路径: writer = SummaryWriter('.\temp')
	
# 3. 可视化1: 可视化某个变量的值,一般为损失值
writer.add_scalar('变量名字',存储的值,序号)
	# 其中序号指的是损失值的序号,比如1、2、3这样的,目的是区分不同值
    # 日志记录: 序号 --- 变量名字 --- 存储值

# 4. 可视化2:可视化模型结构
writer.add_graph(model,input_to_model=batch_data)
	# 第一个参数为模型
	# 第二个参数为输入的shape,一般直接用batch_data即可
	# 注意两者必须在同一设备中,和summary类似

# 5. 关闭可视化
writer.close()

​ 那么,以LeNet5举个例子:

# 导入可视化
from tensorboardX import SummaryWriter

# 创建模型
class LeNet(nn.Module):
	...
	
# 下载数据集或者加载数据集
...
# 加载数据: 分批次,每批256个数据
...
# 创建模型
model = LeNet()
# 模型放入GPU中
...
# 定义损失函数、优化器
...

# *****初始化可视化对象*****
writer = SummaryWriter() # 路径一般默认,不过也可以指定

# 开始训练
x = 0  # 用于指定序号
for i in range(10):
	...
    for j,(batch_data,batch_label) in enumerate(train_loader):
        ...
        if (j + 1) % 200 == 0:
			...
            # 可视化1:一般添加loss值
            writer.add_scalar('200_step_loss',loss_temp / 200,x)
            x += 1
            ...

# 可视化2:模型结构
writer.add_graph(model,input_to_model=batch_data)
# 关闭可视化
writer.close()

​ 对于上面需要说明的一点:(图画的有点抽象,见谅)

pytroch实战12:基于pytorch的网络结构可视化_第1张图片

可视化

​ 当上述代码云心完毕后,如果你没有更改默认路径,那么在所属文件夹会出现一个名为runs的文件夹:

pytroch实战12:基于pytorch的网络结构可视化_第2张图片

​ 那么,你打开Windows的cmd,进入当前目录,运行下面的代码:

tensorboard --logdir=runs

pytroch实战12:基于pytorch的网络结构可视化_第3张图片

​ 然后,将给出的网址复制到浏览器打开(此时不要关闭cmd窗口):

pytroch实战12:基于pytorch的网络结构可视化_第4张图片

pytroch实战12:基于pytorch的网络结构可视化_第5张图片

4. 总结

​ 网络结构的可视化操作还是比较简单的,而且效果也非常不错。如果你要做ppt或者其它的,建议可以试一试。

LeNet5案例完整代码(需要根据需求修改注释)

# author: baiCai
# 导包
import time
import torch
from torch import nn
from torch import optim
from torch.utils.data import DataLoader
from torchvision.datasets import MNIST
import torchvision.transforms as transforms
# 导入可视化
from tensorboardX import SummaryWriter
from torchkeras import summary

# 创建模型
class LeNet(nn.Module):
    def __init__(self):
        super(LeNet,self).__init__()
        # 定义模型
        self.features = nn.Sequential(
            nn.Conv2d(in_channels=1,out_channels=6,kernel_size=(5,5),stride=1,padding=2),
            nn.Sigmoid(),
            nn.MaxPool2d(kernel_size=2,stride=2),
            nn.Conv2d(in_channels=6,out_channels=16,kernel_size=(5,5),stride=1),
            nn.Sigmoid(),
            nn.MaxPool2d(kernel_size=2,stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Linear(in_features=400, out_features=120),
            nn.Sigmoid(),
            nn.Linear(in_features=120, out_features=84),
            nn.Sigmoid(),
            nn.Linear(in_features=84, out_features=10)
        )

    def forward(self,x):
        # 定义前向算法
        x = self.features(x)
        # print(x.shape)
        x = torch.flatten(x,1)
        # print(x.shape)
        result = self.classifier(x)
        return result

# 下载数据集或者加载数据集
train_dataset = MNIST(root='../data',train=True,transform=transforms.ToTensor(),download=True)
test_dataset = MNIST(root='../data',train=False,transform=transforms.ToTensor())
# 加载数据: 分批次,每批256个数据
batch_size = 32
train_loader = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)
test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=False)
# start time
start_time = time.time()
# 创建模型
model = LeNet()
# 模型放入GPU中
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = model.to(device)
# 定义损失函数
loss_func = nn.CrossEntropyLoss()
loss_list = [] # 用来存储损失值
# 定义优化器
SGD = optim.Adam(params=model.parameters(),lr=0.001)
# 初始化可视化对象
writer = SummaryWriter() # 路径一般默认,不过也可以指定
# 打印summary值
# print(summary(model,input_shape=(1,28,28)))
# 训练指定次数
x = 0
for i in range(10):
    loss_temp = 0 # 定义一个损失值,用来打印查看
    # 其中j是迭代次数,data和label都是批量的,每批32个
    for j,(batch_data,batch_label) in enumerate(train_loader):
        # 启用GPU
        batch_data,batch_label = batch_data.cuda(),batch_label.cuda()
        # 清空梯度
        SGD.zero_grad()
        # 模型训练
        prediction = model(batch_data)
        # 计算损失
        loss = loss_func(prediction,batch_label)
        loss_temp += loss
        # BP算法
        loss.backward()
        # 更新梯度
        SGD.step()
        if (j + 1) % 200 == 0:
            print('第%d次训练,第%d批次,损失值: %.3f' % (i + 1, j + 1, loss_temp / 200))
            # 可视化1:一般添加loss值
            writer.add_scalar('200_step_loss',loss_temp / 200,x)
            x += 1
            loss_temp = 0
# end_time
end_time = time.time()
print('训练花了: %d s' % int((end_time-start_time)))
# 可视化2:模型结构
writer.add_graph(model,input_to_model=batch_data)
# 关闭可视化
writer.close()

# 使用GPU: 训练花了: 124 s
# 不适用GPU:训练花了: 160 s
# 测试
# correct = 0
# for batch_data,batch_label in test_loader:
#     batch_data, batch_label = batch_data.cuda(), batch_label.cuda()
#     prediction = model(batch_data)
#     predicted = torch.max(prediction.data, 1)[1]
#     correct += (predicted == batch_label).sum()
# print('准确率: %.2f %%' % (100 * correct / 10000)) # 因为总共10000个测试数据

#  准确率: 11.35 %

你可能感兴趣的:(pytorch学习笔记,pytorch,深度学习,python)