【深度学习笔记】 5_9 含并行连结的网络(GoogLeNet)

注:本文为《动手学深度学习》开源内容,部分标注了个人理解,仅为个人学习记录,无抄袭搬运意图

5.9 含并行连结的网络(GoogLeNet)

在2014年的ImageNet图像识别挑战赛中,一个名叫GoogLeNet的网络结构大放异彩 [1]。它虽然在名字上向LeNet致敬,但在网络结构上已经很难看到LeNet的影子。GoogLeNet吸收了NiN中网络串联网络的思想,并在此基础上做了很大改进。在随后的几年里,研究人员对GoogLeNet进行了数次改进,本节将介绍这个模型系列的第一个版本。

5.9.1 Inception 块

GoogLeNet中的基础卷积块叫作Inception块,得名于同名电影《盗梦空间》(Inception)。与上一节介绍的NiN块相比,这个基础块在结构上更加复杂,如图5.8所示。

在这里插入图片描述

图5.8 Inception块的结构

由图5.8可以看出,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卷积来减少输入通道数,以降低模型复杂度。第四条线路则使用 3 × 3 3\times 3 3×3最大池化层,后接 1 × 1 1\times 1 1×1卷积层来改变通道数。4条线路都使用了合适的填充来使输入与输出的高和宽一致。最后我们将每条线路的输出在通道维上连结,并输入接下来的层中去。

Inception块中可以自定义的超参数是每个层的输出通道数,我们以此来控制模型复杂度。

import time
import torch
from torch import nn, optim
import torch.nn.functional as F

import sys
sys.path.append("..") 
import d2lzh_pytorch as d2l
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

class Inception(nn.Module):
    # c1 - c4为每条线路里的层的输出通道数
    def __init__(self, in_c, c1, c2, c3, c4):
        super(Inception, self).__init__()
        # 线路1,单1 x 1卷积层
        self.p1_1 = nn.Conv2d(in_c, c1, kernel_size=1)
        # 线路2,1 x 1卷积层后接3 x 3卷积层
        self.p2_1 = nn.Conv2d(in_c, c2[0], kernel_size=1)
        self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)
        # 线路3,1 x 1卷积层后接5 x 5卷积层
        self.p3_1 = nn.Conv2d(in_c, c3[0], kernel_size=1)
        self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)
        # 线路4,3 x 3最大池化层后接1 x 1卷积层
        self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)
        self.p4_2 = nn.Conv2d(in_c, 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)  # 在通道维上连结输出

5.9.2 GoogLeNet模型

GoogLeNet跟VGG一样,在主体卷积部分中使用5个模块(block),每个模块之间使用步幅为2的 3 × 3 3\times 3 3×3最大池化层来减小输出高宽。第一模块使用一个64通道的 7 × 7 7\times 7 7×7卷积层。

b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),
                   nn.ReLU(),
                   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))

第二模块使用2个卷积层:首先是64通道的 1 × 1 1\times 1 1×1卷积层,然后是将通道增大3倍的 3 × 3 3\times 3 3×3卷积层。它对应Inception块中的第二条线路。

b2 = nn.Sequential(nn.Conv2d(64, 64, kernel_size=1),
                   nn.Conv2d(64, 192, kernel_size=3, padding=1),
                   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))

第三模块串联2个完整的Inception块。第一个Inception块的输出通道数为 64 + 128 + 32 + 32 = 256 64+128+32+32=256 64+128+32+32=256,其中4条线路的输出通道数比例为 64 : 128 : 32 : 32 = 2 : 4 : 1 : 1 64:128:32:32=2:4:1:1 64:128:32:32=2:4:1:1。其中第二、第三条线路先分别将输入通道数减小至 96 / 192 = 1 / 2 96/192=1/2 96/192=1/2 16 / 192 = 1 / 12 16/192=1/12 16/192=1/12后,再接上第二层卷积层。第二个Inception块输出通道数增至 128 + 192 + 96 + 64 = 480 128+192+96+64=480 128+192+96+64=480,每条线路的输出通道数之比为 128 : 192 : 96 : 64 = 4 : 6 : 3 : 2 128:192:96:64 = 4:6:3:2 128:192:96:64=4:6:3:2。其中第二、第三条线路先分别将输入通道数减小至 128 / 256 = 1 / 2 128/256=1/2 128/256=1/2 32 / 256 = 1 / 8 32/256=1/8 32/256=1/8

b3 = nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32),
                   Inception(256, 128, (128, 192), (32, 96), 64),
                   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))

第四模块更加复杂。它串联了5个Inception块,其输出通道数分别是 192 + 208 + 48 + 64 = 512 192+208+48+64=512 192+208+48+64=512 160 + 224 + 64 + 64 = 512 160+224+64+64=512 160+224+64+64=512 128 + 256 + 64 + 64 = 512 128+256+64+64=512 128+256+64+64=512 112 + 288 + 64 + 64 = 528 112+288+64+64=528 112+288+64+64=528 256 + 320 + 128 + 128 = 832 256+320+128+128=832 256+320+128+128=832。这些线路的通道数分配和第三模块中的类似,首先含 3 × 3 3\times 3 3×3卷积层的第二条线路输出最多通道,其次是仅含 1 × 1 1\times 1 1×1卷积层的第一条线路,之后是含 5 × 5 5\times 5 5×5卷积层的第三条线路和含 3 × 3 3\times 3 3×3最大池化层的第四条线路。其中第二、第三条线路都会先按比例减小通道数。这些比例在各个Inception块中都略有不同。

b4 = nn.Sequential(Inception(480, 192, (96, 208), (16, 48), 64),
                   Inception(512, 160, (112, 224), (24, 64), 64),
                   Inception(512, 128, (128, 256), (24, 64), 64),
                   Inception(512, 112, (144, 288), (32, 64), 64),
                   Inception(528, 256, (160, 320), (32, 128), 128),
                   nn.MaxPool2d(kernel_size=3, stride=2, padding=1))

第五模块有输出通道数为 256 + 320 + 128 + 128 = 832 256+320+128+128=832 256+320+128+128=832 384 + 384 + 128 + 128 = 1024 384+384+128+128=1024 384+384+128+128=1024的两个Inception块。其中每条线路的通道数的分配思路和第三、第四模块中的一致,只是在具体数值上有所不同。需要注意的是,第五模块的后面紧跟输出层,该模块同NiN一样使用全局平均池化层来将每个通道的高和宽变成1。最后我们将输出变成二维数组后接上一个输出个数为标签类别数的全连接层。

b5 = nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),
                   Inception(832, 384, (192, 384), (48, 128), 128),
                   d2l.GlobalAvgPool2d())

net = nn.Sequential(b1, b2, b3, b4, b5, 
                    d2l.FlattenLayer(), nn.Linear(1024, 10))

GoogLeNet模型的计算复杂,而且不如VGG那样便于修改通道数。本节里我们将输入的高和宽从224降到96来简化计算。下面演示各个模块之间的输出的形状变化。

net = nn.Sequential(b1, b2, b3, b4, b5, d2l.FlattenLayer(), nn.Linear(1024, 10))
X = torch.rand(1, 1, 96, 96)
for blk in net.children(): 
    X = blk(X)
    print('output shape: ', X.shape)

输出:

output shape:  torch.Size([1, 64, 24, 24])
output shape:  torch.Size([1, 192, 12, 12])
output shape:  torch.Size([1, 480, 6, 6])
output shape:  torch.Size([1, 832, 3, 3])
output shape:  torch.Size([1, 1024, 1, 1])
output shape:  torch.Size([1, 1024])
output shape:  torch.Size([1, 10])

5.9.3 获取数据和训练模型

我们使用高和宽均为96像素的图像来训练GoogLeNet模型。训练使用的图像依然来自Fashion-MNIST数据集。

batch_size = 128
# 如出现“out of memory”的报错信息,可减小batch_size或resize
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96)

lr, num_epochs = 0.001, 5
optimizer = torch.optim.Adam(net.parameters(), lr=lr)
d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)

输出:

training on  cuda
epoch 1, loss 0.0087, train acc 0.570, test acc 0.831, time 45.5 sec
epoch 2, loss 0.0032, train acc 0.851, test acc 0.853, time 48.5 sec
epoch 3, loss 0.0026, train acc 0.880, test acc 0.883, time 45.4 sec
epoch 4, loss 0.0022, train acc 0.895, test acc 0.887, time 46.6 sec
epoch 5, loss 0.0020, train acc 0.906, test acc 0.896, time 43.5 sec

小结

  • Inception块相当于一个有4条线路的子网络。它通过不同窗口形状的卷积层和最大池化层来并行抽取信息,并使用 1 × 1 1\times 1 1×1卷积层减少通道数从而降低模型复杂度。
  • GoogLeNet将多个设计精细的Inception块和其他层串联起来。其中Inception块的通道数分配之比是在ImageNet数据集上通过大量的实验得来的。
  • GoogLeNet和它的后继者们一度是ImageNet上最高效的模型之一:在类似的测试精度下,它们的计算复杂度往往更低。

参考文献

[1] Szegedy, C., Liu, W., Jia, Y., Sermanet, P., Reed, S., & Anguelov, D. & Rabinovich, A.(2015). Going deeper with convolutions. In Proceedings of the IEEE conference on computer vision and pattern recognition (pp. 1-9).

[2] Ioffe, S., & Szegedy, C. (2015). Batch normalization: Accelerating deep network training by reducing internal covariate shift. arXiv preprint arXiv:1502.03167.

[3] Szegedy, C., Vanhoucke, V., Ioffe, S., Shlens, J., & Wojna, Z. (2016). Rethinking the inception architecture for computer vision. In Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (pp. 2818-2826).

[4] Szegedy, C., Ioffe, S., Vanhoucke, V., & Alemi, A. A. (2017, February). Inception-v4, inception-resnet and the impact of residual connections on learning. In Proceedings of the AAAI Conference on Artificial Intelligence (Vol. 4, p. 12).


注:除代码外本节与原书此节基本相同,原书传送门

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/434841.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pycharm与Anaconda安装

网址: Pycharm:https://www.jetbrains.com/pycharm/ Anaconda:https://www.anaconda.com/download/ 官网下载速度太慢可以选择到清华源下载:https://repo.anaconda.com/archive/ 一:Anaconda安装 安装: …

Android开发社招面试经验,大佬带你看源码

程序员的劫 最近,又被程序员年龄的事情刷屏了。37岁被公司优化,找工作几个月都没有很好的归属,所谓的小公司还看不上。等等类似的话题变成了程序员的吐槽固定标题,无论是程序员,还是其他行业人员,都可以就…

把简单留给用户,把复杂交给 AI

2024 年伊始,Kyligence 联合创始人兼 CEO 韩卿(Luke)分享了对 AI 与数据行业的一些战略思考,以及对中美企业服务市场的见解,引发业界同仁的广泛共鸣。正值 Kyligence 成立 8 周年,恰逢 AI 技术应用风起云涌…

开发一个小程序需要多少钱

【腾讯云】 爆款2核2G3M云服务器首年 61元,叠加红包再享折上折 要做小程序的小伙伴们福利来啦! 抢购方式: 方式一:直达链接》点我直接抢购 方式二:长按住识别以下官方二维码直接抢购 01 小程序认证 根据微信公众平台…

1.2_1 分层结构、协议、接口和服务

1.2_1 分层结构、协议、接口和服务 (一)为什么要分层? 主机A如果想要向主机B发送文件,则一定要经过中间的一些介质、链路。 发送文件前要完成的工作: 1.发起通信的计算机必须将数据通信的通路进行激活。 所谓的激活&a…

经典算法----折半查找

二、经典算法之折半查找 很多同学对于二分法就是&#xff1a;一看就会&#xff0c;一写就废&#xff01;&#xff01;&#xff01;&#xff01; 易错点1&#xff1a;以下循环方式写哪一个&#xff1f; 方案一&#xff1a;while(left<right) 方案二&#xff1a;while(left…

[蓝桥杯 2017 省 A] 油漆面积 Java代码及一些个人理解

[蓝桥杯 2017 省 A] 油漆面积 题目描述 X 星球的一批考古机器人正在一片废墟上考古。 该区域的地面坚硬如石、平整如镜。 管理人员为方便&#xff0c;建立了标准的直角坐标系。 每个机器人都各有特长、身怀绝技。它们感兴趣的内容也不相同。 经过各种测量&#xff0c;每个…

uniapp小程序获取位置权限(不允许拒绝)

需求 小程序上如果需要一些定位功能&#xff0c;那么我们需要提前获取定位权限。我们页面的所有功能后续都需要在用户同意的前提下进行&#xff0c;所以一旦用户点了拒绝&#xff0c;我们应该给予提示&#xff0c;并让用于修改为允许。 实现 1.打开手机GPS 经过测试发现即使…

Java精品项目--第6期基于SpringBoot的茶叶商城的设计分析与实现

项目技术栈 SpringBootMavenMySQLJAVAMybatis-PLusVue.js&#xff08;非前后端分离&#xff09;Element-UI&#xff08;非前后端分离&#xff09;… 表截图 项目截图

Pygame教程05:帧动画原理+边界值检测,让小球来回上下运动

------------★Pygame系列教程★------------ Pygame教程01&#xff1a;初识pygame游戏模块 Pygame教程02&#xff1a;图片的加载缩放旋转显示操作 Pygame教程03&#xff1a;文本显示字体加载transform方法 Pygame教程04&#xff1a;draw方法绘制矩形、多边形、圆、椭圆、弧…

MES系统是怎么进行数据采集的?

在MES管理系统中&#xff0c;数据采集作为最基础也最为关键的一环&#xff0c;对于实现生产过程的透明化、可控好以及优化生产流程具有重要意义。 mes系统是怎么采集数据的? 一、PLC类数据采集&#xff1a;使用C#或C直接编程访问PLC(不需要花钱买组态软件或第三方软件) 二、…

Javaweb之SpringBootWeb案例之自动配置案例的自定义starter测试的详细解析

3.2.4.3 自定义starter测试 阿里云OSS的starter我们刚才已经定义好了&#xff0c;接下来我们就来做一个测试。 今天的课程资料当中&#xff0c;提供了一个自定义starter的测试工程。我们直接打开文件夹&#xff0c;里面有一个测试工程。测试工程就是springboot-autoconfigurat…

CTP-API开发系列之柜台系统简介

CTP-API开发系列之柜台系统简介 CTP-API开发系列之柜台系统简介中国金融市场结构---交易所柜台系统通用柜台系统极速柜台系统主席与次席 CTP柜台系统CTP组件名称对照表CTP柜台系统程序包CTP柜台系统架构图 CTP-API开发系列之柜台系统简介 中国金融市场结构—交易所 我们知道提…

DR模式下部署LVS负载均衡集群的详细原理

目录 一、LVS-DR模式 1、基本原理 2、数据包流向分析 二、LVS-DR中的ARP问题 三、LVS-DR 特点 3.1 DR模式的特点 3.2 LVS-DR的优缺点 四、RS设置lo:0而不设置ens33:0的原因 一、LVS-DR模式 1、基本原理 Director Server作为群集的访问入口&#xff0c;但不作为网关使…

【python--比对两个列表获取列表中出现频率最高的词及频率】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; python练习题 完整代码 完整代码 from collections import Counter from data_keywords import extract_…

SQL注入漏洞,常用注入函数及其pakachu漏洞靶场演示

目录 SQL注入漏洞概述 SQL注入的常用函数 漏洞分类与利用 1.基于联合查询的SQL注入 &#xff12;.盲注 时间盲注&#xff08;base on bool&#xff09;​编辑 &#xff13;.宽字节注入 4.inset&#xff0f;update&#xff0f;delete注入 &#xff15;.header注入 &…

QLC SSD:LDPC纠错算法的优化方案

随着NAND TLC和QLC出现,LDPC也在不断的优化研究,提升纠错能力。小编看到有一篇来自Microchip发布的比较详细的LDPC研究数据,根据自己的理解分析解读给大家,如有错误,请留言指正! 文档中测试LDPC(Low-Density Parity-Check)码是为了评估其在不同配置下对数据错误的有效…

【洛谷 P8749】[蓝桥杯 2021 省 B] 杨辉三角形 题解(动态规划+组合数学+滚动数组)

[蓝桥杯 2021 省 B] 杨辉三角形 题目描述 下面的图形是著名的杨辉三角形: 如果我们按从上到下、从左到右的顺序把所有数排成一列&#xff0c;可以得到如下数列&#xff1a; 1 , 1 , 1 , 1 , 2 , 1 , 1 , 3 , 3 , 1 , 1 , 4 , 6 , 4 , 1 , … 1,1,1,1,2,1,1,3,3,1,1,4,6,4,1, …

《金三银四求职攻略》:程序员面试季倒计时

程序员的金三银四求职宝典 大家好&#xff0c;我是小明&#xff0c;一位即将面临春季求职季的程序员。在这个黄金时段&#xff0c;如何在众多应聘者中脱颖而出&#xff0c;拿下理想的offer&#xff0c;成为了我思考的重点。今天&#xff0c;我将分享一些我个人的求职攻略&…

Claude3 AI系列重磅推出:引领多模态智能时代的前沿技术,超越GPT-4

Claude3正式发布&#xff1a;号称性能超 GPT-4&#xff0c;免费使用、支持中文 划重点: &#x1f680; Claude3系列发布&#xff0c;包括Haiku、Sonnet和Opus版本&#xff0c;Opus在多个领域超越GPT-4。 &#x1f310; 用户可免费使用Claude3Sonnet模型&#xff0c;支持中文&am…
最新文章