inception家族的发展史

在讲之前说明一下:每一个网络都只会讲解它的主要亮点,可能某个网络的某一个小部分不会讲到,但是讲到的部分都会讲得很细。(讲的知识面不是很宽,但是讲到的部分都会讲得很细。)

inceptionv1 (2014.9)

v1就是我们的GoogleNet,由谷歌在2014年提出

在讲之前,我强烈推荐大家去看看这篇博客,相信你们看了后一定会有所启发

(1条消息) GoogLeNet网络结构_仝笛的博客-CS​​​​​​DN博客_googlenet网络结构

v1最核心的部分就是它的inception结构

如下图就是一个inception结构,这是googlenet中最初始的结构

inception结构

我们普通的网络中卷积层,池化层,全连接层等等结构,它们是通过一个串联的结构形成的,经过了一层,才能经过下一层,但是v1,它是通过一个并联的结构,我们的前一层,同时输入到1*1,3*3,5*5,3*3最大池化层这个四个结构中,然后将这得出的四个结果重合在一起 。

但四个结果重合在一起的条件是,每一个单独的结果,它们的长和宽要相同

如图,这四个结果,都有一个正方形,即长和宽是相同的

googlenet一共有9个inception结构,每个inception结构都大同小异,但都是采用了并联的思想,同时将结果输入到每一个卷积层,池化层中。

我们之前讲的inception模块是googlenet中最初始的模块,但这个最初的结构有一个问题,它的四个分支,有一个分支是池化,其他三个分支是卷积,池化过后的维度是不变的,但卷积过后的维度是会增加的,若我们一直使用这个模块,会导致我们的维度越来越深,最终会导致参数量和计算量爆炸。googlenet最后也没有使用这个模块,而是进行了改进,增加了1*1卷积来降低维度,防止我们的参数量和计算量过多。1*1的卷积同时起到了减少参数量,减少计算量,降维,进行跨通道的信息交流,增加模型的非线性表达能力

inception这种并联的结构有一个优点,无论我们的目标图像在图片中占多大的位置(占整张图片,一部分,还是很小的一部分)我们的卷积核有多个尺寸(1*1,3*3,5*5)总有一种尺寸的卷积核会提取到我们的目标图像。

inception块能够大大的节约我们的参数

如上图,我们只使用inception块时,我们的参数时0.16M,而我们使用3*3和5*5卷积时,我们的参数量分别是0.44M和1.22M,FLOPS对应的是它们的计算量。

该表,第一列:是各层的名称;第二列:7*7/2,指卷积核的尺寸为7*7,s=2;第三列:输出图像的尺寸;第四列:网路的深度池化层的深度为0,一个inception的深度为2;第五-第十列:请看下图,inception(3a)中#1*1为64,则该卷积核所需要的个数为64;第十一列:参数量的大小;第十二列:计算量

这9个inception结构具体是怎么样的,大家可以通过最上面的那个链接去自行了解,里面有每个inception的图。

除了inception结构呢,Googlenet的另一个重要的部分就是它的‘辅助分类器’,整个Google net结构中一共只有2个辅助分类器,它们都是完全相同的,每一个辅助分类器都相当于一个输出,则整个Googlenet一共有3个输出(两个辅助分类器和一个输出),如下图

辅助分类器是为了防止梯度消失,提供正则化,注入梯度,让底层更好的演化,学习得到更好的分类特征,让它尽快地收敛。

首先经过一个5*5的全局平均池化,strdie为3,再经过一个1*1的卷积层,s=1,进行一个降维的处理,在卷积过后使用了一个relu激活函数(图上没有标出,要注意),然后经过两个全连接层,第一个全连接层之后使用了一个relu激活函数,之后在这个relu后面有一个dropout函数(图中未画出),失活率为0.7最后经过一个softmax激活函数,得到我们的结果。

inceptionv2(bn-inception)2015.12

v2中加入 batch normalization 加快训练,而v3是对inception模块进行进一步调整(v2和v3是写在同一篇论文中,同时发布的)

v2和v3是受到了NiN模块的启发,本篇文章不对NiN做解释,有兴趣的可以自己了解

在讲v2之前,我们先讲讲什么是batch normalization

在我们将图片输入到我们的网络中之前,我们会将我们的图片进行预处理,使我们的图片具有某一特征,从而加快我们的收敛速度,但是在我们进行了预处理,将图片输入到第一个卷积层之后,我们的图片往往就不具有这一特征了,为了让我们卷积后的图片依然具有某一特征,我们就要对图片进行一些批量化标准处理,即batch normalization,简写为‘bn层’

bn层就是让我们经过第一次卷积过后的feature map具有‘均值为0,方差为1’这一特点,这样在输入第二个卷积层之后,我们就能收敛更快。

 我们通过上图给的公式,对第一个feature map进行转化。

下图是我们给的一个例子我们输入的数据,只能对来自同一个channel的数据进行bn操作

u是一个向量,有两个值1和0.5,1是channel1的平均值,即u_1=1,2是channel的平均值,即u_2=0.5,u=[1,0.5],\delta^2=[1,1.5],1是channel的方差,1.5是cahnnel2的平均值,即\delta ^2_1=1,\delta ^2_2=1.5,代入我们的公式,计算每一个值 其中\epsilon 是一个很小的值,为了防止\delta^2

为0的情况, 代入公式后,我们就可以得到对应的值,如下图右边部分。

该公式中有两个参数γ和β,这两个参数是通过我们的反向传播得到的,但这两个参数我们会提前给出两个初始值,我们令γ=1,β=0,传入我们的网络中,最后再通过反向传播来更新我们的这两个参数。

这里稍作一下补充

1.我们使用bn层的时候建议将我们的bn层放在卷积层和激活层之间,并且不要使用我们的bias,因为没有什么用,我们代入bias时u_1后面会多一个b,x_i后面也会有一个b,而方差在加入bias之前和之后,都是不变的,最终我们的数据求出来时不变的,但如果你真的要用bias的话,会占据系统大量的内存,故最好不使用。

2.我们的batch_size尽量设置的大一些,若我们的batch_size设置的特别小,则我们的表现情况会特别糟糕,我们的batch_size设置得越大,我们的去求出来的方差和均值就越接近我们整个数据的方差和均值。

3.无论我们使用的时tensorflow还是pytorch,在我们训练的时候我们都要进行以下操作

若我们使用的是tensorflow,我们在训练时要将我们的tranning参数设置为True,在验证的时候,要将我们的tranning参数设置为False,在训练的时候,每跑完一个epoch,我们就要更新我们的各种参数,故要将tranning设置为True,在验证的时候,我们将我们训练得出的均值和方差值作为一个标准,我们验证的时候,就是将我们验证集得出的参数和我们的训练得出的参数作为比较,故我们不需要更新我们的参数,就将我们的tranning设置为False,在我们使用pytorch的时候也是这样,只不过在pytorch中,我们是用model.train()和model_eval()来完成相关的操作。

-----------------------------------------------------手动分割线-------------------------------------------------------------

这里我们补充一点课外知识------迁移学习(虽然和inception没有什么关系,但就是很想讲)

当我们的网络很大很复杂的时候,我们的要得到一个训练效果比较好的网络时,我们就需要大量的数据,但有的时候,我们网络网络很复杂的时候,碰巧,我们的数据很少,如果我们将很少的数据代入我们这个很复杂的网络中,就很容易出现过拟合的情况,我们得到的模型的泛化能力就不太好,若我们的网络很复杂,并且我们的数据很多的时候,我们将这些数据带入我们的网络,为了得到一个比较完美的模型,我们要跑很多个epoch才行,并且我们的训练速度很慢,这时候我们就可以使用迁移学习的方法,所谓迁移学习,就是使用别人网络中已经训练好的模型参数。

迁移学习有两大好处:1.能够加快网络的训练速度,网络的收敛很更快。2.即使我们只有很少的数据集,也能得到很好的效果。

但是在我们使用迁移学习的时候,我们需要注意我们数据的预处理方式,我们使用的是别人的与预训练参数,我们对数据采取预处理时,也要使用别人的预处理方式,不然收敛速度会很慢。

常见的迁移学习方法有三种

1.使用了别人预训练模型参数后,训练我们网络的所有参数

2.使用了别人预训练模型参数后,只训练我们网络中的全连接层网络,在使用全连接层时,要将我们全连接层的节点数改为我们样本所需的分类个数

3.在原有的网络基础上,在整个网络的最后,再加一层全连接层,并且只训练这个添加的全连接层。

inceptionv2中就是融入了bn元素,还取消了LRN模块(v1中是使用了LRN模块的)

LRN模块又叫‘(局部相应归一化)’,我们以下图举一个例子

 如图我们的feature map通道数为4,就和下图的一样

 我们要将上图鼠标所指的3进行归一化,将这个值相邻的两个值找出来,由上图我们可以知道(就是每个3*3矩形最中间的值)为3和2,我们将鼠标所指的值作为分子,那四个值得平方和作为分母,就是3/(3^2+3^2+2^2)约等于0.14,我们的分子永远是我们想要归一化的那个值,我们的分母会根据不同的情况而改变,我们刚刚举的例子是相邻的两个值,我们也可以相邻的三个值,也可以是所有通道的值,即3/(3^2+3^2+2^2+2^2)约等于0.12,这样做的好处是同一位置,不需要太多的高激活神经元,起到一个侧向抑制的作用

我们给出LRN的公式

 就是我们分母求平方和的过程,N是我们的总通道数,n是我们要找的相邻的通道个数,k是一个很小的数,防止我们分母为0的情况,分子就是我们想要进行LRN的数,α和β是两个常数,我们这里不做讲解,有兴趣的同学可以自己了解。

在Alexnet中就用到了LRN

Alexnet的论文中认为,归一化有以下的好处

(1)为了后面数据处理的方便,归一化的确可以避免一些不必要的数值问题。
(2)为了程序运行时收敛加快。 下面图解。
(3)同一量纲。样本数据的评价标准不一样,需要对其量纲化,统一评价标准。这算是应用层面的需求。
(4)避免神经元饱和。啥意思?就是当神经元的激活在接近0或者1时会饱和,在这些区域,梯度几乎为0,这样,在反向传播过程中,局部梯度就会接近0,这会有效地“杀死”梯度。
(5)保证输出数据中数值小的不被吞食。

(6)防止了过拟合的情况

在Alexnet中是这样想的,但是在VGG的论文中,做了一个对照试验,发现无论用不用LRN层,都没有太大影响,而且使用LRN层只会增加内存和计算量。

课外知识补充结束

-----------------------------------------------------手动分割线-------------------------------------------------------------

所以在inceptionv2的网络中,舍弃了LRN这个模块

这里小小的总结一下,v2版本融入了bn元素,取消了LRN的结构

v2中还使用了小卷积核代替大的卷积核

例如用两个3*3的小卷积核代替一个大的5*5卷积核,这样做可以减少参数量,增加了网络的2非线性表达能力,同时两个3*3和一个5*5具有相同的感受野,和VGG的思想是相同的

v2的结构图如下,v2中还舍弃了全连接层

第一列:输入尺寸和stride;第二列输出的尺寸;第三列:网络的深度,池化层的深度为0;第四到六列:如下图所示;可以根据v1中的结构类推

inceptionv3(对 inception 模块做了调整)2015.12

v3和v2是在同一篇论文中的,是同时发布的

v2是使用了小的卷积核来代替大的卷积核,而v3在v2的基础上,将小的卷积核进一步拆分

我们常见的卷积核比如1*1,3*3,5*5等等,这些卷积核的长和宽都是相同的卷积核,我们把它叫做对称的卷积核,而在v2中,我们使用了不对称的卷积核。如1*3和3*1,这种就是不对称的卷积核,不对称的卷积又叫空间可分离的卷积。

当我们对一张走廊,过道的图片卷积的时候,我们的使用一个对称的卷积核提取出来的特征就不太好,假如我们用一个不对称的卷积来提取特征的话,效果就很好(因为走廊和非对称的卷积核都是长条形状的)

我们可以把一个对称的3*3卷积核分解成两个不对称的卷积核,分别是1*3和3*1(注意是先1*3后3*1,顺序不能交换),这样可以将卷积核进一步的拆分,从而进一步地降低参数量和计算量

v3中使用也使用了v2中的思想,将一个5*5变成两个3*3,同时也使用了将一个对称的卷积核变成两个非对称卷积核的思想。

在v3中一个5*5可以变成两个3*3,而一个3*3可以变成一个1*3和一个3*1,如下图所示

以上是比较正常的拆分方式

同时v3中还有一些不正常的拆分方式,如下图所示。

一个5*5可以变成两个3*3,一个3*3可以变成一个1*3和一个3*1

但是它一个5*5居然可以变成一个1*7和一个7*1(这是一种很特别的情况)

还有其他的替换方式 

这个是我们原先的图

它用一个1*7和一个7*1替换了一个3*3

用一个1*7,一个7*1 ,一个1*7,一个7*1 替换了一个5*5,这两种情况也很特殊

 

这里做一个小总结,v3使用了小卷积核替换大卷积核的思想,一个小卷积核又被拆分成了两个非对称卷积核 

但是v3还有更加离谱的事情,它将拆分得到的两个非对称卷积核并行排列,我们将非对称的卷积核串联的时候,我们是沿深度展开,我们将其并联的时候,我们是沿着宽度展开,这样的作用是为了用于增加表示维度,来增加信息用的

同时v3的分辨率从224*224变成了299*299,分辨率变了之后,我们输入的图片的大小一定要是299*299的。

v3的结构图如下图所示(箭头567所指的部分分别为inception的ABC模块)

在v1的时候我们讲过,v1中有两个相同的辅助分类器,但是在v3中,我们舍弃了一个分类器

在v1中,我们认为辅助分类器有以下作用

辅助分类器是为了防止梯度消失,引入正则化,注入梯度,让底层更好的演化,学习得到更好的分类特征,让它尽快地收敛。

但是在v3的论文中,作者发现底层的分类器并没有什么用,并不能加速网络的收敛,就将这个分类器舍弃掉了,故v3中只有一个辅助分类器和一个出口。

下采样模块

池化层又叫下采样层,我们普通的池化,要么是先用步长为一的卷积核卷积,再池化用步长位2的池化核池化,就是先增维,再池化;要么直接用步长为2的卷积核直接下采样,计算量不大,但是它会造成信息的缺失。

于是v3中引入了下采样模块,将卷积和池化一起并联,一边卷积增维,一遍下采样卷积

下面两个图表示相同的操作,扩充通道的同时下采样,又保证了计算效率。

总结:v3和v2一样,将大卷积核拆分成了小的卷积核,同时将小卷积核拆分成了非对称的卷积核,拆分方式有正常的和不正常的,小的卷积核可以串联,也可以并联,同时分辨率从224*224变成了299*299,舍弃了一个辅助分类器,使用了下采样模块。

其实v3中还有RMSProp优化器、Label Smoothing正则化(由于实在太多了,先挖个坑,以后填)

resnet 2015(它不是我们inception家族的一份子,但我们还是要讲讲)

resnet是2015年微软实验室提出的,斩获ImageNet竞赛中,分类任务第一名,目标检测第一名。COCO数据集中目标检测第一名,图像分割第一名。

resnet最核心的部分就是引入了残差结构,人们发现,随着网络层数的加深,网络梯度消失和梯度爆炸的情况越来越明显,假设我们的误差梯度是一个大于1的数,在我们反向传播的过程中,每向前传一层,我们就要乘上这个大于1的数据,就会造成梯度爆炸,若我们的梯度误差是一个小于1的数,我们反向传播每向前传一层,我们就要乘上一个小于1的数,最后就会变成梯度消失,一般我们解决这种问题,是采用标准化处理,权重初始化,采用bn层处理;在我们解决了梯度消失和梯度爆炸的问题后,还可能会有网络的退化问题,退化问题用一句话来解释:“层数深的网络的效果没有层数少的网络效果好”resnet的提出,就是为了解决类似于vgg中的那种网络的退化问题。

下图是两个resnet中的残差结构,这里resnet就不细讲了(挖个坑,以后填)有兴趣的自己去了解

左边是适用于网络层数较少的情况,右边是适用于网络层数较深的情况

 resnet种有两种结构,一种是实线结构,一种是虚线结构

 

inceptionv4 2016.2

inception-resnet-v1(在Inception-v3上加入ResNet) 2016.2(和v3十分相似)

inception-resnet-v2(在Inception-v4上加入ResNet) 2016.2(和v4十分相似)

三个网络是出现在一篇论文中,三个网络一起讲

基于 ResNet 加入了 残差连接

v4模型在v3模型上进一步对inception模块进行了改进,同时则更加了inception模块的个数

如下是v3的结构图,原先ABC模块中的个数分别为3,4,2但是在v4中变成了4,7,3,同时对inception模块进行了一些微调和更新

 v4比v3更加的复杂,计算效率比v3更加的小,但是准确率相对于v3有了很大的提升

以下是v4的结构图

 其中的stem模块展开了如下图所示

 stem模块中得出来的35*35*384由图可知,最后会喂到我们的inceptionA模块中,传到inceptionC之后,就变成了8*8*1536,我们对每一个8*8求一个全局平均值,则最后,我们最终我们会得到1536个全局平均值。

在inceptionB和reductionB中间任然有一个辅助分类器,只不过图中没有画出来,即v4任然有两个出口

其中的reductionA模块(下采样模块A)如下图

 reductionB模块(下采样模块B)如图

 而inceptionV4中ABC模块如下图(三个模块的池化都是3*3)

下面直接给一张保姆级的全图(其中的k,l,m,n表示卷积核的个数)

 inception-resnet v1和v3十分相似,  inception-resnet v2和v4十分相似,但是由于 inception-resnet v1和 inception-resnet v2具有残差结构,所以收敛速度更快,但是准确率最后都差不多

下图分别是v4和inception-resnetv1,v2的主干结构图

 下图是三种网络的stem结构,其中v4和inception-resnet v2的stem结构是一样的,

inception-resnet v2

 

inception-resnet中的两个网络中的inception-resnetABC模块如下图所示

 

 inception-resnet中的reductionAB模块如下图所示

A模块两个网络是相同的

 

xception(在v3基础上基于mobilenet和resnet)2016.10

在讲之前,希望大家已经提前了解了dw卷积核pw卷积的相关知识

(4条消息) mobilenetv1,v2,v3简要介绍_Pierrot_Sgr的博客-CSDN博客

也可以看看我之前些的mobilenet网络的博客,里面有pw核dw的相关知识。

下图是关于pw和dw卷积

 pw是每一个通道单独用一个卷积核处理,如果有三个通道,就用三个卷积核,最后得到三个结果concatenate一起,concatenate一起之后,进行dw卷积,用一个与它们通道数相同的1*1卷积核进行卷积,pw卷积是一种跨通道的卷积,会造成信息缺失,所以我们要使用dw卷积,得到新的feature map。

xception是在v3的基础上,结合了mobilenet与resnet的思想诞生的

下图是从v3演变成xception的过程

将v3中的一个1*1卷积核变成了3*3

 将第一层全部变成1*1,第二层全部变成3*3

 第一层共用一个1*1卷积

 1*1卷积后,每个3*3卷积核只处理整个通道的三分之一

 到了极致版本,一个3*3只处理一个通道

 到了这里就有了pw和dw的影子,mobilenet中是先进行pw分组卷积,然后再进行dw卷积,但是在xception中是先进行1*1dw卷积,再进行pw分组卷积,在xception的论文中讲述了,无论哪种卷积先,都对差别不大(dw和pw卷积的作用是减少了参数量和计算量)

xception中有三个结构,entry flow,middle flow,exit flow ,其中的SeparableConv就是dw+pw+concatenate

 

其中也有resnet残差网络的影子,残差网络可以大大加快网络的收敛速度和性能,同时不难看出,它的分辨率也是299*299

这里做一点补充,xception在 pw之后和dw之前,不采用激活函数的效果是最好的

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虽然她送了我玫瑰花

谢谢老板,老板大气,身体健康

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值