• 《动手学深度学习 Pytorch版》 7.4 含并行连接的网络(GoogLeNet)


    import torch
    from torch import nn
    from torch.nn import functional as F
    from d2l import torch as d2l
    
    • 1
    • 2
    • 3
    • 4

    7.4.1 Inception块

    GoogLNet 中的基本卷积块叫做 Inception 块(大概率得名于盗梦空间),由 4 条并行路径组成。

    前 3 条路径使用窗口大小为 1 × 1 1\times 1 1×1 3 × 3 3\times 3 3×3 5 × 5 5\times 5 5×5 的卷积层;

    中间 2 条路径在输入上执行 1 × 1 1\times 1 1×1 卷积,以减少通道数,从而降低模型的复杂度;

    第 4 条路径使用 3 × 3 3\times 3 3×3 的最大汇聚层;

    最后使用 1 × 1 1\times 1 1×1 卷积层改变通道数。

    回避了用哪种卷积核的问题,小孩子才做选择,Google全部都要。

    在这里插入图片描述

    class Inception(nn.Module):
        # c1--c4是每条路径的输出通道数
        def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):
            super(Inception, self).__init__(**kwargs)
            # 线路1,单1x1卷积层
            self.p1_1 = nn.Conv2d(in_channels, c1, kernel_size=1)
            # 线路2,1x1卷积层后接3x3卷积层
            self.p2_1 = nn.Conv2d(in_channels, c2[0], kernel_size=1)
            self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)
            # 线路3,1x1卷积层后接5x5卷积层
            self.p3_1 = nn.Conv2d(in_channels, c3[0], kernel_size=1)
            self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)
            # 线路4,3x3最大汇聚层后接1x1卷积层
            self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)
            self.p4_2 = nn.Conv2d(in_channels, c4, kernel_size=1)
    
        def forward(self, x):
            p1 = F.relu(self.p1_1(x))
            p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))
            p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))
            p4 = F.relu(self.p4_2(self.p4_1(x)))
            # 在通道维度上连结输出
            return torch.cat((p1, p2, p3, p4), dim=1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    7.4.2 GoogLeNet 模型

    GoogLetNet 一共使用 9 个 Inception 块和全局平均汇聚层来生成其估计值。

    • Inception块之间的最大汇聚层可降低维度

    • 第一个模块类似于AlexNet和LeNet,Inception块的组合从VGG继承

    • 全局平均汇聚层避免了在最后使用全连接层。

    在这里插入图片描述

    b1 = nn.Sequential(  # 第一个模块使用64个通道、3*3的卷积层。
        nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
    
    b2 = nn.Sequential(  # 第二个模块使用一个64个通道、1*1卷积层的卷积层和一个卷积层使用192的通道、3*3的卷积层。这对应于Inception块中的第二条路径。
        nn.Conv2d(64, 64, kernel_size=1),
        nn.ReLU(),
        nn.Conv2d(64, 192, kernel_size=3, padding=1),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
    
    b3 = nn.Sequential(  # 串联两个Inception模块
        Inception(192, 64, (96, 128), (16, 32), 32),  # 输出通道数为 64+128+32+32=256  各路径输出比例为 64:128:32:32=2:4:1:1
        Inception(256, 128, (128, 192), (32, 96), 64),  # 输出通道数为 128+192+96+64=480  各路径输出比例为 128:196:96:64=4:6:3:2
        nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
    
    b4 = nn.Sequential(  # 串联五个Inception模块 
        Inception(480, 192, (96, 208), (16, 48), 64),  # 输出通道数为 192+208+48+64=512
        Inception(512, 160, (112, 224), (24, 64), 64),  # 输出通道数为 160+224+64+64=512
        Inception(512, 128, (128, 256), (24, 64), 64),  # 输出通道数为 128+256+64+64=512
        Inception(512, 112, (144, 288), (32, 64), 64),  # 输出通道数为 112+288+64+64=528
        Inception(528, 256, (160, 320), (32, 128), 128),  # 输出通道数为 256+320+128+128=832
        nn.MaxPool2d(kernel_size=3, stride=2, padding=1))
    
    b5 = nn.Sequential(  # 串联两个Inception模块
        Inception(832, 256, (160, 320), (32, 128), 128),  # 输出通道数为 256+320+128+128=832
        Inception(832, 384, (192, 384), (48, 128), 128),  # 输出通道数为 384+384+128+128=1024
        nn.AdaptiveAvgPool2d((1,1)),
        nn.Flatten())
    
    net = nn.Sequential(b1, b2, b3, b4, b5, nn.Linear(1024, 10))
    
    • 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
    X = torch.rand(size=(1, 1, 96, 96))
    for layer in net:
        X = layer(X)
        print(layer.__class__.__name__,'output shape:\t', X.shape)
    
    • 1
    • 2
    • 3
    • 4
    Sequential output shape:	 torch.Size([1, 64, 24, 24])
    Sequential output shape:	 torch.Size([1, 192, 12, 12])
    Sequential output shape:	 torch.Size([1, 480, 6, 6])
    Sequential output shape:	 torch.Size([1, 832, 3, 3])
    Sequential output shape:	 torch.Size([1, 1024])
    Linear output shape:	 torch.Size([1, 10])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    7.4.3 训练模型

    lr, num_epochs, batch_size = 0.1, 10, 128
    train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96)  # 输入宽高降为96以减小计算量
    d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())  # 大约需要二十分钟,慎跑
    
    • 1
    • 2
    • 3
    loss 0.297, train acc 0.887, test acc 0.861
    542.8 examples/sec on cuda:0
    
    • 1
    • 2

    在这里插入图片描述

    练习

    (1)GoogLeNet 有一些后续版本如下,尝试实现并运行它们,并观察实验结果。

    a. 添加批量规范层
    
    b. 对 Inception 进行调整
    
    c. 使用标签平滑进行模型正则化
    
    d. 加入残差连接
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (2)使用 GoogLeNet 的最小图像大小是多少?

    最小图像大小应该是 3 × 3 3\times 3 3×3

    因为 5 × 5 5\times 5 5×5卷积核、2填充、1步幅至少需要 3 × 3 3\times 3 3×3大小的图像才能使输出大于零


    (3)将AlexNet、VGG 和 NiN 的模型参数大小与 GoogLeNet 进行比较。后两个网络架构是如何显著减少模型参数大小的?

    1 × 1 1\times 1 1×1 的卷积数取代全连接层让参数变小。

  • 相关阅读:
    jmeter(三十三):阶梯线程组Stepping Thread Group,并发线程Concurrency Thread Group
    我开的游戏经常被攻击该怎么办,云服务器陷入黑洞了要怎么处理,有没有什么好的办法彻底解决攻击
    Idea插件整理
    二十二、SpringBoot + Jwt + Vue 权限管理系统 (3)
    vue 预览视频
    Linux中断和中断处理 “上部分”
    课程32:.Net Core Web API部署IIS
    .NET开源且免费的Windows远程桌面管理软件
    前端性能优化方法与实战07 平台实践:如何从 0 到 1 搭建前端性能平台
    7. SQL中函数的简介
  • 原文地址:https://blog.csdn.net/qq_43941037/article/details/133120824