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


    基于pytorch的网络结构可视化

    前言

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

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

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

    目录结构

    1. 安装:

    安装tensorboardX

    ​ 安装可视化库:

    pip install tensorboardX
    
    • 1

    ​ 当然建议指定镜像源

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

    安装torchkeras

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

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

    2. summary使用方法:

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

    ​ 首先导入库:

    from torchkeras import summary
    
    • 1

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

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

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

    注意:

    • 第一个参数值为模型对象
    • 第二个参数值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
    --------------------------------------------------------------------------
    
    • 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

    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    ​ 那么,以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()
    
    • 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

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

    在这里插入图片描述

    可视化

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

    在这里插入图片描述

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

    tensorboard --logdir=runs
    
    • 1

    在这里插入图片描述

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

    在这里插入图片描述

    在这里插入图片描述

    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 %
    
    • 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
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
  • 相关阅读:
    65、内网安全-域环境&工作组&局域网探针方案
    下载node-sass
    C++ Reference: Standard C++ Library reference: C Library: cctype: ispunct
    Java八股文总结(二)
    [附源码]java毕业设计校园闲置物品交易
    如何使用Python和Plotly绘制3D图形
    44_ue4进阶末日生存游戏开发[左键添加功能与丢弃功能]
    【MySQL篇】第二篇——库的操作
    1.1.3开发基础-硬件-示波器
    从官方文档中探索 Android App 架构演进的方向
  • 原文地址:https://blog.csdn.net/weixin_46676835/article/details/130898570