深度学习网络结构之---Inception

2024-06-15 10:20

本文主要是介绍深度学习网络结构之---Inception,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、Inception名称的由来

二、Inception结构

 三、Inception v2

四、Inception v3 

1、深度网络的通用设计原则

2.卷积分解(Factorizing Convolutions)

3.对称卷积分解

3.非对称卷积分解

 五、Inception v4


一、Inception名称的由来

        Inception网络名字来源于《盗梦空间》。inception网络代替人工确定卷积 层中的过滤器类型,解决了计算量爆炸的问题,让网络变得更深。

        基于对AlexNet 的卷积过程的研究,大家逐渐强化了一个信念-----更深的 网络带来更高的准确率,所以最简单,安全,有效地提高准备率的办法就是增加网络 的深度.这也正是Inception名称所隐含的"We need to go deeper"的含义.

        增加网络的深度(往往同时增加每层神经元数量) 容易导致以下几个方面的 问题.

        (1) 导致神经网络参数的数量过多,网络不容易训练,容易出现过拟合,需要更 多的训练数据. 然而训练数据并不容易获得,尤其是需要人工标记样本数据时就更 难了.所以如何在增加网络规模的同时尽可能地减少参数的数量是首先要考虑的 问题.

        (2 )增大了网络的规模(更深,更宽) , 需要消耗大量的计算资源,需要"有 效"和"充分"地使用计算资源.以两个卷积堆叠为例,随着卷积层的过滤器线性增 加,所需要的计算资源与过滤器个数的平方成正比.如果所增加的计算资源没有 被"有效"地使用,如所有的权重于0(但不等于0),那么这些计算量不会带来准确率 的提高,

        (3)当网络的深度达到一定程度之后,浅层神经网络容易出现梯度弥散的问题, 这是因为,误差反向传播的时候,随着深度的增加梯度会迅速变小,从而导致权重参 数变化缓慢,模型无法收敛.

        Inception 的网络架构正是沿着如何解决以上几个问题的方向,有针对性地设 计网络架构的.

二、Inception结构

        Inception就是将多个卷积或池化操作放在一起组装成一个网络模块,设计 神经网络时,以模块为单位去组装整个网络结构。Inception结构设计了一个稀 疏网络结构,但是能够产生稠密的数据,既能增加神经网络表现,又能保证计 算资源的使用效率。

        假设input feature map的size为28 × 28 × 256 ,output feature map的 size为28 × 28 × 480 则native Inception Module的计算量有854M。计算过程 如下  

        从上图可以看出,计算量主要来自高维卷积核的卷积操作,因而在每一个 卷积前先使用1 × 1卷积核将输入图片的feature map维度先降低,进行信息压 缩,在使用3x3卷积核进行特征提取运算,相同情况下,Inception v1的计算量 仅为358M。  

        Inception v1结构总共有4个分支,输入的feature map并行的通过这四个 分支得到四个输出,然后在在将这四个输出在深度维度(channel维度)进行拼 接(concate)得到我们的最终输出(注意,为了让四个分支的输出能够在深度方 向进行拼接,必须保证四个分支输出的特征矩阵高度和宽度都相同),因此 inception结构的参数为:

branch1:Conv1×1 , stride=1
branch2:Conv3×3, stride=1, padding=1
branch3:Conv5×5, stride=1, padding=2
branch4:MaxPool3×3, stride=1, padding=1

        一个完整的Inception模块如图所示。

 

        通过将这些模块组合起来就得到了完整的inception网络,由于它是由 google的研究员提出的,所以也叫做goolenet,是为了向lenet致敬。  

inception网络:

        Inception网络就是将多个Inception模块连接成一个网络。

         网络的最后几层通常为全连接层,最后接一个softmax层。可以看到网络中 的隐藏层有很多分支。这些分支使得隐藏层也可以单独进行预测,降低了过拟 合的风险。

代码实现:

 

#需求:inception,cifar10 确定框架 conv,maxpool flatten ,dense 
dropout ,预处理,bn,激活平均池化,全局平均池化
import tensorflow as tf
from tensorflow.keras.layers import Conv2D, MaxPool2D, 
Flatten, Dense, Dropout, BatchNormalization, Activation, 
AveragePooling2D, GlobalAveragePooling2D
from tensorflow.keras import Model
(x_train,y_train),
(x_test,y_test)=tf.keras.datasets.cifar10.load_data()
x_train=x_train.reshape([-1,32,32,3])/255
x_test=x_test.reshape([-1,32,32,3])/255
class ConvBNRelu(Model):def __init__(self, ch, kernelsz=3, strides=1, 
padding='same'):super(ConvBNRelu, self).__init__()self.model = tf.keras.models.Sequential([Conv2D(ch, kernelsz, strides=strides, 
padding=padding),BatchNormalization(),Activation('relu')])def call(self, x):x = self.model(x,                       training=False) # 在training=False时,
BN通过整个训练集计算均值、方差去做批归一化,training=True时,通过当前
batch的均值、方差去做批归一化。推理时 training=False效果好return x
class InceptionBlk(Model):def __init__(self, ch, strides=1):super(InceptionBlk, self).__init__()self.ch = chself.strides = stridesself.c1 = ConvBNRelu(ch, kernelsz=1, strides=strides)self.c2_1 = ConvBNRelu(ch, kernelsz=1, 
strides=strides)self.c2_2 = ConvBNRelu(ch, kernelsz=3, strides=1)self.c3_1 = ConvBNRelu(ch, kernelsz=1, 
strides=strides)self.c3_2 = ConvBNRelu(ch, kernelsz=5, strides=1)self.p4_1 = MaxPool2D(3, strides=1, padding='same')self.c4_2 = ConvBNRelu(ch, kernelsz=1, 
strides=strides)def call(self, x):x1 = self.c1(x)x2_1 = self.c2_1(x)x2_2 = self.c2_2(x2_1)x3_1 = self.c3_1(x)x3_2 = self.c3_2(x3_1)x4_1 = self.p4_1(x)x4_2 = self.c4_2(x4_1)# concat along axis=channelx = tf.concat([x1, x2_2, x3_2, x4_2], axis=3)return x
class Inception10(Model):def __init__(self, num_blocks, num_classes, init_ch=16, 
**kwargs):super(Inception10, self).__init__(**kwargs)self.in_channels = init_chself.out_channels = init_chself.num_blocks = num_blocksself.init_ch = init_ch4. Inception v2 
即在v1的基础上于卷积层与激活函数之间插入BN层:Conv-BN-ReLU,并
将v1结构中的5 × 5 卷积核替换为2个3 × 3 卷积核。第二篇论文里,作者给出了
inception v2中卷积分解的详细说明。self.c1 = ConvBNRelu(init_ch)self.blocks = tf.keras.models.Sequential()for block_id in range(num_blocks):for layer_id in range(2):if layer_id == 0:block = InceptionBlk(self.out_channels, 
strides=2)else:block = InceptionBlk(self.out_channels, 
strides=1)self.blocks.add(block)# enlarger out_channels per blockself.out_channels *= 2self.p1 = GlobalAveragePooling2D()self.f1 = Dense(num_classes, activation='softmax')def call(self, x):x = self.c1(x)x = self.blocks(x)x = self.p1(x)y = self.f1(x)return y
model = Inception10(num_blocks=2, num_classes=10)
#模型编译
model.compile(loss=tf.keras.losses.SparseCategoricalCrossentr
opy(),optimizer=tf.keras.optimizers.Adam(lr=0.001),metrics=['accuracy'])
#one-hot编码
history=model.fit(x_train,y_train,batch_size=64,epochs=1,vali
dation_split=0.3)
score = model.evaluate(x_test, y_test)
print('loss', score[0])
print('accuracy', score[1])

 三、Inception v2

        即在v1的基础上于卷积层与激活函数之间插入BN层:Conv-BN-ReLU,并 将v1结构中的5 × 5 卷积核替换为2个3 × 3 卷积核。第二篇论文里,作者给出了 inception v2中卷积分解的详细说明。

        Batch Normalization

        小卷积核替代大卷积核

        在VGGNet中就提出了通过堆叠两层3 × 3 的卷积核可以替代一层5 × 5 的卷 积核,堆叠三层 3 × 3的卷积核替代一层 7 × 7 的卷积核(参考:VGGNet网络 详解与模型搭建)。这样的连接方式在保持感受野范围的同时又减少了参数 量,并且可以避免表达瓶颈,加深非线性表达能力。基于此,作者通过将 inception v1结构中的5 × 5 卷积核替换为2个3 × 3 卷积核。如下左图为v1结 构,右图为v2结构。

四、Inception v3 

1、深度网络的通用设计原则

        (1) 避免表达瓶颈,特别是在网络靠前的地方。 信息流前向传播过程中显 然不能经过高度压缩的层,即表达瓶颈。从input到 output,feature map的宽和高基本都会逐渐变小,但是不能一下子就变得很小。比如你 上来就来个kernel = 7, stride = 5 ,这样显然不合适。另外输出的维度 channel,一般来说会逐渐增多(每层的num_output),否则网络会很难 训练。(特征维度并不代表信息的多少,只是作为一种估计的手段)。

        (2) 高维特征更易处理。 高维特征更易区分,会加快训练。

        (3)可以在低维嵌入上进行空间汇聚而无需担心丢失很多信息。 比如在进 行3x3卷积之前,可以对输入先进行降维而不会产生严重的后果。假设 信息可以被简单压缩,那么训练就会加快。

       (4)平衡网络的宽度与深度

2.卷积分解(Factorizing Convolutions)

        将一个大卷积核的操作分解成若干个小卷积核的操作称为卷积分 解,并探讨了2种不同的卷积分解方法,即对称卷积分解和不对称卷积 空间分解。

3.对称卷积分解

        即使用小卷积核串联来替代大卷积核,这在inception v2中已经提到过。同时作 者还提出,通过大量实验表明这种替代方案并不会造成表达能力的下降。通过 堆叠两层3 × 3 3\times33×3的卷积核可以替代一层5 × 5 的卷积核,堆叠三层 3 × 3 的卷积核替代一层 7 × 7 的卷积核,可以看出,大卷积核完全可以由一系列 的3 × 3 卷积核来替代,那能不能再分解得更小一点呢?GoogLeNet团队考虑了 非对称卷积分解。

3.非对称卷积分解

        任意n × n 的卷积都可以通过1 × n 卷积后接n × 1卷积来替代,如下图(右)所 示。

 在网络的前期使用这种分解效果并不好,还有在中度大小的feature map 上使用效果才会更好

        降低特征图大小

        一般情况下,如果想让特征图的通道数,可以有如下两种方式:

        先池化再作Inception卷积,或者先作Inception卷积再作池化。但是方法一 (左图)先作pooling(池化)会导致特征表示遇到瓶颈(特征缺失),方法二 (右图)是正常的缩小,但计算量很大。为了同时保持特征表示且降低计算 量,将网络结构改为下图,使用两个并行化的模块来降低计算量(卷积、池化 并行执行,再进行合并),即用卷积得到一半的特征图,池化得到一半的特征 图,再进行拼接。  

 五、Inception v4

        2016年ResNet网络的提出解决了随着神经网络的加深,参数越来越多,模 型越来越难以训练,训练时间大大增加,容易出现梯度消散问题。为了融合这 一重要成果,Inception v4研究了Inception模块与残差连接(Residual Connection)的结合来改进V3结构。

        如图,将残差模块的卷积结构替换为Inception结构,即得到Inception Residual结构。除了上述右图中的结构外,作者通过20个类似的模块进行组 合,最后形成了InceptionV4的网络结构,构建了Inception-ResNet模型.  

总结回顾
Inception v1主要采用了多尺度卷积核、1x1卷积操作。
Inception v2在v1的基础上增加了BN层,使用2个3 × 3小卷积核堆叠替换5 × 
5大卷积核;
inception v3进行了卷积分解(将7 × 7 分解成两个一维的卷积1 × 7 和1 × 
7 ,3 × 3 也是一样1 × 3 和3 × 1 和特征图降维。
inception v4在v3的基础上融合了Residual模块。

这篇关于深度学习网络结构之---Inception的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1063180

相关文章

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

五大特性引领创新! 深度操作系统 deepin 25 Preview预览版发布

《五大特性引领创新!深度操作系统deepin25Preview预览版发布》今日,深度操作系统正式推出deepin25Preview版本,该版本集成了五大核心特性:磐石系统、全新DDE、Tr... 深度操作系统今日发布了 deepin 25 Preview,新版本囊括五大特性:磐石系统、全新 DDE、Tree

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]