首页 > 其他分享 >深度学习网络结构之---Inception

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

时间:2024-06-15 08:59:11浏览次数:23  
标签:ch 卷积 self 网络 --- strides 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 = ch
       self.strides = strides
       self.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=channel
       x = 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_ch
       self.out_channels = init_ch
       self.num_blocks = num_blocks
       self.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 block
           self.out_channels *= 2
       self.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模块。

标签:ch,卷积,self,网络,---,strides,Inception,网络结构
From: https://blog.csdn.net/lbr15660656263/article/details/139693439

相关文章

  • chatTTS系列之-apiServer
    文章目录背景技术方案方案实现安装FastAPI编写一个入口逻辑实现全局只维护一个chat对象生成随机音色合成一个完整音频返回结果总结背景在之前文章中我们对chattts有了一个大致的了解并对webui进行了一定的优化。然而,还有很多情况下我们还需要进行api调用。gradio......
  • Java---BigInteger和BigDecimal和枚举
    1.简介1.BigInteger可以支持任意长度的整数2.BigDecimal可以支持任意精度的浮点数3.用来做精确计算2.创建方式newBigInteger();newBigInteger(参数1,进制):可以将不同进制转成10进制显示newBigDecimal();BigInteger.valueOf();BigDecimal.valueOf();Scanner对象的n......
  • (056)FPGA时钟--->(006)时钟不确定性
     (006)时钟不确定性1目录(a)FPGA简介(b)Verilog简介(c)时钟简介(d)时钟不确定性(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既......
  • DreamJudge-1248-整数奇偶排序
    1.题目描述TimeLimit:1000msMemoryLimit:256mb输入10个整数,彼此以空格分隔。重新排序以后输出(也按空格分隔),要求:1.先输出其中的奇数,并按从大到小排列;2.然后输出其中的偶数,并按从小到大排列。输入输出格式输入描述:任意排序的10个整数(0~100),彼此以空格分隔。输......
  • XXL-job 使用
    1、找到XXL-job官网去下代码https://github.com/xuxueli/xxl-job2、下载下来用IDEA打开,你会得到这样子的目录结构3、打开doc目录下面有个db,在你数据库里面创建对应的数据库4、运行服务端xxl-job-admin登录进去账号admin密码123456好了,现在我们服务端启动好了5、创建......
  • (055)FPGA时钟--->(005)时钟偏斜
     (005)时钟偏斜1目录(a)FPGA简介(b)Verilog简介(c)时钟简介(d)时钟偏斜(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定......
  • 【TF-IDF算法】
    ......
  • 【安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试】
    安装笔记-系列文章目录安装笔记-20240613-Linux-在OpenWrt的LuCI界面支持命令行调试文章目录安装笔记-系列文章目录安装笔记-20240613-Linux-在OpenWrt的LuCI界面支持命令行调试前言一、软件介绍名称:ttyd主页官方介绍特点二、安装步骤测试版本:openwrt-23.05.3......
  • boost-Asio 基础学习1.5--域名主机名解析筛选resolver
    在开发过程中往往看见的不是ipv4或者ipv6,而是主机的域名!如www.badiu.com而上期文章也说了......
  • Java--数组的使用
    1.普通For循环(用的最多,需从中取出数据以及下标)        eg:图中三类问题都可2.For-each循环(一般用来打印一些结果)    eg:打印数组的具体元素3.数组作方法入参(对数组进行一些操作)    eg:可通过参数调用数组4.数组做返回值(对数组进行修改,最后返回一......