19. 网络结构搭建实例

网络结构搭建实例
1. 网络结构图
  • 图示为适应 cifar10 数据集的一个网络结构图,本文主要针对于复现如下网络结构,并介绍相关函数的使用

2. 网络结构各层参数分析
  • 复现网络结构前需要对各层的参数进行分析

    • 第一层:Input (3*32*32) --> Conv(5*5) --> output(32*32*32)得,卷积层的参数为:

      nn.Conv2d(in_channels = 3,
               out_channels = 32,
               kernel_siza = 5,
               stride = 1, # 公式计算
               padding = 2, # 公式计算
               dilation=1) # 公式计算
      
    • 第二层:MaxPooling(2*2) --> output(32*16*16)得,池化层的参数为:

      nn.MaxPool(kernel_size=2,
                 stride=2, # 公式计算
                 padding=0, # 公式计算
                 dilation=1) # 公式计算
      
    • 第三层: Conv(5*5) --> output(32*16*16),卷积层参数为

      nn.Conv2d(in_channels = 32,
               out_channels = 32,
               kernel_siza = 5,
               stride = 1, # 公式计算
               padding = 2, # 公式计算
               dilation=1) # 公式计算
      
    • 第四层:MaxPooling(2*2) --> output(32*8*8),池化层的参数为

      nn.MaxPool(kernel_size=2,
                 stride=2, # 公式计算
                 padding=0, # 公式计算
                 dilation=1) # 公式计算
      
    • 第五层:Conv(5*5) --> output(64*8*8),卷积层参数为

      nn.Conv2d(in_channels=32, 
                out_channels=64, 
                kernel_size=5,
                stride = 1, # 公式计算
                padding = 2, # 公式计算
                dilation=1) # 公式计算
      
    • 第六层:MaxPooling(2*2) --> output(64*4*4),卷积层参数为

      nn.MaxPool(kernel_size=2,
                 stride=2, # 公式计算
                 padding=0, # 公式计算
                 dilation=1) # 公式计算
      
    • 第七层:Flatten()展开并线性变换为64结点

      • nn.Flatten()层主要用于将数据展开,对于一个 (64, 4, 4)维度的数据,就是以最后一个维度优先的原则,将整个多维矩阵展平,维度变为为: (64, 4, 4)–> (1, 1024)

        nn.Flatten()
        
      • Linear(1024, 64) 全连接层将1024个数据,映射为64个数据,数据维度变换位:(1, 1024) --> (1, 64)

        nn.Linear(in_features=1024, 
                  out_features=64)
        
    • 第八层:全连接层 (1, 64) --> (1, 10),对应的线性层参数为

      nn.Linear(in_features=64,
               out_features=10)
      
3. 构建完整的网络结构
  • 创建一个基本网络架构 Modelforward函数中定义完整的数据处理流程

    class Model(nn.Module):
        def __init__(self):
            super(Model, self).__init__()
            self.conv1 = nn.Conv2d(in_channels=3, 
                                   out_channels=32, 
                                   kernel_size=5,
                                   stride=1, 
                                   padding=2,
                                   dilation=1)
            
            self.pool1 = nn.MaxPool2d(kernel_size=2,
                                      stride=2,
                                      padding=0,
                                      dilation=1)
            
            self.conv2 = nn.Conv2d(in_channels=32, 
                                   out_channels=32, 
                                   kernel_size=5,
                                   stride=1, 
                                   padding=2,
                                   dilation=1)
            
            self.pool2 = nn.MaxPool2d(kernel_size=2,
                                      stride=2,
                                      padding=0,
                                      dilation=1)
            
            self.conv3 = nn.Conv2d(in_channels=32, 
                                   out_channels=64, 
                                   kernel_size=5,
                                   stride=1, 
                                   padding=2,
                                   dilation=1)
            
            self.pool3 = nn.MaxPool2d(kernel_size=2,
                                      stride=2,
                                      padding=0,
                                      dilation=1)
            
            self.flatten = nn.Flatten()
            
            self.linear1 = nn.Linear(in_features=1024, 
                                    out_features=64)
            
            self.linear2 = nn.Linear(in_features=64, 
                                    out_features=10)
            
        def forward(self, x):
            x = self.conv1(x) # 第一层卷积
            x = self.pool1(x) # 第二层池化
            x = self.conv2(x) # 第三层卷积
            x = self.pool2(x) # 第四层池化
            x = self.conv3(x) # 第五层卷积
            x = self.pool3(x) # 第六层池化
            x = self.flatten(x) # 第七层展开
            x = self.linear1(x) # 第七层全连接
            x = self.linear2(X) # 第八层全连接
            return x
    
  • 在应用到具体的数据处理之前,可以通过创建一个基本的数据样例,来判断网络的整体输出结构是否有问题

    input = torch.ones(64, 3, 32, 32)
    model = Model()
    output = model(input)
    print(output.size()) # torch.Size([64, 10])
    
4. 使用Sequential简化代码
  • SequentialCompose类功能相仿,都是将完整的数据处理序列进行集成,从而简化代码结构

    class Model(nn.Module):
        def __init__(self):
            super(Model, self).__init__()
            self.model = nn.Sequential(
                nn.Conv2d(3, 32, 5, 1, 2, 1),
                nn.MaxPool2d(2, 2, 0, 1),
                nn.Conv2d(32, 32, 5, 1, 2, 1),
                nn.MaxPool2d(2, 2, 0, 1),
                nn.Conv2d(32, 64, 5, 1, 2, 1),
                nn.MaxPool2d(2, 2, 0, 1),
                nn.Flatten(),
                nn.Linear(1024, 64),
                nn.Linear(64, 10)
            )
    
        def forward(self, x):
            x = self.model(x)
            return x
    
    • Sequential()函数将所有的层结构操作集成起来,配建成一个完整的数据处理序列,该函数能够将冗余的代码简化,代码结构更友好
5. 使用TensorBoard可视化网络结构图
  • TensorBoard模块提供了网络结构图可视化模块 add_graph,能够细节化展示网络结构图

    with SummaryWriter("log") as writer:
        writer.add_graph(model = Model(), 
                         input_to_model=input)
    
    • model: 指定需要进行展示的Model类的实例
    • input_to_model: 指明用于传入网络结构中进行处理的数据
  • 使用命令 tensorboard --logdir=log 打开 tensorboard 的控制台

    • 选择GRAPHS视图,可以看到基于 Model 类实例构建的网络结构简图

      image-20240820135319328

    • 双击结点,并使用滚轮放大结构图,可以看到详细的参数,如图所示,x是一个 (64, 3, 32, 32)的数据作为 input

      image-20240820135446808

    • 这里同样可以查看完整的网络结构示意图,每一条脉络上都清楚的标明了当前数据在进行网络数据处理的过程中,维度数据的变换

      image-20240820135629452

6. print函数对网络的输出结果
  • 对于上述手动搭建的网络结构,在不适用 Sequential 的情况下,直接输出 Model 类的实例化

    print(Model())
    >>>
    Model(
      (conv1): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
      (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      (conv2): Conv2d(32, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
      (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      (conv3): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
      (pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      (flatten): Flatten(start_dim=1, end_dim=-1)
      (linear1): Linear(in_features=1024, out_features=64, bias=True)
      (linear2): Linear(in_features=64, out_features=10, bias=True)
    )
    
    • (xxx): layer(): 输出结果中 :的前半部分 (xxx) 是网络层在 Model 类中定义的变量名称, 后半部分 layer() 是每一层对应的具体参数
  • 对于一个使用 Sequential 简化的网络结构的输出结果如下

    print(Model())
    >>>
    Model(
      (model): Sequential(
        (0): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
        (1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
        (2): Conv2d(32, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
        (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
        (4): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
        (5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
        (6): Flatten(start_dim=1, end_dim=-1)
        (7): Linear(in_features=1024, out_features=64, bias=True)
        (8): Linear(in_features=64, out_features=10, bias=True)
      )
    )
    
    • 输出结果中表明了数据处理顺序,并给出了每一层的具体参数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥都想学的大学生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值