网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
1. LeNet5
LeNet5 诞生于 1994 年,LeNet做为CNN的经典网络结构,结构如下。
LeNet5特征能够总结为如下几点:
1)卷积神经网络使用三个层作为一个系列: 卷积,池化,非线性
2) 使用卷积提取空间特征
3)使用映射到空间均值下采样(subsample)
4)双曲线(tanh)或S型(sigmoid)形式的非线性
5)多层神经网络(MLP)作为最后的分类器
6)层与层之间的稀疏连接矩阵避免大的计算成本
2.AlexNet
网络结构
如下图所示,8层网络,参数大约有60 million,使用了relu函数,头两个全连接层使用了0.5的dropout。使用了LRN和重叠的池化,现在LRN都不用了,一般用BN作Normalization。当时使用了多GPU训练。
预处理
先down-sample成最短边为256的图像,然后剪出中间的256x256图像,再减均值做归一化(over training set)。 训练时,做数据增强,对每张图像,随机提取出227x227以及水平镜像版本的图像。除了数据增强,还使用了PCA对RGB像素降维的方式来缓和过拟合问题。
预测
对每张图像提取出5张(四个角落以及中间)以及水平镜像版本,总共10张,平均10个预测作为最终预测。
超参数
SGD,学习率0.01,batch size是128,momentum为0.9,weight decay为0.0005(论文有个权重更新公式),每当validation error不再下降时,学习率除以10。权重初始化用(0,0.01)的高斯分布,二四五卷积层和全连接层的bias初始化为1(给relu提供正值利于加速前期训练),其余bias初始化为0。
3.VGG
网络结构
如下图所示,VGG-16,16层,参数大约有138 million。实验发现LRN的加入没有提升反而更差,舍弃使用。实验发现1x1效果更差,于是没有使用,1x1卷积在Network in Network(颜水成)中提出推广,是很重要的思想,在GoogleNet和ResNet都有用到。
使用小卷积核3x3可以捕捉左右上下的信息,而且利于堆叠深度(保证参数不要过大)。步长为1。same卷积。
两个3x3卷积可以和5x5卷积达到一样的感受野。三个3x3卷积可以和7x7卷积达到一样的感受野。使用三个3x3的好处在于使用了3个非线性变换,同时后减小了参数.假设输入输出通道数一样,那么有
和AlexNet一样,头两个全连接层后面加0.5的dropout。
超参数
和AlexNet基本一致。batch size是256。初始化也是用(0,0.01)的高斯分布,只不过VGG先训练一个浅层的网络,然后把浅层网络的部分参数来初始化深层网络部分参数,其它参数还是用高斯分布。值得注意的是论文提交后VGG发现使用glorot的初始化方法可以不用预训练。
预处理
和AlexNet不同,在下采样的时候不是变成256,变成一个S,S有两种方法来设定。第一个方法是固定的S(single-scale),固定为256或384。为了加速384的网络,用256预训练的模型进行权重初始化。另外学习率调小为0.001。第二个方法从[256, 512]中随机采样S(multi-scale,注意这里的是multi-scale training,和overfeat中的multi-scale test含义不一样),这可以看成用尺寸抖动(scale jittering)对训练集进行增强。为了加速,使用384预训练的模型进行权重初始化。
预测
采用了AlexNet的10 views法(VGG论文中把它称作multi-crop评估)和overfeat的多尺度预测方法(VGG论文中把它称作dense评估)相结合。在OverFeat已经提到了multi-crop是有缺点的,存在冗余的卷积计算,所以使用了dense评估,但是Inceptionv1的论文中提到multi-crop使用大量crops能提高准确率因为它的采样更精细。而VGG认为实作上准确率的提升不足以弥补速度,但是为了参考起见,还是跑了multi-scrop的方法。在实验中,两者结合优于multi-crop优于dense,好那么一点点,差别不大。
4.GoogleNet
Inceptionv1
网络结构
如下图所示为Inception块。网络总共有22层,图太大,这里就给个表格。可以看到虽然把全连接替换成了全局均值池化(这后面还是使用了0.4的dropout),但是网络图中最后还是有一个全连接层,这是为了便于把网络fine tune到其它数据集。
参数
为了提升模型表现,典型的办法是增大模型(增加深度或宽度),但是这样会带来过大的参数,然后导致计算资源增大而且需要的数据更多(而高质量数据往往是昂贵的),所以要考虑降低参数。Inceptionv1虽然有22层的参数却只有5 million,是同期VGG16(138 million)的1/27,是AlexNet(60 million)的1/12而准确率却远胜AlexNet。
1x1卷积好处
减小了参数,允许增加深度; 可以降维,构建瓶颈层来减小计算成本,Inception块中就是通过在3x3和5x5后面加入1x1来减小计算;增强了网络的表达能力(可以根据自己的意愿,或压缩或增加或保持通道数)。还有配合全局均值池化来代替全连接层,这个就是为了能大大减小模型的参数。1x1的思想也来自Network in Network。
超参数和预处理
因为比赛的过程做了很多变动,包括采样方法和各种超参,所以很难定义一个有效的指导去训练这个网络。只给出了几个超参数,固定学习率,每8epoch下降4%,momentum是0.9。
预测:先下降样出256,288,320和352大小,分别从左中右三个方位裁(如果是人画像则从上中下三个方位裁),然后从4 corners和center剪出224x224再加上把正方形缩放到224,以及它们的水平镜像。这样就可以得到4x3x6x2也就是144个crops,最后对crops取平均。
Inceptionv2
网络结构
如下图所示,主要改变有,用两个3x3代替5x5,28x28的Inception块从2个变成了3个,pooling时有些是avg有些是max,在Incetpion块之间不再有额外的max-pool而是直接把卷积和池化的stride设置为2。BN被用在每一个输入层后面(先BN再激活)。batch size为32。网络使用DistBelief(Tensorflow前身)训练
其它变动
增大学习率并加快学习率衰减(适用BN后的数据),移除dropout并减小L2权重衰减(BN有一定的正则效果),去除LRN(发现用了BN后不需要LRN了),更彻底对训练样本进行shuffle,减小数据增强时对数据的光学畸变(因为BN训练更快,每个样本被训练次数变少,模型需要注重更真实的样本)。
Inceptionv3
v2网络结构
共42层,网络图就不放了,主要改动有如下。各个改动模块图可以参考后面v4的结构图。
- 修改部分Inception块,使5x5分解成2个3x3卷积(可参考下面v4的InceptionA)。
- 修改部分Inception块,分解成非对称卷积(把nxn分解成1xn和nx1卷积,这里n=7。注意原始结构并没有7x7卷积)(可参考下面v4的InceptionB)。
- 修改部分Inception块,扩大卷积核数量(汇聚的分支数量)(可参考下面v4的InceptionC)
修改部分Inception块,减小特征图大小(使用并行的stride为2的卷积和池化)(可参考下面v4的Reduction)
v3网络结构
在以上基础上,加入如下改动
用RMSProp训练,decay为0.9,ϵ为1.0
使用Label smoothing进行模型正则
开头第一层7x7分解成3个3x3卷积
加入带BN的辅助分类器
Inceptionv4,Inception-ResNet
v4网络结构:如下第一个图是v4。
Inception-ResNet
探索了多种Inception-ResNet,论文只阐述了两个。其中Inceptin-ResNet-v1和Inceptinv3计算代价差不多,Inceptin-ResNet-v2和Inceptionv4计算代价差不多,然而实作上Inceptionv4慢很多可能是因为层数太多。在带有ResNet的Inception中,还有一个和纯Inception的不同点是只在传统层上使用BN,不在BN层上使用,这样可以减小计算从而堆叠更多Inceptin块。
Inception-ResNet-v2结构
如下第二个图是Inception-ResNet-v2(输出的shape是Inception-ResNet-v1的)。
5.ResNet
网络加深
对于网络加深,会出现梯度消失或梯度爆炸,这个问题可以通过正则初始化(何凯明初始化等等)和BN来解决。
退化问题
然而深层网络到了一定深度,准确率趋近饱和,而且继续加深的话会降低准确率,这称为退化问题(degradation),而且这个问题并不是过拟合导致的(过拟合在训练集应该更好),也不是梯度消失造成的(论文检查了梯度)。
残差块
为了解决退化问题,提出了残差学习,如下图所示为残差块,假设本来是要学习H(x),加了一条恒等映射之后我们要学习的就是F(x) = H(x) - x,(假设)学习F(x)会比学习H(x)更容易,最极端的情况就是假设我们要学习的映射是x,那么让F(x)为0,比学习到H(x)为恒等映射要容易。这种做法的motivation是,如果增加的层能被构建成恒等映射层,那么一个更深的网络的准确率至少不会低于浅层网络。
残差块的相加
当残差块的输入和输出不是相同维度时(因为部分残差块会使用stride为2的卷积来降采样),有两种方法来保证维度一致,一个是补0,另一个是乘以W矩阵做映射(使用1x1卷积)。
训练配置
预处理时像VGG一样随机采样[256, 480]的scale,然后像AlexNet一样crop出224x224的图像以及水平翻转,然后做mean substracted。预测时候使用AlexNet的10-crop测试法,最好的结果是跟从VGG中的全卷积后的multi-scale评估,scale为{224, 256, 384, 480, 640}。在每个卷积的激活前使用BN,不使用dropout。何凯明初始化。SGD,batch size为256,学习率从0.1开始每次错误率平缓时就除以10,模型训练了60万个iteration,权重衰减为0.0001,momentum为0.9。
Identity和projection
对于残差块的相加,有三种配置,A配置是捷径用identity,需要增加维度时的捷径补0。B配置是捷径一般都用identity,但是增加维度时使用映射。C配置是所有捷径都使用映射(1x1卷积)。表现是C>B>A,但是三者差异不大,实作上不会使用C,因为C增加了参数和计算。
网络结构
论文阐述了ResNet-18-34-50-101-152。其中ResNet-18/34使用配置A,ResNet-50/101/152使用配置B,此外使用了bottleneck结构,如下第一个图的右图所示。
6.preresnet
分析
ResNetv1的公式如下,论文分析了h函数和f函数的选取,即shortcut路径的函数选取,以及addition后的操作选取。在ResNetv1中,h函数为恒等映射,f函数为relu函数,如下图(a)所示。
h函数的选取
论文分析了h函数选取为恒等映射,做常数scale,异或,1x1卷积,dropout时的表现,发现恒等映射的表现最好,主要是通过实验来分析。
f函数的选取
由于h函数使用恒等映射表现最好,下图的分析中h函数都使用的恒等映射。下图(a)表示f函数为Relu,这是ResNetv1的做法。下图(b)表示f函数为BN+Relu。下图©表示f函数为恒等映射(Relu放到addition前)。下图d表示f函数为恒等映射,但是把最后一个Relu放在下一个残差块的F-path中。下图e和图d类似,只不过把BN也放在addition后的下一个残差块的F-path,ResNetv2使用的就是图e的结构,通过实验发现这个结构表现最好。
f和h函数都为恒等映射
ResNetv2采取图e的结构,此时f和h函数都为恒等映射,那么上式可以写成下式,可以看到这样的式子有几个特点,首先,不管L和l差多少层,xL和xl总是相差一个残差函数;其次,普通网络输入和输出的关系是很多个Wx相乘(忽略激活和BN的话),而这里是各个残差函数相加;另外,从求导式看,1+后面那一项不会总是为-1(对一个mini-batch的样本来说),所以梯度很难为0。
训练配置
和ResNetv1基本一致。对于CIFAR的实验前400个iteration用0.01(warming up),之后恢复0.1,尽管观察到这对于残差块没有必要。对于ImageNet实验,学习率为0.1(no warming up),在30轮和60轮除以10。在ResNet的开头第一个残差块和最后一个残差块是特殊case,第一个残差块的激活会放在后面的“单独卷积”之后和分成两路之前,最后一个残差块的激活放在它的addition之后。
7.resnext
贡献
网络结构简明,模块化
需要手动调节的超参少
与 ResNet 相比,相同的参数个数,结果更好:一个 101 层的 ResNeXt 网络,和 200 层的 ResNet 准确度差不多,但是计算量只有后者的一半.
方法
提出来 cardinality 的概念,在上图左右有相同的参数个数,其中左边是 ResNet 的一个区块,右边的 ResNeXt 中每个分支一模一样,分支的个数就是 cardinality。此处借鉴了 GoogLeNet 的 split-transform-merge,和 VGG/ResNets 的 repeat layer。
所谓 split-transform-merge 是指通过在大卷积核层两侧加入 1x1 的网络层,控制核个数,减少参数个数的方式。借鉴 fei-fei li 的 cs231n 课件
而 repeat layer 则是指重复相同的几层,前提条件是这几层的输出输出具有相同的维度,一般在不同的 repeat layers 之间使用 strip=2 降维,同时核函数的个数乘 2。
网络参数
以上图为例,中括号内就是 split-transform-merge,通过 cardinality© 的值控制 repeat layer。
output 在上下相邻的格子不断减半,中括号内的逗号后面卷积核的个数不断翻倍。
等价模式
图一右侧的模型有两个等价的模型,最右侧是 AlexNet 中提出的分组卷积,相同层的 width 分组卷积,最终作者使用的是下图最右边的模型,更加简洁并且训练更快。
8.densenet
文章提出的DenseNet(Dense Convolutional Network)主要还是和ResNet及Inception网络做对比,思想上有借鉴,但却是全新的结构,网络结构并不复杂,却非常有效!众所周知,最近一两年卷积神经网络提高效果的方向,要么深(比如ResNet,解决了网络深时候的梯度消失问题)要么宽(比如GoogleNet的Inception),而作者则是从feature入手,通过对feature的极致利用达到更好的效果和更少的参数。博主虽然看过的文章不算很多,但是看完这篇感觉心潮澎湃,就像当年看完ResNet那篇文章一样!
先列下DenseNet的几个优点,感受下它的强大:
1、减轻了vanishing-gradient(梯度消失)
2、加强了feature的传递
3、更有效地利用了feature
4、一定程度上较少了参数数量
几张图可以看出densenet的思想和结构
9.SENet(Squeeze-and-Excitation Networks)
参考链接:
https://www.cnblogs.com/bonelee/p/9030092.html
https://blog.csdn.net/yimingsilence/article/details/79233650
通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征.
已经有很多工作在空间维度上来提升网络的性能。那么很自然想到,网络是否可以从其他层面来考虑去提升性能,比如考虑特征通道之间的关系?我们的工作就是基于这一点并提出了 Squeeze-and-Excitation Networks(简称 SENet)。在我们提出的结构中,Squeeze 和 Excitation 是两个非常关键的操作,所以我们以此来命名。我们的动机是希望显式地建模特征通道之间的相互依赖关系。另外,我们并不打算引入一个新的空间维度来进行特征通道间的融合,而是采用了一种全新的「特征重标定」策略。具体来说,就是通过学习的方式来自动获取到每个特征通道的重要程度,然后依照这个重要程度去提升有用的特征并抑制对当前任务用处不大的特征。
上图是我们提出的 SE 模块的示意图。给定一个输入 x,其特征通道数为 c_1,通过一系列卷积等一般变换后得到一个特征通道数为 c_2 的特征。与传统的 CNN 不一样的是,接下来我们通过三个操作来重标定前面得到的特征。
首先是 Squeeze 操作,我们顺着空间维度来进行特征压缩,将每个二维的特征通道变成一个实数,这个实数某种程度上具有全局的感受野,并且输出的维度和输入的特征通道数相匹配。它表征着在特征通道上响应的全局分布,而且使得靠近输入的层也可以获得全局的感受野,这一点在很多任务中都是非常有用的。
其次是 Excitation 操作,它是一个类似于循环神经网络中门的机制。通过参数 w 来为每个特征通道生成权重,其中参数 w 被学习用来显式地建模特征通道间的相关性。
最后是一个 Reweight 的操作,我们将 Excitation 的输出的权重看做是进过特征选择后的每个特征通道的重要性,然后通过乘法逐通道加权到先前的特征上,完成在通道维度上的对原始特征的重标定。
上左图是将 SE 模块嵌入到 Inception 结构的一个示例。方框旁边的维度信息代表该层的输出。
这里我们使用 global average pooling 作为 Squeeze 操作。紧接着两个 Fully Connected 层组成一个 Bottleneck 结构去建模通道间的相关性,并输出和输入特征同样数目的权重。我们首先将特征维度降低到输入的 1/16,然后经过 ReLu 激活后再通过一个 Fully Connected 层升回到原来的维度。这样做比直接用一个 Fully Connected 层的好处在于:1)具有更多的非线性,可以更好地拟合通道间复杂的相关性;2)极大地减少了参数量和计算量。然后通过一个 Sigmoid 的门获得 0~1 之间归一化的权重,最后通过一个 Scale 的操作来将归一化后的权重加权到每个通道的特征上。
10. BAM: Bottleneck Attention Module
我们把重心放在了Attention对于一般深度神经网络的影响上,我们提出了一个简单但是有效的Attention 模型—BAM,它可以结合到任何前向传播卷积神经网络中,我们的模型通过两个分离的路径 channel和spatial, 得到一个Attention Map.
这里作者将BAM放在了Resnet网络中每个stage之间。有趣的是,通过可视化我们可以看到多层BAMs形成了一个分层的注意力机制,这有点像人类的感知机制。BAM在每个stage之间消除了像背景语义特征这样的低层次特征,然后逐渐聚焦于高级的语义–明确的目标(比如图中的单身狗)。
Spatial attention branch
这个空间分支产生了空间Attention去增强或者抑制特征在不同的空间位置,众所周知,利用上下文信息是去知道应该关注哪些位置的关键点。在这里我们为了高效性运用空洞卷积去增大感受野。
我们观察到,与标准卷积相比,空洞卷积有助于构造更有效的spatial map.
细节图:
11.CBAM: Convolutional Block Attention Module
Convolutional Block Attention Module (CBAM) 表示卷积模块的注意力机制模块。是一种结合了空间(spatial)和通道(channel)的注意力机制模块。相比于senet只关注通道(channel)的注意力机制可以取得更好的效果。
它依然采用了block的形式,但是在每一个block上进行更加细致的设计来使得网络的结构更加合理有效。
整体的结构如下图
作者采用了类似于人类attention,也就是注意力的机制,对一个特征矩阵进行重新构造。注意力机制其实并不复杂,就是采用一种可以学习的方式来对特征重新赋予权重,权重高的特征就是注意力的注意点。
注意力
从上面的结构图可以看到,一个特征经过一个Channel Attention Module和一个Spatial Attention Module被重新构造,输出了一个精修过的特征矩阵。
通道注意力
首先是通道注意力,我们知道一张图片经过几个卷积层会得到一个特征矩阵,这个矩阵的通道数就是卷积层核的个数。那么,一个常见的卷积核经常达到1024,2048个,并不是每个通道都对于信息传递非常有用了的。因此,通过对这些通道进行过滤,也就是注意,来得到优化后的特征。
主要思路就是:增大有效通道权重,减少无效通道的权重。
公式如下:
结构如下:
在通道维度上进行全局的pooling操作,再经过同一个mlp得到权重,相加作为最终的注意力向量(权重)。
这里非常像SENet,SENet在很多论文中都被证实对效果有提升,这里的区别是,SENet采用的是平均值的pooling,这篇论文又加入了最大值pooling。作者在论文中,通过对比实验,证实max pooling提高了效果。
注意这里的mlp的中间层较小,这个可能有助于信息的整合。
空间注意力
论文中,作者认为通道注意力关注的是:what,然而空间注意力关注的是:Where。
公式如下:
结构如下:
模型
下图是一个将论文的方法应用到ResNet的例子:
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
[外链图片转存中…(img-GCEo6aA5-1715738028917)]
[外链图片转存中…(img-PEEr4L3q-1715738028918)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新