文章目录

  • GoogLeNet网络简介
  • GoogLeNet网络结构
    • Inception之前的几层结构
    • Inception结构
      • Inception3a模块
      • Inception3b + MaxPool
      • Inception4a
      • Inception4b
      • Inception4c
      • Inception4d
      • Inception4e+MaxPool
      • Inception5a
      • Inception5b
    • Inception之后的几层结构
    • 辅助分类模块
      • 辅助分类模块1
      • 辅助分类模块2
  • 整体网络结构
    • pytorch搭建完整代码
    • 结构图

GoogLeNet网络简介

GoogLeNet原文地址:Going Deeper with Convolutions:https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Szegedy_Going_Deeper_With_2015_CVPR_paper.pdf

GoogLeNet在2014年由Christian Szegedy提出,它是一种全新的深度学习结构。

GoogLeNet网络的主要创新点在于:

  1. 提出Inception结构在多个尺寸上同时进行卷积再聚合;

  2. 使用1X1的卷积进行降维以及映射处理;

  3. 添加两个辅助分类器帮助训练;
    辅助分类器是将中间某一层的输出用作分类,并按一个较小的权重加到最终分类结果中。

  4. 使用平均池化层代替全连接层,大大减少了参数量。

GoogLeNet网络结构

GoogLeNet的完整网络结构如下所示:

下面我们将其逐层拆分讲解并结合代码分析

Inception之前的几层结构

在进入Inception结构之前,GoogLeNet网络先堆叠了两个卷积(实则3个,有一个1X1的卷积)和两个最大池化层。

# input(3,224,224)
self.front = nn.Sequential(nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3),   # output(64,112,112)nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3,stride=2,ceil_mode=True),    # output(64,56,56)nn.Conv2d(64,64,kernel_size=1),nn.Conv2d(64,192,kernel_size=3,stride=1,padding=1),     # output(192,56,56)nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3,stride=2,ceil_mode=True),    # output(192,28,28)
)

Inception结构

Inception模块只会改变特征图的通道数,而不会改变尺寸大小。

Inception结构相对复杂,我们重新创建一个类来构建此结构,并通过参数不同的参数来控制各层的通道数。

class Inception(nn.Module):'''in_channels: 输入通道数out1x1:分支1输出通道数in3x3:分支2的3x3卷积的输入通道数out3x3:分支2的3x3卷积的输出通道数in5x5:分支3的5x5卷积的输入通道数out5x5:分支3的5x5卷积的输出通道数pool_proj:分支4的最大池化层输出通道数'''def __init__(self,in_channels,out1x1,in3x3,out3x3,in5x5,out5x5,pool_proj):super(Inception, self).__init__()self.branch1 = nn.Sequential(nn.Conv2d(in_channels, out1x1, kernel_size=1),nn.ReLU(inplace=True))self.branch2 = nn.Sequential(nn.Conv2d(in_channels,in3x3,kernel_size=1),nn.ReLU(inplace=True),nn.Conv2d(in3x3,out3x3,kernel_size=3,padding=1),nn.ReLU(inplace=True))self.branch3 = nn.Sequential(nn.Conv2d(in_channels, in5x5, kernel_size=1),nn.ReLU(inplace=True),nn.Conv2d(in5x5, out5x5, kernel_size=5, padding=2),nn.ReLU(inplace=True))self.branch4 = nn.Sequential(nn.MaxPool2d(kernel_size=3,stride=1,padding=1),nn.Conv2d(in_channels,pool_proj,kernel_size=1),nn.ReLU(inplace=True))def forward(self,x):branch1 = self.branch1(x)branch2 = self.branch2(x)branch3 = self.branch3(x)branch4 = self.branch4(x)outputs = [branch1,branch2,branch3,branch4]return torch.cat(outputs,1)   # 按通道数叠加

Inception3a模块

# input(192,28,28)
self.inception3a = Inception(192, 64, 96, 128, 16, 32, 32)     # output(256,28,28)

Inception3b + MaxPool

# input(256,28,28)
self.inception3b = Inception(256, 128, 128, 192, 32, 96, 64)       # output(480,28,28)
self.maxpool3 = nn.MaxPool2d(3, stride=2, ceil_mode=True)            # output(480,14,14)

Inception4a

# input(480,14,14)
self.inception4a = Inception(480, 192, 96, 208, 16, 48, 64)        # output(512,14,14)

Inception4b

# input(512,14,14)
self.inception4b = Inception(512, 160, 112, 224, 24, 64, 64)       # output(512,14,14)

Inception4c

# input(512,14,14)
self.inception4c = Inception(512, 160, 112, 224, 24, 64, 64)       # output(512,14,14)

Inception4d

# input(512,14,14)
self.inception4d = Inception(512, 112, 144, 288, 32, 64, 64)       # output(528,14,14)

Inception4e+MaxPool

# input(528,14,14)
self.inception4e = Inception(528, 256, 160, 320, 32, 128, 128) # output(832,14,14)
self.maxpool4 = nn.MaxPool2d(3, stride=2, ceil_mode=True)        # output(832,7,7)

Inception5a

# input(832,7,7)
self.inception5a = Inception(832, 256, 160, 320, 32, 128, 128)     # output(832,7,7)

Inception5b

# input(832,7,7)
self.inception5b = Inception(832, 384, 192, 384, 48, 128, 128)     # output(1024,7,7)

Inception之后的几层结构

辅助分类模块

除了以上主干网络结构以外,GoogLeNet还提供了两个辅助分类模块,用于将中间某一层的输出用作分类,并按一个较小的权重(0.3)加到最终分类结果。

与Inception模块一样,我们也重新创建一个类来搭建辅助分类模块结构。

class AccClassify(nn.Module):# in_channels: 输入通道# num_classes: 分类数def __init__(self,in_channels,num_classes):self.avgpool = nn.AvgPool2d(kernel_size=5, stride=3)self.conv = nn.MaxPool2d(in_channels, 128, kernel_size=1)  # output[batch, 128, 4, 4]self.relu = nn.ReLU(inplace=True)self.fc1 = nn.Linear(2048, 1024)self.fc2 = nn.Linear(1024, num_classes)def forward(self,x):x = self.avgpool(x)x = self.conv(x)x = self.relu(x)x = torch.flatten(x, 1)x = F.dropout(x, 0.5, training=self.training)x = F.relu(self.fc1(x), inplace=True)x = F.dropout(x, 0.5, training=self.training)x = self.fc2(x)return x

辅助分类模块1

第一个中间层输出位于Inception4a之后,将Inception4a的输出经过平均池化,1X1卷积和全连接后等到分类结果。

self.acc_classify1 = AccClassify(512,num_classes)

辅助分类模块2

self.acc_classify2 = AccClassify(528,num_classes)

整体网络结构

pytorch搭建完整代码

"""
#-*-coding:utf-8-*-
# @author: wangyu a beginner programmer, striving to be the strongest.
# @date: 2022/7/5 18:37
"""
import torch.nn as nn
import torch
import torch.nn.functional as Fclass GoogLeNet(nn.Module):def __init__(self,num_classes=1000,aux_logits=True):super(GoogLeNet, self).__init__()self.aux_logits = aux_logits# input(3,224,224)self.front = nn.Sequential(nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3),   # output(64,112,112)nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3,stride=2,ceil_mode=True),    # output(64,56,56)nn.Conv2d(64,64,kernel_size=1),nn.Conv2d(64,192,kernel_size=3,stride=1,padding=1),     # output(192,56,56)nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3,stride=2,ceil_mode=True),    # output(192,28,28))# input(192,28,28)self.inception3a = Inception(192, 64, 96, 128, 16, 32, 32)  # output(64+128+32+32=256,28,28)self.inception3b = Inception(256, 128, 128, 192, 32, 96, 64)  # output(480,28,28)self.maxpool3 = nn.MaxPool2d(3, stride=2, ceil_mode=True)  # output(480,14,14)self.inception4a = Inception(480, 192, 96, 208, 16, 48, 64)  # output(512,14,14)self.inception4b = Inception(512, 160, 112, 224, 24, 64, 64)  # output(512,14,14)self.inception4c = Inception(512, 128, 128, 256, 24, 64, 64)  # output(512,14,14)self.inception4d = Inception(512, 112, 144, 288, 32, 64, 64)  # output(528,14,14)self.inception4e = Inception(528, 256, 160, 320, 32, 128, 128)  # output(832,14,14)self.maxpool4 = nn.MaxPool2d(3, stride=2, ceil_mode=True)  # output(832,7,7)self.inception5a = Inception(832, 256, 160, 320, 32, 128, 128)  # output(832,7,7)self.inception5b = Inception(832, 384, 192, 384, 48, 128, 128)  # output(1024,7,7)if self.training and self.aux_logits:self.acc_classify1 = AccClassify(512,num_classes)self.acc_classify2 = AccClassify(528,num_classes)self.avgpool = nn.AdaptiveAvgPool2d((1,1))        # output(1024,1,1)self.dropout = nn.Dropout(0.4)self.fc = nn.Linear(1024,num_classes)def forward(self,x):# input(3,224,224)x = self.front(x)       # output(192,28,28)x= self.inception3a(x)  # output(256,28,28)x = self.inception3b(x)x = self.maxpool3(x)x = self.inception4a(x)if self.training and self.aux_logits:classify1 = self.acc_classify1(x)x = self.inception4b(x)x = self.inception4c(x)x = self.inception4d(x)if self.training and self.aux_logits:classify2 = self.acc_classify2(x)x = self.inception4e(x)x = self.maxpool4(x)x = self.inception5a(x)x = self.inception5b(x)x = self.avgpool(x)x = torch.flatten(x,dims=1)x = self.dropout(x)x= self.fc(x)if self.training and self.aux_logits:return x,classify1,classify2return xclass Inception(nn.Module):'''in_channels: 输入通道数out1x1:分支1输出通道数in3x3:分支2的3x3卷积的输入通道数out3x3:分支2的3x3卷积的输出通道数in5x5:分支3的5x5卷积的输入通道数out5x5:分支3的5x5卷积的输出通道数pool_proj:分支4的最大池化层输出通道数'''def __init__(self,in_channels,out1x1,in3x3,out3x3,in5x5,out5x5,pool_proj):super(Inception, self).__init__()# input(192,28,28)self.branch1 = nn.Sequential(nn.Conv2d(in_channels, out1x1, kernel_size=1),nn.ReLU(inplace=True))self.branch2 = nn.Sequential(nn.Conv2d(in_channels,in3x3,kernel_size=1),nn.ReLU(inplace=True),nn.Conv2d(in3x3,out3x3,kernel_size=3,padding=1),nn.ReLU(inplace=True))self.branch3 = nn.Sequential(nn.Conv2d(in_channels, in5x5, kernel_size=1),nn.ReLU(inplace=True),nn.Conv2d(in5x5, out5x5, kernel_size=5, padding=2),nn.ReLU(inplace=True))self.branch4 = nn.Sequential(nn.MaxPool2d(kernel_size=3,stride=1,padding=1),nn.Conv2d(in_channels,pool_proj,kernel_size=1),nn.ReLU(inplace=True))def forward(self,x):branch1 = self.branch1(x)branch2 = self.branch2(x)branch3 = self.branch3(x)branch4 = self.branch4(x)outputs = [branch1,branch2,branch3,branch4]return torch.cat(outputs,1)class AccClassify(nn.Module):def __init__(self,in_channels,num_classes):self.avgpool = nn.AvgPool2d(kernel_size=5, stride=3)self.conv = nn.MaxPool2d(in_channels, 128, kernel_size=1)  # output[batch, 128, 4, 4]self.relu = nn.ReLU(inplace=True)self.fc1 = nn.Linear(2048, 1024)self.fc2 = nn.Linear(1024, num_classes)def forward(self,x):x = self.avgpool(x)x = self.conv(x)x = self.relu(x)x = torch.flatten(x, 1)x = F.dropout(x, 0.5, training=self.training)x = F.relu(self.fc1(x), inplace=True)x = F.dropout(x, 0.5, training=self.training)x = self.fc2(x)return x# print(GoogLeNet())

结构图

卷积神经网络模型之——GoogLeNet网络结构与代码实现相关推荐

  1. 卷积神经网络模型解读汇总——LeNet5,AlexNet、ZFNet、VGG16、GoogLeNet和ResNet

      在我的个人博客上一篇博文中分析了卷积神经网络的结构与相关算法,知道了这些基本原理之后.这篇博文主要介绍在卷积神经网络的发展历程中一些经典的网络模型. LeNet5   LeCun等将BP算法应用到 ...

  2. CNN-4: GoogLeNet 卷积神经网络模型

    1.GoogLeNet 模型简介 GoogLeNet 是2014年Christian Szegedy提出的一种全新的深度学习结构,该模型获得了ImageNet挑战赛的冠军. 2.GoogLeNet 模 ...

  3. 第05章 深度卷积神经网络模型

    序言 1. 内容介绍   本章介绍深度学习算法-卷积神经网络用于 图片分类 的应用,主要介绍主流深度卷积神经网络 (CNN) 模型,包括 ResNet DenseNet SeNet 的算法模型.数学推 ...

  4. 图片2分类卷积神经网络模型训练、分类预测案例全过程(1)

    图片2分类卷积神经网络模型训练.分类预测案例全过程(1) 前言 (1)尽管目前有关卷积神经网络深度学习的相关材料较多,但深度学习牵涉到数据预处理.模型构建.模型调用等环节,我也是一个初学者,中间有很多 ...

  5. 卷积神经网络发展历史及各种卷积神经网络模型简介

    1.前言 我的毕设做的是基于opencv和卷积神经网络的人脸识别项目.在做完这个项目之后,我一直想好好总结一下所学到的关于卷积神经网络的知识.现在趁着有点空闲,随手记录一点以前学过的,或者正在学习的知 ...

  6. 经典卷积神经网络模型盘点

    前言 卷积神经网络在图像数据的处理中大放异彩.最早发布的卷积神经网络LeNet已经能取得与支持向量机相媲美的结果,深度学习时代又诞生了各种深度网络,特点和适用背景也各不相同.本文按时间顺序介绍几种经典 ...

  7. 如何提高卷积神经网络模型的泛化能力

    如何提高卷积神经网络模型的泛化能力 在做工程的时候如何提高自己训练出来的模型的泛化能力是一项具有挑战性同时也是一件充满"玄学"的事情.回想我这一年半载训练的那么几个任务的调参来讲, ...

  8. 卷积神经网络模型可解释性

    卷积神经网络模型可解释性 缺乏可解释性仍然是在许多应用中采用深层模型的一个关键障碍.在这项工作中,明确地调整了深层模型,这样人类用户可以在很短的时间内完成他们预测背后的过程.具体地说,训练了深度时间序 ...

  9. 卷积神经网络模型如何辨识裸体图片

    著名人工智能公司Clarifai公司近日推出了识别成人内容的模型和API NSFW,该模型能够很准确地识别含有裸体和半裸的图片和视频,在Clarifai的这篇博文中,作者用裸体检测问题来展示训练现代版 ...

最新文章

  1. C语言求35 45的最大公约数,c语言编程题目及答案
  2. 每天学一点儿shell:linux常用快捷键
  3. 由于c语言是由字符流组成的,C语言试题及答案
  4. wpf 在另一个窗体上显示_另一个唐伯虎:大街上裸身奔跑、锒铛入狱多次自裁未遂...
  5. 普通卷积armv7-neon指令集实现—QNNPACK
  6. ES5-10 原型、原型链、闭包立即执行函数、插件开发
  7. node.js 针对不同的请求路径(url) 做出不同的响应
  8. 信息学奥赛一本通(1262:【例9.6】挖地雷)
  9. 为什么黑客都用python-黑客编程为什么首选Python语言?这里告诉你答案!
  10. Qt UDP组播的应用
  11. 移动滑块改变使用容量
  12. Oracle PL/SQL游标的学习
  13. 如何制作行政区划矢量图(shp格式)
  14. java 计算2的64次幂_2的64次方
  15. python 矩阵特征值分解_特征值分解和奇异值分解
  16. Windows与网络基础-27-子网掩码
  17. win7搭建VM10虚拟机,搭建win7旗舰版64系统
  18. 人大金仓命令行客户端工具KSQL系列1
  19. DCloud UniAPP Android 蓝牙连接ESCPOS打印机
  20. qpython3h教程_Python3实现AI五子棋【初版】|python3教程|python入门|python教程

热门文章

  1. centos 中svn服务的启动、关闭、重启, 以及添加开机启动
  2. 智慧城市理念落地现实过程中边缘计算在其中占据何种优势
  3. 特殊的象形柱图echarts
  4. html2canvas截图的使用
  5. TextView文字左右对齐
  6. k8s安装rook-ceph1.8
  7. Left()ReverseFind()
  8. 横向 的vant组件的日历
  9. 当我们买手机时,我们在买什么
  10. 微信公众号开发接收语音消息时权限