卷积神经网络
作者:互联网
1,交叉相关,卷积
假设我们现在要做猫狗分类,如果还是用单纯的MLP(全连接)做的话,由于图片有很多的像素点,那么我们的输入就会有很多,对应就要有更多的参数。想要训练这个模型将不可实现,因为需要有大量的GPU、分布式优化训练的经验和超乎常人的耐心。但是其实不用,图像中本就拥有丰富的结构,而这些结构可以被人类和机器学习模型使用。卷积神经网络(convolutional neural networks,CNN)是机器学习利用自然图像中一些已知结构的创造性方法。
处理视觉任务的网络架构应该具备的两个特点:
!平移不变性(translation invariance):不管检测对象出现在图像中的哪个位置,神经网络的前面几层应该对相同的图像区域具有相似的反应,即为“平移不变性”。(比如要识别一张照片上面猫是否存在,就要在猫在照片中处于不同的位置的情况下时都能正常工作。)
!局部性(locality):神经网络的前面几层应该只探索输入图像中的局部区域,而不过度在意图像中相隔较远区域的关系,这就是“局部性”原则。最终,可以聚合这些局部特征,以在整个图像级别进行预测。
单通道卷积:
输出大小略小于输入大小。这是因为卷积核的宽度和高度大于1,而卷积核只与图像中每个大小完全适合的位置进行互相关运算。
如果输入大小Nh×Nw,且卷积核步长为1,卷积核大小Kh×Kw输出的维度是:
总结:
!卷积层将输入和核矩阵进行交叉相关(这里注意我们虽然叫做卷积。是因为交叉和卷积实际上很相近,只不过做卷积卷积核要做180度的翻转,所以其实严格来说我们说卷积神经网络说错了,实际上做的只是交叉相关运算),加上偏移之后得到输出。
!核矩阵和偏移是可以学习的参数。
!核矩阵的大小是超参数。
2,卷积核可以帮助发现图像的信息,比如边缘检测中,如下面的例子:
如果我们只需寻找黑白边缘,那么以上[1,-1]的边缘检测器足以。然而,当有了更复杂数值的卷积核,或者连续的卷积层时,我们不可能手动设计滤波器。那么我们是否可以学习由X生成Y的卷积核呢?
现在让我们看看是否可以通过仅查看“输入-输出”对来学习由X生成Y的卷积核。 我们先构造一个卷积层,并将其卷积核初始化为随机张量。接下来,在每次迭代中,我们比较Y与卷积层输出的平方误差,然后计算梯度来更新卷积核。所以就像上一小点总结中说的那样,核矩阵和偏移是要学习的参数。这其实也就是卷积神经网络学习参数的基础。
3,卷积的填充和步幅
卷积的输出形状取决于输入形状和卷积核的形状。
还有什么因素会影响输出的大小呢?填充(padding)和步幅(stride)。假设以下情景:有时,在应用了连续的卷积之后,我们最终得到的输出远小于输入大小。这是由于卷积核的宽度和高度通常大于1所导致的。比如,一个240×240像素的图像,经过10层5×5的卷积后,将减少到200×200像素。如此一来,原始图像的边界丢失了许多有用信息。而填充是解决此问题最有效的方法。 有时,我们可能希望大幅降低图像的宽度和高度。例如,如果我们发现原始的输入分辨率十分冗余。步幅则可以在这类情况下提供帮助。
填充:
在应用多层卷积时,我们常常丢失边缘像素。 由于我们通常使用小卷积核,因此对于任何单个卷积,我们可能只会丢失几个像素。但随着我们应用许多连续卷积层,累积丢失的像素数就多了。解决这个问题的简单方法即为填充(padding):在输入图像的边界填充元素(通常填充元素是0)。假如卷积核大小是h*k,
我们可以设置ph=kh−1和pw=kw−1,使输入和输出具有相同的高度和宽度。
假设kh是奇数,我们将在高度的两侧填充ph/2行。如果kh是偶数,则一种可能性是在输入顶部填充⌈ph/2⌉行,在底部填充⌊ph/2⌋行。同理,我们填充宽度的两侧。卷积神经网络中卷积核的高度和宽度通常为奇数,例如1、3、5或7。选择奇数的好处是,保持空间维度的同时,我们可以在顶部和底部填充相同数量的行,在左侧和右侧填充相同数量的列。
步幅:
我们之前使用的步幅是1,有时候为了高效计算或是缩减采样次数,卷积窗口可以跳过中间位置,每次滑动多个元素。我们将每次滑动元素的数量称为步幅(stride)。
步幅可以减小输出的高和宽,例如输出的高和宽仅为输入的高和宽的1/n(n是一个大于1的整数)。在实践中,我们很少使用不一致的步幅,也就是说,我们通常有ph=pw和sh=sw。
小结:
!填充可以增加输出的高度和宽度。这常用来使输出与输入具有相同的高和宽。
!步幅可以减小输出的高和宽,例如输出的高和宽仅为输入的高和宽的1/n(n是一个大于1的整数)。
!填充和步幅可用于有效地调整数据的维度。
4,多输入和多输出通道
多输入通道单输出通道:
其实就是只有单输出通道时,输入多少维,卷积核就有多少维。然后每一维的结果加起来得到输出。如果是多输出通道,那么相对应想要几个输出,就有几个上面单输出通道用到的卷积核,每个输出通道可以识别不同的模式,比如动物的脚,头……
例子,三输入通道,五输出通道,那么就是一个卷积核要有三维,总共有五个卷积核,然后这五个卷积核卷积输入之后得到的五个输出我们称之为五个featuremaps。
1*1卷积层
1×1卷积,即kh=kw=1,看起来似乎没有多大意义。毕竟,卷积的本质是有效提取相邻像素间的相关特征,而1×1卷积显然没有此作用。尽管如此,1×1仍然十分流行,经常包含在复杂深层网络的设计中。因为使用了最小窗口,1×1卷积失去了卷积层的特有能力——在高度和宽度维度上,识别相邻元素间相互作用的能力。其实1×1卷积的唯一计算发生在通道上。总的来说,就是1*1卷积层不识别空间模式,只是融合通道,因为只是将输入的多个通道的每一个特定位置像素进行加权求和而已。
1*1卷积是如何减少权重参数的:
假设现在神经网络某个卷积操作之后的特征图为192 * 28 * 28
即特征图通道为192,特征图大小为28*28
如果直接用一个5*5的卷积去减小通道数到32,权重参数为5*5*192*32=15360
如果先用一个1*1卷积减小到16,再用5*5扩大到32,
权重参数为1*1*192*16 + 5*5*16*32 = 18944.、
5,池化层pooling
(pooling)层,它具有双重目的:降低卷积层对位置的敏感性,同时降低对空间降采样表示的敏感性。
与卷积层类似,池化层运算符由一个固定形状的窗口组成,该窗口根据其步幅大小在输入的所有区域上滑动,为固定形状窗口(有时称为池化窗口)遍历的每个位置计算一个输出。然而,不同于卷积层中的输入与卷积核之间的互相关计算,汇聚层不包含参数。相反,池运算是确定性的,我们通常计算池化窗口中所有元素的最大值或平均值。这些操作分别称为最大池化层(maximum pooling)和平均池化层(average pooling)。在处理多通道输入数据时,[池化层在每个输入通道上单独运算],而不是像卷积层一样在通道上对输入进行汇总。这意味着池化层的输出通道数与输入通道数相同。
最大池化层:把滑动池化窗口最大的值拿出来,其余的丢掉。
平均池化层:对滑动池化窗口内的元素求平均值拿出来。
现在池化层用的越来越少了。李沐认为现在通常直接在卷积中用stride,或者我们会对数据做增强,使得卷积层就已经降低了对位置的敏感性。
6,LeNet(80年代末提出,卷积神经网络的鼻祖,目的是MNIST手写数字识别)
基本上LeNet做的工作就是下面两点:
如果想通过调参改进模型,可以从下面几点入手:
!调整卷积窗口大小。
!调整输出通道的数量。
!调整激活函数(如ReLU)。
!调整卷积层的数量。
!调整全连接层的数量。
!调整学习率和其他训练细节(例如,初始化和轮数)。
7,AlexNet
AlexNet其实就是改进的LeNet,不同的点如下:
AlexNet和LeNet的设计理念非常相似,但也存在显著差异。首先,AlexNet比相对较小的LeNet5要深得多。AlexNet由八层组成:五个卷积层、两个全连接隐藏层和一个全连接输出层。其次,AlexNet使用ReLU而不是sigmoid作为其激活函数,使用最大池化层而不是平均池化层。并且在两个4096全连接层后加入了dropout实现正则化。最后还做了数据增强的工作,增加了噪音,减少过拟合。
8,VGG
VGG-11使用可复用的卷积块构造网络。不同的VGG模型可通过每个块中卷积层数量和输出通道数量的差异来定义。块的使用导致网络定义的非常简洁。使用块可以有效地设计复杂的网络。在VGG论文中,Simonyan和Ziserman尝试了各种架构。特别是他们发现深层且窄的卷积(即)比较浅层且宽的卷积更有效。
LeNet、AlexNet和VGG有一个共同的设计模式:通过一系列的卷积层与汇聚层来提取空间结构特征;然后通过全连接层对特征的表征进行处理。AlexNet和VGG对LeNet的改进主要在于如何扩大和加深这两个模块。
9,NIN(Net in Net不常用,但是设计理念影响了后面的设计比如GoogLeNet)
NiN网络总结来说就是在卷积层后面增加两个1∗1卷积核替代全连接的作用,然后将全连接层换成平均全局池化层(Global Average Pooling),可以减少大量的训练参数有效避免过拟合。
全局平均池化层:
传统的CNN最后一层都是全连接层,参数个数非常之多,容易引起过拟合(如Alexnet),一个CNN模型,大部分的参数都被全连接层给占用了,所以论文提出采用了全局均值池化替代全连接层。与传统的全连接层不同,我们对每个特征图一整张图片进行全局均值池化,这样每张特征图都可以得到一个输出。这样采用均值池化,连参数都省了,可以大大减小网络参数,避免过拟合,另一方面它有一个特点,每张特征图相当于一个输出特征,然后这个特征就表示了我们输出类的特征。
全局平均池化的优势:
(1)通过加强特征图与类别的一致性,让卷积结构更简单
(2)不需要进行参数优化,所以这一层可以避免过拟合
(3)它对空间信息进行了求和,因而对输入的空间变换更具有稳定性
我试着将AlexNet的两个全连接层替换成1*1卷积,发现果然参数变少了,速度快了百分之十左右。(后面那张是改了之后的结果)
10,GoogLeNet
GoogLeNet中,基本的卷积块被称为Inception块(Inception block)。这很可能得名于电影《盗梦空间》(Inception),因为电影中的一句话“我们需要走得更深”(“We need to go deeper”)。
(由196个通道变成256通道,是这个inception中各个路径的通道数是可以设置的超参数)
Inception块由四条并行路径组成。前三条路径使用大小为1×1、3×3和5×5的卷积层,从不同空间大小中提取信息。中间的两条路径在输入上执行1×1卷积,以减少通道数,从而降低模型的复杂性。第四条路径使用 3×3 最大汇聚层,然后使用 1×1 卷积层来改变通道数。这四条路径都使用合适的填充来使输入与输出的高和宽一致,最后我们将每条线路的输出在通道维度上连结,并构成Inception块的输出。在Inception块中,通常调整的超参数是每层输出通道数。
GoogLeNet一共使用9个Inception块和全局平均汇聚层的堆叠来生成其估计值。Inception块之间的最大汇聚层可降低维度。第一个模块类似于AlexNet和LeNet,Inception块的组合从VGG继承,全局平均汇聚层避免了在最后使用全连接层。
那么,GoogLeNet是如何进一步提升性能的呢?
一般来说,提升网络性能最直接的办法就是增加网络深度和宽度,深度指网络层次数量、宽度指神经元数量。但这种方式存在以下问题:
(1)参数太多,如果训练数据集有限,很容易产生过拟合;
(2)网络越大、参数越多,计算复杂度越大,难以应用;
(3)网络越深,容易出现梯度弥散问题(梯度越往后穿越容易消失),难以优化模型。
所以,有人调侃“深度学习”其实是“深度调参”。
解决这些问题的方法当然就是在增加网络深度和宽度的同时减少参数,为了减少参数,自然就想到将全连接变成稀疏连接。但是在实现上,全连接变成稀疏连接后实际计算量并不会有质的提升,因为大部分硬件是针对密集矩阵计算优化的,稀疏矩阵虽然数据量少,但是计算所消耗的时间却很难减少。
总结:
!Inception块相当于一个有4条路径的子网络。它通过不同窗口形状的卷积层和最大汇聚层来并行抽取信息,并使用 1×1 卷积层减少每像素级别上的通道维数从而降低模型复杂度。
!GoogLeNet将多个设计精细的Inception块与其他层(卷积层、全连接层)串联起来。其中Inception块的通道数分配之比是在ImageNet数据集上通过大量的实验得来的。
!GoogLeNet和它的后继者们一度是ImageNet上最有效的模型之一:它以较低的计算复杂度提供了类似的测试精度。
!超参数太多,很难复现。
11,Batch Normalization
为什么传统的神经网络在训练开始之前,要对输入的数据做Normalization?
原因在于神经网络学习过程本质上是为了学习数据的分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另一方面,一旦在mini-batch梯度下降训练的时候,每批训练数据的分布不相同,那么网络就要在每次迭代的时候去学习以适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对所有训练数据做一个Normalization预处理的原因。
问题提出:
深度网络参数训练时内部存在协方差偏移(Internal Covariate Shift)现象:深度网络内部数据分布在训练过程中发生变化的现象。
为什么会带来不好影响?训练深度网络时,神经网络隐层参数更新会导致网络输出层输出数据的分布发生变化,而且随着层数的增加,根据链式规则,这种偏移现象会逐渐被放大。这对于网络参数学习来说是个问题:因为神经网络本质学习的就是数据分布(representation learning),如果数据分布变化了,神经网络又不得不学习新的分布。为保证网络参数训练的稳定性和收敛性,往往需要选择比较小的学习速率(learning rate),同时参数初始化的好坏也明显影响训练出的模型精度,特别是在训练具有饱和非线性(死区特性)的网络。
一个网络模型中,我们的输入数据在最底层,输出和损失在最上层,那当一个网络很深的时候,反向传播时就会出现上层的参数更新会比较快,但是底层的梯度可能会非常小导致更新不动。
Batch Normalization算法流程:
BatchNorm的作用是什么呢?BatchNorm就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同分布。
对于深度学习这种包含很多隐层的网络结构,在训练过程中,因为各层参数不停在变化,所以每个隐层都会面临covariate shift的问题,也就是在训练过程中,隐层的输入分布老是变来变去,这就是所谓的“Internal Covariate Shift”,Internal指的是深层网络的隐层,是发生在网络内部的事情,而不是covariate shift问题只发生在输入层。
然后提出了BatchNorm的基本思想:能不能让每个隐层节点的激活输入分布固定下来呢?这样就避免了“Internal Covariate Shift”问题了,顺带解决反向传播中梯度消失问题。BN 其实就是在做 feature scaling,而且它的目的也是为了在训练的时候避免这种 Internal Covariate Shift 的问题,只是刚好也解决了 sigmoid 函数梯度消失的问题。
BN的基本思想其实相当直观:因为深层神经网络在做非线性变换前的激活输入值(就是那个x=WU+B,U是输入)随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于Sigmoid函数来说,意味着激活输入值WU+B是大的负值或正值),所以这导致反向传播时低层神经网络的梯度消失,这是训练深层神经网络收敛越来越慢的本质原因,而BN就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正态分布,其实就是把越来越偏的分布强制拉回比较标准的分布,这样使得激活输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,意思是这样让梯度变大,避免梯度消失问题产生,而且梯度变大意味着学习收敛速度快,能大大加快训练速度。
什么意思?就是说经过BN后,目前大部分Activation的值落入非线性函数的线性区内,其对应的导数远离导数饱和区,这样来加速训练收敛过程。
但是很明显,看到这里,稍微了解神经网络的读者一般会提出一个疑问:如果都通过BN,那么不就跟把非线性函数替换成线性函数效果相同了?这意味着什么?我们知道,如果是多层的线性函数变换其实这个深层是没有意义的,因为多层线性网络跟一层线性网络是等价的。这意味着网络的表达能力下降了,这也意味着深度的意义没有了。BN为了保证非线性的获得,对变换后的满足均值为0方差为1的x又进行了scale加上shift操作(y=scale*x+shift),每个神经元增加了两个参数scale和shift参数,这两个参数是通过训练学习到的,意思是通过scale和shift把这个值从标准正态分布左移或者右移一点并长胖一点或者变瘦一点,每个实例挪动的程度不一样,这样等价于非线性函数的值从正中心周围的线性区往非线性区动了动。
核心思想应该是想找到一个线性和非线性的较好平衡点,既能享受非线性的较强表达能力的好处,又避免太靠非线性区两头使得网络收敛速度太慢。
12,ResNet
假设现有一个比较浅的网络(Shallow Net)已达到了饱和的准确率,这时在它后面再加上几个恒等映射层(Identity mapping,也即y=x,输出等于输入),这样就增加了网络的深度,并且起码误差不会增加,也即更深的网络不应该带来训练集上误差的上升。而这里提到的使用恒等映射直接将前一层输出传到后面的思想,便是著名深度残差网络ResNet的灵感来源。
假定某段神经网络的输入是x,期望输出是H(x),即H(x)是期望的复杂潜在映射,如果是要学习这样的模型,则训练难度会比较大。(存在深度网络退化的问题,理论上不加残差网络的情况下网络越深效果也会越好,但是实际上并不是这样)
回想前面的假设,如果已经学习到较饱和的准确率(或者当发现下层的误差变大时),那么接下来的学习目标就转变为恒等映射的学习,也就是使输入x近似于输出H(x),以保持在后面的层次中不会造成精度下降。
在上图的残差网络结构图中,通过“shortcut connections(捷径连接)”的方式,直接把输入x传到输出作为初始结果,输出结果为H(x)=F(x)+x,当F(x)=0时,那么H(x)=x,也就是上面所提到的恒等映射。于是,ResNet相当于将学习目标改变了,不再是学习一个完整的输出,而是目标值H(X)和x的差值,也就是所谓的残差F(x)= H(x)-x,因此,后面的训练目标就是要将残差结果逼近于0,使到随着网络加深,准确率不下降。
图解为什么residual有用:
假设y是靠近数据源的一块卷积快,y’是第二块,y’’是加入残差机制的第二块,而w是靠近数据源的权重参数。那么我们可以看到不加残差时反向传播后y’对w的更新会变得越来越小(也就是梯度消失),但是加入残差后有个加号使得能在每一块之之后依然保持梯度较大。
13,DenseNet
DenseNet采用的是一种更密集的连接方式,是一个密集卷积神经网络,以前向传播方式,将每一层与其余层密集连接。这样做的目的是可以确保各层之间的信息流动达到最大,将所有层(特征图大小匹配)直接连接在一起,注意,这里是维度上相加。
ResNet和DenseNet的关键区别在于,DenseNet输出是连接(用图中的表示)而不是如ResNet的简单相加。连接的意思是将两个相同长度,宽度的特征图合并在一起,生成一个新的图,通道数是两个特征图通道数之和,而ResBlock里的Add,是将特征图的值相加,这就需要保证两个特征图的各个维度相同。
对于每一层而言,前面所有层的特征映射都用作输入,而它自己的特征映射也会用作后面所有层的输入。
DenseNet的几个优点,感受下它的强大:
1、减轻了vanishing-gradient(梯度消失)。
2、加强了feature的传递。
3、更有效地利用了feature。
4、一定程度上较少了参数数量。
14,数据增强
我们在机器学习中,为何要进行数据增强呢?
在深度学习中,一般要求样本的数量要充足,样本数量越多,训练出来的模型效果越好,模型的泛化能力越强。但是实际中,样本数量不足或者样本质量不够好,这就要对样本做数据增强,来提高样本质量。
关于数据增强的作用总结如下:
1,增加训练的数据量,提高模型的泛化能力
2,增加噪声数据,提升模型的鲁棒性
数据增强可以是上下左右翻转,切割局部,变色调明亮度等等。数据增强有很多种方法,但是不一定对模型泛化能力增强有作用,所以我们可以根据具体的应用需求来决定采用哪种方法。
1,数据翻转:数据翻转是一种常用的数据增强方法,这种方法不同于旋转 180°。这种方法是做一种类似于镜面的翻折。
2,数据旋转:旋转就是顺时针或者逆时针的旋转,注意在旋转的时候, 最好旋转90-180度否则会出现尺度的问题。
3,图像缩放:图像可以被放大或缩小。放大时,放大后的图像尺寸会大于原始尺寸。大多数图像处理架构会按照原始尺寸对放大后的图像进行裁切而图像缩小会减小图像尺寸,这使我们不得不对图像边界之外的东西做出假设。
4,图像剪裁:这种方法更流行的叫法是随机裁剪,我们随机从图像中选择一部分,然后降这部分图像裁剪出来,然后调整为原图像的大小。
5,图像平移:平移是将图像沿着x或者y方向(或者两个方向移动。我们在平移的时候需对背景进行假设,比如说假设为黑色等等,因为平移的时候有一部分图像是空的,由于图片中的物体可能出现在任意的位置,所以说平移增强方法十分有用。
6,添加噪声:过拟合通常发生在神经网络学习高频特征的时候(因为低频特征神经网络很容易就可以学到,而高频特征只有在最后的时候才可以学到)而这些特征对于神经网络所做的任务可能没有帮助,而且会对低频特征产生影响,为了消除高频特征我们随机加入噪声数据来消除这些特征。
注:torchvision.transforms里面内置了一些增广的方法可以直接用。
15,微调(迁移学习transfer learning)
迁移学习可以说是深度学习中最重要的技术,特别是对计算机视觉而言。当目标数据集比源数据集小得多时,微调有助于提高模型的泛化能力。
假如我们想识别图片中不同类型的椅子,然后向用户推荐购买链接。一种可能的方法是首先识别100把普通椅子,为每把椅子拍摄1000张不同角度的图像,然后在收集的图像数据集上训练一个分类模型。由于训练样本数量有限,训练模型的准确性可能无法满足实际要求。
为了解决上述问题,一个显而易见的解决方案是收集更多的数据。但是,收集和标记数据可能需要大量的时间和金钱。例如,为了收集ImageNet数据集,研究人员花费了数百万美元的研究资金。尽管目前的数据收集成本已大幅降低,但这一成本仍不能忽视。
另一种解决方案是应用迁移学习(transfer learning)将从源数据集学到的知识迁移到目标数据集。例如,尽管ImageNet数据集中的大多数图像与椅子无关,但在此数据集上训练的模型可能会提取更通用的图像特征,这有助于识别边缘、纹理、形状和对象组合。这些类似的特征也可能有效地识别椅子。
一个神经网络每一层学到不同的东西,底层学到的特征更加通用,而高层学到的往往就比较靠近语义了,也就是和数据集相关性更强了。所以我们在迁移学习中可以固定底部一些层在源数据集上面学到的参数,不再在目标数据集上面进行更新了。
微调包括以下四个步骤:
!在源数据集(例如ImageNet数据集)上预训练神经网络模型,即源模型。
!创建一个新的神经网络模型,即目标模型。这将复制源模型上的所有模型设计及其参数(输出层除外)。我们假定这些模型参数包含从源数据集中学到的知识,这些知识也将适用于目标数据集。我们还假设源模型的输出层与源数据集的标签密切相关;因此不在目标模型中使用该层。
!向目标模型添加输出层,其输出数是目标数据集中的类别数。然后随机初始化该层的模型参数。
!在目标数据集(如椅子数据集)上训练目标模型。输出层将从头开始进行训练,而所有其他层的参数将根据源模型的参数进行微调。
注意:如果源数据集和目标数据集相差很大,可能微调的效果不会很好。例如将imagenet上预训练得到的模型迁移到医疗影像分类上面。
16,目标检测
在图像分类任务中,我们假设图像中只有一个主要物体对象,我们只关注如何识别其类别。然而,很多时候图像里有多个我们感兴趣的目标,我们不仅想知道它们的类别,还想得到它们在图像中的具体位置。在计算机视觉里,我们将这类任务称为目标检测(object detection)或目标识别(object recognition)。目标检测是目前来说计算机视觉任务里面应用最广泛的。
目标检测这里所说的位置可以用边缘框框起来每一个不同的个体,一个边缘框可以通过四个数字定义,可以有不同种的表示形式:
小结:
!目标检测不仅可以识别图像中所有感兴趣的物体,还能识别它们的位置,该位置通常由矩形边界框表示。
!我们可以在两种常用的边界框表示(中间,宽度,高度)和(左上,右下)坐标之间进行转换。
深度学习目标检测算法分成基于锚框的和无锚框的,如下图所示
(目前主流还是基于锚框的算法)
锚框(Anchor Box)
我们进行目标检测,数据集的物体有很多,我们不可能都人为地画边缘框,所以我们需要一些算法自动生成对物体的边框猜测。所谓锚框,就是目标检测算法中,以锚点为中心,由算法预定义的多个不同长宽比的先验框。
在训练阶段,是把anchor box作为训练样本,为了训练样本我们需要为每个锚框标注两类标签:一是锚框所含目标的类别,简称类别;二是真实边界框相对锚框的偏移量,简称偏移量(offset)。在目标检测时,我们首先生成多个锚框,然后为每个锚框预测类别以及偏移量,接着根据预测的偏移量调整锚框位置从而得到预测边界框,最后筛选需要输出的预测边界框。
假设图像中有Na个anchor box,有Nb个真实边界框,这样的话就形成了一个anchor box与真实边界框之间的对应关系矩阵,那么就根据这个对应关系找出与每个anchor box交并比最大的真实边界框,然后真实边界框的标签作为anchor box的标签,然后计算anchor box相对于真实边界框的偏移量。
YOLOv3算法中的锚框的长宽比是算法作者通过分析COCO数据集中对象长宽比,通过K-Mean估计得到的。锚框的长宽比是一个在已有数据集上的先验值,是一个超参数,可以在模型的配置文件中配置,例如:YOLOv5中的锚框配置。
那么怎样来比较两个框,即预测框和真实框的相似度?可以用到IoU交并比。
除了比较预测框和真实框的相似度,还需要预测每个预测框的类别标签。
实际上怎么操作?(下面是其中一种给标号的方法 )
给定图像,假设锚框是A1,A2,…,Ana,真实边界框是B1,B2,…,Bnb,其中na≥nb。让我们定义一个矩阵X∈Rna×nb,其中第i行、第j列的元素xij是锚框Ai和真实边界框Bj的IoU。该算法包含以下步骤:
!在矩阵X中找到最大的元素,并将它的行索引和列索引分别表示为i1和j1。然后将真实边界框Bj1分配给锚框Ai1。这很直观,因为Ai1和Bj1是所有锚框和真实边界框配对中最相近的。在第一个分配完成后,丢弃矩阵中i1th行和j1th列中的所有元素。
!在矩阵X中找到剩余元素中最大的元素,并将它的行索引和列索引分别表示为i2和j2。我们将真实边界框Bj2分配给锚框Ai2,并丢弃矩阵中i2th行和j2th列中的所有元素。
!此时,矩阵X中两行和两列中的元素已被丢弃。我们继续,直到丢弃掉矩阵X中nb列中的所有元素。此时,我们已经为这nb个锚框各自分配了一个真实边界框。
!只遍历剩下的na−nb个锚框。例如,给定任何锚框Ai,在矩阵X的第ith行中找到与Ai的IoU最大的真实边界框Bj,只有当此IoU大于预定义的阈值时,才将Bj分配给Ai。
在预测时,我们先为图像生成多个锚框,再为这些锚框一一预测类别和偏移量。即根据训练好的模型参数去预测这些anchor box的类别和偏移量,进而得到预测的边界框。由于阈值和anchor box数量选择的问题,同一个目标可能会输出多个相似的预测边界框,这样不仅不简洁,而且会增加计算量,为了解决这个问题,常用的措施是使用非极大值抑制(non-maximum suppression,NMS)。
NMS就是一个抑制冗余的反复迭代-遍历的过程。对于一个预测边界框B,模型最终会输出会计算它属于每个类别的概率值,其中概率值最大对应的类别就是预测边界框的类别。在同一副图像上,把所有预测边界框(不区分类别)的预测概率从大到小进行排列,然后取出最大概率的预测边界框B1作为基准,然后计算剩余的预测边界框与B1的交并比,如果大于给定的某个阈值,则将这个预测边界框移除。这样的话保留了概率最大的预测边界框并移除了其他与其相似的边界框。接下来要做的就是从剩余的预测边界框中选出概率值最大的预测边界框B2计算过程重复上述的过程。
17,目标检测算法
R-CNN(region CNN)
R-CNN的全称是Region-CNN (区域卷积神经网络),是第一个成功将深度学习应用到目标检测上的算法。R-CNN基于卷积神经网络(CNN),线性回归,和支持向量机(SVM)等算法,实现目标检测技术。
传统的目标检测方法一般在图片上使用穷举法选出所所有物体可能出现的区域框,对这些区域框提取特征并使用图像识别方法分类,得到所有分类成功的区域后,通过非极大值抑制(Non-maximumsuppression)输出结果。
R-CNN遵循传统目标检测的思路,同样采用提取框,对每个框提取特征、图像分类、非极大值抑制四个步骤进行目标检测。只不过在提取特征这一步,将传统的特征(如SIFT、HOG 特征等)换成了深度卷积网络提取的特征。
R-CNN的步骤如下:
!图像输入:输入待检测的图像。
!区域建议(Region proposals):对第一步输入的图像进行区域框的选取。常用的方法是Selective Search EdgeBox,主要是利用图像的边缘、纹理、色彩、颜色变化等信息在图像中选取2000个可能存在包含物体的区域(这一步骤 选择可能存在物体的区域,跟分类无关,包含一个物体)。
!特征提取:使用CNN网络对选取的2000存在物体的潜在区域进行特征提取。但是可能存在一些问题,由于上一步Region proposals所提取出来的图像的尺寸大小是不一样的,我们需要卷积后输出的特征尺度是一样的,所以要将Region proposals选取的区域进行一定的缩放处理(warped region)成统一的227x227的大小,再送到CNN中特征提取。R-CNN特征提取用的网络是对ImageNet上的AlexNet(AlexNet网络详解)的CNN模型进行pre-train得到的基本的网络模型。然后需要对网络进行fine-tune,这时网络结构需要一些修改,因为AlexNet是对1000个物体分类,fc7输出为1000,因此我们需要改为(class + 1)若类别数为20则应改为20+1=21个节点,加一的原因是对图像背景类识别,判断是不是背景。其他的都用AlexNet的网络结构fine-tune(全连接),其中包括五层卷积和两层全连接层。(在这里使用的是ImageNet竞赛上面训练好的AlexNet模型去除最后两层全连接层的模型(也可以是VGG,GoogLeNet,ResNet等)。特征提取用的是卷积神经网络代替了传统的HOG特征,Haar特征等取特征的方法。)
!SVM分类:将提取出来的特征送入SVM分类器得到分类模型,在这里每个类别对应一个SVM分类器,如果有20个类别,则会有20SVM分类器。对于每个类别的分类器只需要判断是不是这个类别的,如果同时多个结果为Positive则选择概率之最高的。
!Bounding Box Regression:这个回归模型主要是用来修正由第二步Region proposals得到的图像区域。同第四步的分类一样,每个类别对应一个Regression模型。这个Bounding Box Regression主要是为了精准定位。它所做的就是把旧的区域重新映射到新的区域。
!使用非极大值抑制输出(针对于测试阶段:可能几个区域选择的是同一个区域内的物体,为了获得无冗余的区域子集。通过使用非极大值抑制(loU>=0.5)获取无冗余的区域子集。主要有以下几步:
① 所与区域分值从大到小排列
② 剔除冗余,与最大分值区域loU>=0.5的所有区域
③ 保留最大分值区域,剩余区域作为新的候选集
Fast R-CNN
Fast R-CNN相对于R-CNN的提速原因就在于:不过不像R-CNN把每个候选区域给深度网络提特征,而是整张图提一次特征,再把候选框映射到conv5上,而SPP只需要计算一次特征,剩下的只需要在conv5层上操作就可以了。
Fast R-CNN快在不再对每一个锚框进行特征提取,而是先对一整张图进行卷积,然后再对feature map进行锚框映射,然后通过Rol最大池化层将不同尺度的锚框提取到相同尺寸,然后统一放进全连接层进行分类回归预测。如上图,采用2*2划分的最大池化层,每个特征图的锚框切割成2*2=4块,即都将变成长度为4的长度的结果,这样就做到了尺寸统一,能够放进全连接层。
Faster R-CNN(two-stage network,大网络中加入了一个小网络)
与Fast R-CNN相比,Faster R-CNN只将生成提议区域的方法从选择性搜索改为了区域提议网络,模型的其余部分保持不变。具体来说,区域提议网络的计算步骤如下:
!使用填充为1的的卷积层变换卷积神经网络的输出,并将输出通道数记为。这样,卷积神经网络为图像抽取的特征图中的每个单元均得到一个长度为的新特征。
!以特征图的每个像素为中心,生成多个不同大小和宽高比的锚框并标注它们。
!使用锚框中心单元长度为的特征,分别预测该锚框的二元类别(含目标还是背景)和边界框。
!使用非极大值抑制,从预测类别为目标的预测边界框中移除相似的结果。最终输出的预测边界框即是兴趣区域汇聚层所需的提议区域。
值得一提的是,区域提议网络作为Faster R-CNN模型的一部分,是和整个模型一起训练得到的。 换句话说,Faster R-CNN的目标函数不仅包括目标检测中的类别和边界框预测,还包括区域提议网络中锚框的二元类别和边界框预测。 作为端到端训练的结果,区域提议网络能够学习到如何生成高质量的提议区域,从而在减少了从数据中学习的提议区域的数量的情况下,仍保持目标检测的精度。
小结:
!R-CNN对图像选取若干提议区域,使用卷积神经网络对每个提议区域执行前向传播以抽取其特征,然后再用这些特征来预测提议区域的类别和边界框。
!Fast R-CNN对R-CNN的一个主要改进:只对整个图像做卷积神经网络的前向传播。它还引入了兴趣区域汇聚层,从而为具有不同形状的兴趣区域抽取相同形状的特征。
!Faster R-CNN将Fast R-CNN中使用的选择性搜索替换为参与训练的区域提议网络,这样后者可以在减少提议区域数量的情况下仍保证目标检测的精度。
其实Faster R-CNN并不快,但是目标检测精度比较高,工业上比较关注它的速度,一般应用于特别关心精度的场景,比如用来刷榜比赛。下图是各种目标检测算法的速度(x轴)和精度(y轴MAP):
SSD:Single Shot Detection单发多框检测(这里命名是因为对比R-CNN是只采用了one stage的网络,现在用的不多)
在网络的每一层都进行锚框。不管是对一开始的输入还是每一层之后的特征图,锚框都是对它们的每一个像素锚多个框,方法如下:
如果是分辨率很高的图片,其实SSD不太适合,因为SSD是每个像素都设锚框,会造成计算量非常大。
YOLO(You Only Live Once,人生只有一次,应该要珍惜,所以作者改成You Only Look Once,只用看一次,说明yolo算法很快)
YOLO也是single stage网络,也有锚框,但是和SSD相比,不再用每一个像素都建立有锚框,而是尽量让锚框都不重叠,从而解决有很多锚框重叠的问题。如此一来,YOLO算法的计算量就会大大减少。那它是怎么实现的呢?
把图片均匀切成若干份,每一份都是一个锚框,这样一来锚框自然不会重叠。然后每个锚框又会去预测若干个边缘框(因为只测一个边缘框的话,刚好有几个物体重叠在附近的话,也只会框出一个物体,就会丢失信息。)
由于YOLO系列相对较快,所以工业界大量使用。
18,语义分割
与传统的图像分割不一样,图像分割将图像划分为若干组成区域,这类问题的方法通常利用图像中像素之间的相关性。它在训练时不需要有关图像像素的标签信息,在预测时也无法保证分割出的区域具有我们希望得到的语义。但是语义分割就不仅要求将不同的物体分类,还要知道每一个像素的标签。
语义分割技术的应用:
另外,在语义分割的基础上更细分物体,那就是实例分割,语义分割只要知道物体的分类,与语义分割不同,实例分割不仅需要区分语义,还要区分不同的目标实例。例如,如果图像中有两条狗,则实例分割需要区分像素属于的两条狗中的哪一条。
19,转置卷积(本质上也是卷积)
转置卷积不是做还原,只是为了得到像素标签的输出。
小结:
20,FCN
下面我们了解一下全卷积网络模型最基本的设计。如图13.11.1所示,全卷积网络先使用卷积神经网络抽取图像特征,然后通过卷积层将通道数变换为类别个数,最后在13.10节中通过转置卷积层将特征图的高和宽变换为输入图像的尺寸。因此,模型输出与输入图像的高和宽相同,且最终输出通道包含了该空间位置像素的类别预测。
FCN(Fully Convolutional Network,全卷积神经网络)。FCN的网络结构主要包括:连续的卷积层、反卷积层以及跳跃结构。连续的卷积结构用于提取图像特征,主要采用VGGNet或者ResNet等网络结构。因为卷积处理过后的池化层会缩小图像的尺寸,为了得到和原图像等大的分割图,我们需要上采样或者反卷积结构。反卷积的前向和后向传播,只用颠倒卷积的前后向传播即可,所以无论优化还是后向传播算法都是没有问题的。跳跃结构的作用在于优化结果,因为如果将全卷积之后的结果直接上采样得到的结果是很粗糙的,即所得的分割图像会失去很多细节,所以将不同池化层的结果进行上采样之后加和来优化输出,这样得出的分割图像效果会更好。
简单地说:全卷积网络没有全连接层,全部由卷积层构成。
主要过程:
首先将一幅 RGB 图像输入到卷积神经网络后,经过多次卷积及池化过程得到一系列的特征图,然后利用反卷积层对最后一个卷积层得到的特征图进行上采样,使得上采样后特征图与原图像的大小一样,从而实现对特征图上的每个像素值进行预测的同时保留其在原图像中的空间位置信息,最后对上采样特征图进行逐像素分类,逐个像素计算 softmax 分类损失。
那么全连接层换成卷积层有什么好处?
我们输入的图片大小和卷积核大小一致时,其实等价于建立全连接。但全连接不会学习过滤,会给每个连接分权重且不会修改连接关系。卷积则是会学习有用的关系,没用得到关系它会弱化或者直接 dropout。这样卷积块可以共用一套权重,减少重复计算,还可以降低模型复杂度。
FCN的缺点:
分割的结果不够精细。图像过于模糊或平滑,没有分割出目标图像的细节。
因为模型是基于CNN改进而来,即便是用卷积替换了全连接,但是依然是独立像素进行分类,没有充分考虑像素与像素之间的关系。
21,样式迁移
将一个图像中的风格应用在另一图像上,即样式迁移(style transfer)。
下面是基于卷积神经网络的风格迁移方法。首先,我们初始化合成图像,例如将其初始化为内容图像。该合成图像是风格迁移过程中唯一需要更新的变量,即风格迁移所需迭代的模型参数。然后,我们选择一个预训练的卷积神经网络来抽取图像的特征,其中的模型参数在训练中无须更新。这个深度卷积神经网络凭借多个层逐级抽取图像的特征,我们可以选择其中某些层的输出作为内容特征或风格特征。以图13.12.2为例,这里选取的预训练的神经网络含有3个卷积层,其中第二层输出内容特征,第一层和第三层输出风格特征。(目的是为了使某些层对应的内容损失和某些层对应的样式损失变小。)
我们通过正向传播(实线箭头方向)计算样式迁移的损失函数,并通过反向传播(虚线箭头方向)迭代模型参数,即不断更新合成图像。
样式迁移常用的损失函数由3部分组成:
!内容损失使合成图像与内容图像在内容特征上接近;
!样式损失使合成图像与样式图像在样式特征上接近;
!总变差损失则有助于减少合成图像中的噪点。
最后,当模型训练结束时,我们输出样式迁移的模型参数,即得到最终的合成图像。
标签:输出,卷积,神经网络,图像,CNN,输入 来源: https://www.cnblogs.com/rossxp/p/16396484.html