卷积神经网络的网络结构_典型卷积神经网络结构

卷积神经网络的网络结构_典型卷积神经网络结构GoogLeNet原文地址:GoingDeeperwithConvolutions:https://www.cv-foundation.org/openaccess/content_cvpr_2015/papers/Szegedy_Going_Deeper_With_2015_CVPR_paper.pdfGoogLeNet在2014年由ChristianSzegedy提出,它是一种全新的深度学习结构。GoogLeNet网络的主要创新点在于:提出Inception结构在多个尺寸上同时进行卷积再聚合;

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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 F
class 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,classify2
return x
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__()
# 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())

结构图

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/170439.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • python语音信号处理(一)「建议收藏」

    python语音信号处理(一)「建议收藏」1.引言python已经支持WAV格式的书写,而实时的声音输入输出需要安装pyAudio。最后我们还将使用pyMedia进行Mp3的解码和播放。音频信号是模拟信号,我们需要将其保存为数字信号,才能对语音进行算法操作,WAV是Microsoft开发的一种声音文件格式,通常被用来保存未压缩的声音数据。语音信号有四个重要的参数:声道数、采样频率、量化位数(位深)和比特率声道数:可以是单声道、双声道…采样频率(Samplerate):每秒内对声音信号采样样本的总数目,44100Hz采样频率意味着

  • Tomcat 调优及 JVM 参数优化

    Tomcat 调优及 JVM 参数优化Tomcat的缺省配置是不能稳定长期运行的,也就是不适合生产环境,它会死机,让你不断重新启动,甚至在午夜时分唤醒你。对于操作系统优化来说,是尽可能的增大可使用的内存容量、提高CPU的频率,保证文件系统的读写速率等。经过压力测试验证,在并发连接很多的情况下,CPU的处理能力越强,系统运行速度越快。Tomcat的优化不像其它软件那样,简简单单的修改几个参数就可以了,它的优化主要…

  • 二叉树的中序遍历非递归算法java_二叉树遍历例题解析

    二叉树的中序遍历非递归算法java_二叉树遍历例题解析*非递归算法思想:  (1)设置一个栈S存放所经过的根结点(指针)信息;初始化S; (2)第一次访问到根结点并不访问,而是入栈;  (3)中序遍历它的左子树,左子树遍历结束后,第二次遇到根结点,就将根结点(指针)退栈,并且访问根结点;然后中序遍历它的右子树。 (4)当需要退栈时,如果栈为空则结束。     代码实现:void…

  • 各大公司的大数据质量监控平台

    各大公司的大数据质量监控平台转自:https://zhuanlan.zhihu.com/p/41679658在这个信息化时代,你用手机打开微信聊天、打开京东app浏览商品、访问百度搜索、甚至某些app给你推送的信息流等等,数据无时无刻不在产生。数据,已经成为互联网企业非常依赖的新型重要资产。数据质量的好坏直接关系到信息的精准度,也影响到企业的生存和竞争力。MichaelHammer(《Reengineeringt…

  • method exists php,浅谈php method_exists检测类中是否包括函数

    method exists php,浅谈php method_exists检测类中是否包括函数php教程method_exists检测类中是否包括函数?或许有些人不是很明白其中道理,下面做如下详细分析。method_exists()函数的语法如下:boolmethod_exists(objectobject,stringmethod_name)method_exists()函数的作用是检查类的方法是否存在。如果method_name所指的方法在object所指的…

  • 史上最详细阿里云服务器搭建网站流程(图文教程)

    史上最详细阿里云服务器搭建网站流程(图文教程)新手如何用阿里云服务器Linux系统安装宝塔面板搭建WordPress博客网站呢?WordPress作为全球实用最广泛的CMS系统,以功能强大、扩展性强,插件众多,易扩充功能等特点,受到全球站长开发者青睐。而阿里云作为国内用户量最多的云服务器商,因此,本文以阿里云为例,详细介绍云服务器Linux系统如何安装宝塔面板搭建WordPress博客网站。新手如何用阿里云服务器Linux系统安装宝塔面板搭建WordPress博客网站呢?WordPress作为全球实用最广泛的CMS系统,以功能强大、扩展性强,插件众

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号