【深度学习入门】计算机视觉任务

news2024/11/15 7:53:25

一、引言

        对于神经网络,可以把中间的隐藏层看作一个黑盒子,这个黑盒子能自动选择如何提取特征,这不同于传统机器学习的人工操作,它的实现原理也是我们学习深度学习的重点。本文章以计算机视觉任务中的图像分类任务为例子,学习这个黑盒子里的各种实现细节。

二、图像分类任务

(1)任务说明

        假设现在又一系列的标签,如:狗、猫、汽车、飞机……,然后把一张图像输入到神经网络,让它判断这张图像是什么类别的。比如输入一张猫的图像,如果判断为猫,那么就是正确的。

(2)计算机眼中的图像

        一张图像在计算机眼中就是一个三维数组的形式,其中每一个元素就是像素,因为每一个像素存储在一个字节中,所以像素值的取值范围在0~255(2^8-1)之间,这个值越小就越暗,越大就越亮。

        为什么说图像是三维数组的形式?每一张图像都有颜色通道,比如一张JPG图像,它的颜色通道就是RGB,代表红、绿、蓝,三个通道值可以组合成不同的颜色。如果三通道的像素值分别为0(红)、0(绿)、255(蓝),那么呈现出的颜色就是蓝色。每一张图像都有分辨率,分辨率就是图像长、宽的像素个数。因此,长、宽、通道,就组成了一个三维数组。

        一个图像的位深是24,表示有3个颜色通道,每个像素用8位存储,那么这个图像最多有2^24种颜色(R、G、B通道分别有2^8种取值,三通道又能相互组合)。如果位深是32,则代表这张图像除了RGB三通道外,还有一个透明度通道alpha。下图为将RGB图像的一个局部转换成计算机眼中的样子,每一个小方格就代表一个像素。

(3)分类的挑战

        拍摄角度:拍摄物体的角度不一定都是正面的,也有可能是侧面、倾斜面。

        姿态改变:比如猫不一定都是趴着的,也有可能是站立的、坐着的、扭曲身体的。

        部分遮蔽:例如在人群中,人会被其他人或东西遮住一部分。

        背景混入:比如猫的毛发跟背景的地毯非常相似,混成了一块。

        对于上面的这些困难以及其它的更多困难,都是可以解决的。只要能获得对应问题的一定量的数据,然后将数据传给网络,让它知道真实的位置在哪,网络自行学习,就能解决对应的问题。

(4)数据集的选择

       因为ImageNet数据集过于庞大,对硬件要求非常高,除非有条件买服务器(价格上万),所以初学者学习时不建议使用该数据集。推荐使用CIFAR-10数据集,有5类标签,5万个训练集,1万个测试集,在数量上已经足够。另外,该数据集的每张图片大小均为32 * 32分辨率,有3个通道,那么像素点个数仅有3072个,对计算机硬件要求不高、处理速度快。下图是CIFAR-10数据集的10个类别以及每个类别随机选取10张图像的展示。

(4)传统机器学习存在的问题

        以K近邻算法为例。K邻近的算法思想:选取K个离测试样本最近的训练样本,其中哪个类别最多,测试样本就属于哪个类别。如下图,如果以实线内作为选取范围,那么圆属于三角形;如果以虚线内作为选取范围,那么圆属于正方形。因此,K的选择,会影响K近邻算法预测的结果

        K近邻计算流程:

  • 计算已知类别训练集中的所有样本点到当前测试样本点的距离。
  • 按照距离的大小依次排序。
  • 选取与当前测试样本点距离最小的前K个点。
  • 计算前K个点所属类别在K个点中出现的频率。
  • 返回出现频率最高的类别作为预测分类。

        距离的计算公式:d\left ( I_{i},I_{j} \right )=\sum_{p}^{}\left | I_{i}^{p}-I_{j}^{p} \right |,i 和 j 为像素点的编号,p为图像中像素点总个数。举例:对应的第三个像素,10-24取绝对值得14,最后把所有像素差值的绝对值求和得到距离。

        K近邻算法的测试结果:

        可以观察到有些测试样本的预测结果正确,比如船;但大部分的预测结果都是不正确的。为什么?观察测试结果中的倒数第三个测试样本,可以看到与之匹配度高的图像都是有黑色背景的。K近邻不能区分前景(主体)和后景(背景)而我们关注的是前景。因此,它的预测的正确率就比较低,不能用来做分类任务。

        K近邻不能区分前景和后景,是因为它没有一个对前景和背景学习的过程。而神经网络就有对前景和后景的一个学习过程。

三、神经网络基础

(1)得分函数

        得分函数是原图像数据映射到每个类别得分的函数。

        比如上图中的输入图像有3072个像素,这些像素就是函数中的x,每个像素所代表的位置不同。猫耳朵、毛眼睛的像素更重要,而背景的像素就不重要,我们用权重W来量化这种重要程度。比如,背景不重要,那么对应像素值的权重可以是0;猫耳朵重要,对应像素值的权重可以是较大的数。

        把原图的3072个像素值,转换成一个3072x1的向量x。对于每一个类别都会有一个权重w_{i},1 < i < 10,每个权重w_{i}包含了对应于每个像素点的权重,故它的大小为1x3072,10个种类的权重向量合并在一起,就是一个10x3072的矩阵W。W与x叉乘,就得到一个10x1的向量,每一行就代表对应类别的得分。最后会用10x1的向量b对结果进行微调。

        从上图中,可以形象地理解到,权重矩阵W对于分类结果起决定性作用,而b只是起到微调的作用。

        如上图,比如从原图像中取一个局部,这个局部的单通道有4个像素点。首先取一个W,里面的权重都是随机的(其中0.0表示对应像素点不重要,2.1表示对应像素点比较重要,负值表示对像素点起抑制作用,正值表示对像素点起促进作用),然后通过随机的W和b可以计算得到每个类别的得分。但是猫的得分为负值,其他类别的得分反而很高,说明这个权重是不合适的。因此,神经网络还需要继续学习,将权重W一轮轮改进为更合适的值

(2)损失函数

        权重W好与不好,需要一个量化去衡量,损失函数就可以用数值来衡量模型的效果。对于同一个神经网络,它可以做很多种任务,比如分类、回归,做不同的任务,唯一不同的就是损失函数。

① 损失函数举例

        损失函数的种类很多,先举一个例子,铰链损失(hinge loss):L_{i}=\sum_{j\neq y_{i}}^{}max(0,s_{j}-s_{y_{i}}+1)s_{j}表示其它错误的类别,s_{y_{i}}表示正确的类别,+1表示一个容忍度,正确类别的得分要至少比其它错误类别得分大1。

        解释为什么要有这个容忍度:比如错误类别的得分是3.15,正确类别的得分是3.2,带入到损失函数,3.15 - 3.2 < 0,若不加1,max最后取值为0。但是这个差距太小了,可能只是恰好在这一个测试样本中正确,用其它测试样本就不一定正确了。因此,我们需要一个容忍度,当正确类别得分比错误类别得分大一点时,也要对模型进行优化。

        如上图所示,第一张图像应该是猫,但car的得分却比cat多,损失函数计算结果就是一个正值;第三张图像是青蛙,青蛙的得分却是一个负值,错得很离谱,损失函数计算的结果就是一个比较大的正值;第二张图是汽车,汽车的得分比其他类别大了至少1,损失函数计算结果就是0,表示没有损失。

② 正则惩罚项

          如果有相同的损失函数:L=\frac{1}{N}\sum_{i=1}^{N}\sum_{​{j\neq y_{i}}}\max(0,f(x_{i};W)_{j}-f(x_{i};W)_{​{y_{i}}}+1)f(x,W)=Wx,i 表示第 i 个样本,j 表示第 j 个类别;和相同的输入数据:x=[1,1,1,1]。对于不同的模型:

模型A:w_{1}=[1,0,0,0]

模型B:w_{2}=[0.25,0.25,0.25,0.25]

有相同的输出结果:w_{1}^{T}x=w_{2}^{T}x=1

        但这并不意味着两个模型形同,模型A只关注了局部的特征(后面三个特征值是0,完全没参与计算);而模型B关注了全局的特征。模型B比模型A更平稳,我们不希望存在模型A这种“突变”。A、B模型的权重参数的变化趋势如下图:

        因此,还需对损失函数进行改进,加一个正则惩罚项(损失函数=数据损失+正则惩罚项):

L=\frac1N\sum_{i=1}^N\sum_{j\neq y_i}\max(0,f(x_i;W)_j-f(x_i;W)_{y_i}+1)+\boxed{\lambda R(W)}

R(W)=\sum_k\sum_lW_{k,l}^2

        加上正则惩罚项的效果,就是把“突变”给削弱了。同一个正则惩罚项,模型的突变越大,正则惩罚项计算值越大,损失越大。\lambda越大,惩罚力度越大,对同一个“突变”的削弱程度越大

        优化的损失函数能让模型更拟合训练数据的分布,但是不能让模型太过复杂,过拟合的模型是没用的(通俗讲就是学傻了,能认识旧的,不能认识新的)。

(3)前向传播

        上述就是一整个前向传播的过程(计算损失值的过程),如下图所示:

(4)Softmax分类器

        分类任务跟预测任务的一个区别就是,分类任务通过计算得到得分后,还需要转换为概率值。Softmax是一种激活函数,可以将一个含任意实数的 k 维向量“压缩”到另一个 k 维实向量中,使得每一个元素的范围在0~1之间,并且所有元素和为1。举一个例子:

        有三个类别,蓝色框内是得分;exp表示e^{x},为了将得分之间的差距拉大;normalize是归一化,为了将得分映射到 0~1 之间,公式如下:

        Softmax函数计算概率: P(Y=k|X=x_i)=\frac{e^{s_{k}}}{\sum_je^{s_j}}s= f( x_{i}; W)。表示对于样本 x_{i} ,标签为k的概率。i 表示第 i 个样本,j 表示第 j 类。

        Softmax分类器的损失函数通常使用交叉熵损失(http://t.csdnimg.cn/FwQlO,计算样本 i 的交叉熵损失:L_i=-\log P(Y=y_i|X=x_i)P(Y=y_i|X=x_i) 表示样本 i 的类别是真值(真值即样本 i 的标签y_{i})的概率。对数的函数图如下:

        概率值越靠近0,得到的损失值越大;概率值越靠近1,得到的损失值越接近0。

        Softmax函数和Sigmoid函数的区别(Sigmoid函数参考:http://t.csdnimg.cn/FwQlO):      

  • Softmax函数,用交叉熵损失函数,解决多分类问题;Sigmoid函数,用二分类交叉熵损失函数,解决二分类问题。
  • 使用Sigmoid,模型输出一个0~1的值,表示其中一个类别的概率。如:输出0.8,那么样本是猫的概率为0.8,是非猫的其他类别(狗、猪)的概率为1-0.8=0.2,可以设置一个阈值,大于阈值就是猫,小于阈值就是狗或者猪。
  • 使用Sigmoid,模型也可以输出多个0~1的值,但是这些输出值是相互独立的,不是互斥的(对于一个样本,所有输出的概率值之和不是1,概率之间没有关系),即一个样本可以有多个标签。
  • 使用Softmax,模型输出多个0~1的值,表示样本属于每个类别的概率。如:输出 [0.6, 0.3, 0.1] 表示是猫的概率为0.6,是狗的概率为0.3,是猪的概率为0.1,选择概率值最高的猫作为最终的预测结果。

(5)反向传播

        反向传播过程,用到了梯度下降算法,可以求解损失函数的损失值最低时对应的参数。梯度下降的详细内容参考:http://t.csdnimg.cn/2WtX4。

        神经网络中,每一层提取的特征不同,因此,反向传播求解的权重矩阵也不同。比如,W_{1} 关注于整个猫的特征,W_{2} 关注于猫的胡须特征,W_{3}关注猫的眼睛特征……。 深度学习中,输入数据要与一系列权重矩阵组合才能得到输出数据,这也是与线性回归、逻辑回归(只有一个权重矩阵)不同的地方,因此,神经网络是非常强大的。

        举一个简单的例子来说明反向传播的过程:f(x,y,z)=(x+y)z,调节 x、y、z 参数使得f 的值最小,要用到梯度下降算法,就需要求 f 对各个参数的偏导,求偏导的过程是层层向后求导的。

        比如求 \frac{\partial f}{\partial x} = \frac{\partial f}{\partial q}\frac{\partial q}{\partial x}=z*1=z,是 f 先对 q 求偏导,q 再对 x 求偏导。这叫做链式法则,反向传播的过程中的梯度是从后往前一步步传播的。

        如上图所示,输入数据经过前向传播得到损失函数,损失函数逐层从后往前对参数求偏导调整参数值使得损失达到最低值。再举一个复杂的例子:f(w,x)=\frac1{1+e^{-(w_0x_0+w_1x_1+w_2)}}

       蓝色的是输入数据,绿色的是前向传播逐层计算结果,红色的是反向传播逐层求偏导计算的结果。f 对 w_{0} 求偏导:

\frac{\partial f}{\partial w_{0}} = \frac{\partial f}{\partial g}\frac{\partial g}{\partial i}\frac{\partial i}{\partial e}\frac{\partial e}{\partial d}\frac{\partial d}{\partial c}\frac{\partial c}{\partial a}\frac{\partial a}{\partial w_{0}}=-\frac{1}{g^{2}}*1*epxe*-1*1*1*x_{0}=\frac{1}{g^{2}}*expe*x_{0}   式(1)

        再将 g、e、x_{0} 的值 1.37、-1.00、-1.00代入式(1)(式1中expx表示e^{x}) 得到 f 对 w_{0} 求偏导的结果大约为 -0.20,f 对其它参数求偏导的过程类似。 -0.20就意味着 w_{0} 调大一个值(学习率*梯度的反方向),f 就减小。

        计算时,可以逐步地求偏导,也可以一个单元地求偏导(包装成一个门单元)。比如f(w,x)=\frac1{1+e^{-(w_0x_0+w_1x_1+w_2)}} 中存在 sigmoid 函数 \sigma(x)=\frac1{1+e^{-x}},那么就可以把 sigmoid 函数作为一个单元求偏导:\frac{d\sigma(x)}{dx}=\frac{e^{-x}}{\left(1+e^{-x}\right)^2}=\left(\frac{1+e^{-x}-1}{1+e^{-x}}\right)\left(\frac1{1+e^{-x}}\right)= \left(1-\sigma(x)\right)\sigma(x),将\sigma(x)的值0.73代入\left(1-\sigma(x)\right)\sigma(x)得0.2,相当于把\frac{\partial f}{\partial w_{0}} = \frac{\partial f}{\partial g}\frac{\partial g}{\partial i}\frac{\partial i}{\partial e}\frac{\partial e}{\partial d}\frac{\partial d}{\partial c}\frac{\partial c}{\partial a}\frac{\partial a}{\partial w_{0}}替换成\frac{\partial f}{\partial w_{0}} = \frac{\partial \sigma }{\partial x}\frac{\partial x}{\partial c}\frac{\partial c}{\partial a}\frac{\partial a}{\partial w_{0}}

        除了sigmoid门单元,还有一些常见的门单元

  • 加法门单元:均等分配的效果。假设z=x+y,它的前一层计算的梯度值是0.2,那么\frac{\partial z}{\partial x}\frac{\partial z}{\partial y}的结果都为1,将 1 与前一层的梯度相乘都得前一层梯度本身,如下图所示:

  • MAX门单元:分配给较大值的效果。假设z=max(x,y),x=2(较大值),y=-1(较小值),前一层的梯度值是2,那么z=2,\frac{\partial z}{\partial x}=2\frac{\partial z}{\partial y}=0,相当于把上一层的梯度值分配给较大值x的梯度,较小值y的梯度为0,如下图所示:                                                  

  • 乘法门单元:互换的效果。假设z=x*y,x=3,y=-4,上一层的梯度值为2,那么z=-12,\frac{\partial z}{\partial x}=y=-4\frac{\partial z}{\partial y}=x=3z求x和y的偏导就是x和y的值互换,再各自乘以上一层的梯度值得-8和6,如下图所示:                                                         

        上面的例子只是为了让我们理解反向传播计算的大概过程,实际中并不是对数值计算,而是对矩阵计算,手算是不现实的,有现成的工具包可以使用

(6)神经网络整体架构

① 层次结构

        神经网络工作的基本原理是一个层次结构,数据传入输入层(input layer);隐藏层(hidden layer)再根据需要对数据进行变换,即特征提取,隐藏层有很多个;最后将提取的结果从输出层(output layer)传出。如下图所示:

  ② 神经元

        神经元就是上图中的一个个圆圈,它的含义就是特征的量,即矩阵的大小。比如年龄、体重、身高就是3个特征,对应3个圈。如果输入的是一张大小为32*32*3的图像,就有3072个特征,输入层就是一列3072个圆圈。

        只有输入层的特征,计算机认为不够或者难以理解,就会在隐藏层对数据进行变换,变换成新的特征,比如通过参数的组合 age*0.1+weight*0.2+height*0.3 得到一个新的特征。这些新的特征不同于输入层的特征有具体的含义(年龄、身高、体重),它们是没有含义的,仅仅是有助于达到最好的提取效果。因此,我们说神经网络的内部就像一个黑盒子,人类并不能理解其中各种数据的意思。

        斯坦福大学的老师做的一个能进行可视化展示的神经网络,能帮助我们理解神经元个数对结果的影响:ConvNetJS demo: Classify toy 2D data (stanford.edu)。

        这一块能选择不同形状分布的数据:

        这一块能更改神经网络的神经元个数:

        下面是隐藏层中不同神经元个数的神经网络,对同一个螺旋分布的数据的训练效果的可视化展示:

        可以看到,神经元越多,拟合的程度越大,训练效果越好。下面是隐藏层设置15个神经元的神经网络对随机数据(没有规律的数据)的训练结果:

        可以看到,用蓝色线框出的绿色圆周围都是红色圆,可能属于异常的样本,机器学习不能做到在没有规律的数据中找到规律,但是神经网络能做到,这种情况会导致给出一个测试样本(紫色的圆)本应划分为红色圆,但因为过拟合被划分为了绿色圆。过拟合的神经网络会过分拟合训练数据(包括异常的数据),导致在测试集上的效果变差,俗称学傻了

③ 全连接

        上一层的每个特征都与下一层的每个特征连接在一起的结构就是全连接,如上图中的黑线。这个黑线事实上是没有的,取而代之的是参数矩阵。比如图中的输入层矩阵大小是[1x3],表示1个样本3个特征,batch就等于1,表示每次迭代只训练一个样本;隐藏层1和隐藏层2的矩阵大小是[1x4];那么输入层和隐藏层1之间的黑线代表的参数矩阵W_{1}的大小就是[3x4],隐藏层1和隐藏层2之间的黑线代表的参数矩阵W_{2}的大小就是[4x4],隐藏层2和输出层之间的黑线代表的参数矩阵W_{3}的大小就是[4x1]。

④ 非线性

        上图的结构大概可以这样表示[\left ( XW_{1} \right )W_{2}]W_{3}W_{1}W_{2}W_{3} 不能替换成W表示为XW,因为在每一层与W_{i}组合完之后会进行非线性变换,即用非线性函数做映射,如Sigmoid函数、max函数。如果用max函数做非线性变换,那么神经网络整体架构的式子就可以表示成:

f=W_{3}max(0,W_{2}max\left ( 0,max\left ( 0,W_{1}X \right ) \right ))

        神经网络的层数多,使用的参数就很多;输入数据比较大时,每一个特征都会对应一个参数,参数也会很多,参数量通常是千万、上亿级别。

(7)正则化与激活函数

① 惩罚力度对结果的影响

        观察下图,对于同一个训练数据,不同的惩罚项系数对训练结果的影响:

       惩罚项系数越小,对权重参数中的突变削弱力度越小,决策边界越不规则,过拟合的风险就越大,在训练集上的效果越好;惩罚项系数较大,决策边界较光滑,在测试集上的效果较好。对于蓝色线框出来的数据,它们的周围都是绿色圆,而本身却是红色圆,这不符合规律,因此大概率是异常数据。当惩罚项系数较小,如图中的0.001,因为过拟合而导致在训练集上效果好,而测试集上效果不好(本来属于绿圆,却被预测为红圆);当惩罚项系数较大时,如图中0.1,决策边界较光滑,把数据有规律地划分,这样虽然在训练集上的效果不是特别好(没有过分拟合),但在测试集上的预测效果更好(没有受到异常数据的影响)。我们的目的是用模型预测未知的样本,而不是在已知样本上傻学,因此并不希望模型过拟合

② 激活函数的对比

        Sigmoid函数和Relu函数的对比图:

        神经网络在上个世纪60年代就已存在,但是并没有受到重视,一个原因是当时计算机硬件性能太差,还有一个原因就是用的Sigmoid函数导致模型效果较差。Sigmoid函数有一个致命的缺点,当输入值较大或者较小,输出值会趋向于平稳,导致梯度变为0,即梯度消失。反向传播一层层从后向前传递梯度时,只要有一个梯度为0,那么它前面的所有梯度都为变为0(偏导数的计算是连乘的),最后导致权重参数没有变化,无法降低模型的损失,模型预测效果较差

        而现在的神经网络有90%使用的是Relu函数,5%使用的Relu函数的变形体,剩下的使用其它的激活函数。它的优点一是梯度计算简单,二是在正区间不会出现梯度消失的问题

(8)数据预处理

① 数据标准化

        下面三张图展示了标准化的过程:包括中心化和归一化,使数据平均值为0,标准差为1,符合标准正态分布。意义:放缩后只与均值、标准差有关,因此对异常值不敏感。归一化的意义:让数据的每个维度的特征对结果的贡献更均衡,使结果不受不同特征范围大小的影响,如右图。

        中图:中心化由原数据减去均值实现。右图:归一化由中心化后的数据除以标准差实现。

② 参数初始化

        W=0.01*np.random.randn(D,H)

        使用随机策略对参数初始化,乘以0.01的作用是让参数浮动的较小,均衡地考虑全局的特征。

(9)DROP-OUT

        下图中的右图展示了训练阶段(不用在测试阶段)一次迭代中的DROP-OUT:

        每次迭代随机选择一定比例的神经元去掉(不是直接把神经元从网络中去掉,可能在之后迭代中,本次去掉的神经元还会用到),防止神经网络过拟合,加快训练速度。

四、卷积神经网络

(1)和传统神经网络的区别

        如上图所示,左图的传统神经网络的输入层是把图像的多有特征拉成一个向量;而右图的卷积神经网络(CNN)的输入层没有改变图像原本的维度(h*w*c)。

(2)整体架构

        卷积神经网络有输入层、卷积层、池化层、全连接层、输出层,如下图所示:

        全连接层在传统神经网络部分已经说明,接下来的重点是卷积层(提取特征)和池化层(压缩特征)。

① 卷积层

        一张猫的图像,有背景、胡须、眼睛等,不同特征意义不同、重要性不同。因此分成几个部分分别做卷积,卷积过程大致如下(图中仅展示了一个通道的卷积):

        粉色是原始的图像,蓝色是做卷积的一部分图像,绿色是做卷积后提取出的特征图。深蓝色部分的每一格右下角的数字就是权重,深绿色部分是所有特征值与对应权重的点乘之和。以上面的图为例子,3*0+3*1+2*2+0*2+0*2+1*0+3*0+1*1+2*2 = 12。

        卷积核每次会移动固定的步长,再做卷积,得到最终的特征图,如下所示:

        下面是对有三个通道的部分图像 x,分别由两个不同的卷积核(Filter)w0、w1做卷积,再加上偏置(Bisa)b0、b1,得到两个不同的特征图(绿色部分),最后堆叠为一个2通道的特征图(大小3x3x2):

        从上图可以看到,输入数据的通道数和卷积核的通道数必须是一致的卷积核的个数决定输出数据的通道数

        以输入数据中用蓝色线框出来的部分和卷积核w0、偏置项b0为例子,说明计算输出数据的通道0的特征图的第一个特征值3的过程:输入数据x的通道0、1、2从上往下依次与卷积核w0的0、1、2通道做卷积,0*1+0*1+0*1+0*-1+1*-1+1*0+0*-1+1*1+1*0=-1+1=0;0*-1+0*-1+0*1+0*-1+0*1+1*0+0*-1+2*1+2*0=2;0*1+0*0+0*-1+0*0+2*0+2*0+0*1+0*-1+0*-1=0。

然后把所有通道计算的值相加:0+2+0=2。最后还需加上偏置项b0:2+1=3。

        图中输入数据的灰色部分是填充的边缘(pad),在卷积核按固定步长滑动的过程中,输入数据靠中间的特征被重复利用计算卷积的概率更大,而靠边缘的特征被重复利用的概率很小,这是不公平的。为了减小这个不公平,就进行边缘填充,让输入数据的边缘特征向中间靠近。填充值为0,不会对结果产生影响。

        卷积层涉及的参数

  • 滑动窗口的步长:一般是1,步长越小,得到的特征图的特征越丰富。下图是步长分别为1、2对结果的影响对比。

  • 卷积核尺寸:一般是3*3,卷积核尺寸越小,得到的特征图的特征更丰富。
  • 边缘填充:一般是1,有时候也会因为方便整除好计算填充其它的宽度。
  • 卷积核个数:卷积核个数决定提取到的特征图通道数。

        卷积结果的长、宽计算公式

H_{2}=\frac{H_{1}-F_{H}+2P}{S}+1

W_{2}=\frac{W_{1}-F_{W}+2P}{S}+1

        H_{1}W_{1}表示输入数据的长、宽;F_{H}F_{W}表示卷积核的长、宽;P表示边缘填充的宽度,乘以2是因为数据的两边都会填充P的宽度;S为滑动窗口的步长。

        卷积层有很多,就像传统神经网络中的隐藏层有很多,每次在前一个卷积层提取的特征图基础上再进行卷积,会让特征越来越概括。比如,一开始一个特征只能表示眼睛的一个像素,经过很多层卷积层后,一个特征能表示一整个眼睛。如下图所示:

       

        一张图像可以分为很多个区域,按理来说,根据传统神经网络可以知道,不同的特征使用的权重不同,这样会使模型拟合得更好,那么不同区域使用的卷积参数也应该不同,但实际上卷积神经网络的卷积参数是共享的,即同一个卷积核通过窗口滑动对不同区域计算卷积特征。相比传统神经网络,这样的好处是,权重参数大量减少,计算速度加快,训练更简单,过拟合风险降低

        比如,一张32*32*3的图像(3072个神经元),经过一个隐藏层,得到4000个特征值,那么输入层和隐藏层之间需要尺寸为 3072*4000 的权重矩阵,即一千万多个参数。如果将一张32*32*3的图像输入一个卷积层,用10个5*5*3的卷积核进行卷积操作,指定步长1,边缘填充1,那么将得到长度和宽度都为\frac{32-5+2*1}{1}+1=30、通道数为10(经过10个卷积核做卷积)的特征图,含有30*30*10=9000个特征值,得到的特征值个数比传统神经网络的结果更多。但仅用了10*5*5*3=750,再加10个偏置参数,共760个参数

② 池化层

        池化层(pool)执行下采样操作(downsampling),保留重要的特征,减少不重要的特征数量,以加快训练速度、减少过拟合风险。我们常用最大池化,将特征图分为几个区域,选取每个区域的最大值,组成下采样后的特征图,最大池化过程的示范如下图:

        还有一种是平均池化,计算每个区域的平均值,组成下采样后的特征图。卷积提取的特征图是经过训练得到的权重参数计算后的结果,值越大的特征表明对结果的重要性越大,平均池化将最重要的特征值拉低作为选出的特征,明显不会比直接选取值最大的特征效果好,经过研究者们的多次实验也验证了这一点。因此,平均池化是被淘汰的,常用最大池化

③ 通常的网络架构

        一个卷积层后必需接一个激活函数(RELU函数),两次卷积后接一个池化层,依次有三套两卷积一池化,最后必有一个全连接层,将特征图转化为得分或者概率。比如,经过最后一个池化层,得到的特征图尺寸为32*32*10(10240个特征),再经过全连接层,得到5个类别的概率值,那么最后一个池化层和全连接层之间,会使用大小为10240*5的权重参数矩阵。

        通常看到的几层神经网络,是把有参数计算的层次算作一层,因为卷积层、全连接层有参数计算,激活函数(非线性变换)、池化层(选取重要特征)没有参数计算,所以上图的卷积神经网络有7层(6层卷积层+1层全连接层)。

        下图可以看到特征图在卷积神经网络中的变化:

        卷积层可以调整卷积核的个数、大小,以丰富特征图数量、提取更精炼的特征图;池化层可以让特征图的体积缩小(改变长度、宽度,通道数不改变);全连接层将特征图拉成一个向量再进行预测。

五、经典的卷积神经网络

(1)AlexNet

        AlexNet 在2012年的 ImageNet 比赛中大展风采,让深度学习火了起来,可称为近代神经网络的开封之作。尽管如此,AlexNet有许多缺陷,如下图所示:

        例如,第一个卷积层使用的卷积核大小为11*11、窗口滑动步长为4,提取的特征非常粗略,边缘填充宽度为0,也是不常见的;红色线框出来的LRN层,在后面研究者的实验中也证明是没用的;整个AlexNet有8层,包括5层卷积层和3层全连接层,网络层数少,效果也较差。

(2)VGG

        在2014年有了VGG网络,它有几个版本,网络层数主要是16或者19,相比AlexNet多了很多层。并且它用到的所有卷积核大小都是3*3,相比AlexNext提取的特征图,VGG的特征更丰富。并且它每次在经过池化层后,为了弥补因为选取特征而损失的特征信息(特征图的长宽度缩小),会将特征图的数量翻倍,如下图蓝线框所示,64翻倍为128,128翻倍为256……:

        VGG 比 AlexNext 的效果更好,但是它花费的计算时间更多

(3)ResNet

        随着计算机性能瓶颈的提高,神经网络的网络层数瓶颈也越来越高,按理来说,网络层数越高效果越好,但在实验中发现大约在20层过后,再添加网络层数反而效果变差了。如下图所示,56层和20层的VGG网络的效果比较(错误率越高,效果越差):

        这是因为不能保证所有卷积层特征提取得到的特征图一定会比之前好。当研究者们都觉得深度学习止步于此时,2015年何凯明提出了 ResNet ,通过引入残差结构解决网络退化的问题。残差结构的实现原理,通俗讲就是,如果加了卷积层后效果更好就保留;效果不好值就为0,取而代之使用原来的特征图,总的效果就是,提取的特征图至少不会比原本的差。残差结构如下图所示:

        下图是VGG网络(左)和ResNet(右)的效果对比图,可以看到ResNet随着网络层数的增加,错误率降低了:

        我们在使用ResNet网络的时候,不用考虑网络架构应该是怎样的、参数应该是怎样的,因为这些都是现成的,站在巨人的肩膀上使用成果就行了。此外,应该把神经网络当作用于特征提取的,至于是解决分类还是回归任务,区别在于损失函数的不同、还有最后的全连接层是如何连接的。不管是物体追踪、分类、检索……都可以通过一个网络结构完成。

六、感受野的作用

        感受野就是提取的特征值是由原图中多少个值参与计算而来。比如,下图中经过Second Conv得到的一个特征值,对应于Input的感受野就是5*5。因为一个特征值是由背景、前景等丰富的特征筛选组合而来是更好的,所以感受野越大越好

        如果想让特征值的感受野为7*7,用一层有7*7的卷积核的卷积层即可,为什么还要分别用三次有3*3的卷积核的卷积层呢(滑动窗口步长为1,因为7*7的输入数据已经包含了pad的大小,所以公式中没有单独列出2*pad项。第一层:\frac{7-3}{1}+1=5,得到5*5的特征图;第二层:\frac{5-3}{1}+1=3,得到3*3的特征图;第三层:\frac{3-3}{1}+1=1,得到1*1的特征图,感受野为7*7)?

        假设输入数据的大小是h*w*c,并使用b个卷积核(得到b个特征图)。计算使用一层7*7的卷积核所需参数个数:b*(7*7*c)=49bc;如果使用三层3*3的卷积核所需要参数个数:3*b*(3*3*c)=27bc。可以看到,堆叠小的卷积核所需要的参数更少一些并且卷积过程越多,特征提取越细致加入的非线性变换也增多(每一层卷积后必有激活函数)。这就是VGG网络用3*3小卷积核来完成特征提取的原因

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2096103.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

zookeeper 集群搭建 及启动关闭脚本

1准备奇数台机子3&#xff0c;5&#xff0c;7 我准备的是三台 192.168.58.81 zookeeper-1 192.168.58.82 zookeeper-2 192.168.58.83 zookeeper-3 下载jdk 把他配置环境变量并检查是否是环境变量 echo $JAVA_HOME cd /opt/software wget http://mirrors.hust.edu.…

docker部署project-exam-system项目

8月30日笔记 项目实战&#xff1a;使用docker部署project-exam-system 1、背景&#xff1a; 使用基础的docker指令来创建镜像&#xff0c;实现项目的发布&#xff0c;使用Dockderfile&#xff0c;docker compose编排容器。 2、环境准备&#xff1a; &#xff08;1&#x…

sts 0/1 没有 pod生成 -> kube-controller-manager没了

kube-controller-manager.yaml 在 nerdctl ps -a 看不到 journalctl -xu kubelet > /tmp/kubelet.log /tmp/kubelet.log 老6

OpenSetting组件的用法

文章目录 1. 概念介绍2. 使用方法与主要功能2.1 使用方法2.2 主要功能 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取App自身信息"相关的内容&#xff0c;本章回中将介绍一个三方包:open_setting.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念…

JavaWeb:实验二JSP表单开发及访问数据库

一、实验目的 1&#xff0e;掌握JSP表单的开发方法。 2&#xff0e;熟悉JDBC技术和使用JDBC连接各种数据库。 二、实验性质 综合性实验 三、实验内容 实现注册与登录功能&#xff1a; 1.创建一个数据库&#xff0c;在数据库建立用户表。&#xff08;5分&#xff09; 2…

城市管理违规行为智能识别 Task3学习心得

本次学习主要针对数据集增强和模型预测 1、数据增强&#xff1a; 1&#xff09;将四张训练图像组合成一张&#xff0c;增加物体尺度和位置的多样性。 2&#xff09;复制一个图像的随机区域并粘贴到另一个图像上&#xff0c;生成新的训练样本 3&#xff09;图像的随机旋转、…

day25 Java基础——面向对象两万字详解!(纯干货)

day25 Java基础——面向对象两万字详解&#xff01;&#xff08;纯干货&#xff09; 文章目录 day25 Java基础——面向对象两万字详解&#xff01;&#xff08;纯干货&#xff09;1. 类与对象的关系类&#xff08;Class&#xff09;对象&#xff08;Object&#xff09;类与对象…

gitee绑定公钥后依旧无法使用_gitee push添加公钥无效

解决&#xff1a; 步骤按照官网操作即可&#xff1a;gitee官方说明 看看远程地址是否使用的http模式&#xff0c;是的话换ssh模式

Adobe Acrobat Reader的高级功能详解

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; Adobe Acrobat Reader是广泛使用的PDF查看器&#xff0c;其不仅可以用于查看和打印PDF文件&#xff0c;还具有一些高级功能&#xff0c;可以提升用户的PDF文档处理效率。以下是对Adobe Acrobat Reader的一些…

RH850系列芯片深度剖析 1.7-启动流程解析

RH850系列芯片深度剖析 1.7-启动流程解析 文章目录 RH850系列芯片深度剖析 1.7-启动流程解析一、简介二、启动相关文件说明三、启动相关的段四、启动流程4.1 启动文件启动4.1.1 寄存器初始化4.1.2 时钟初始化4.1.3 模块Standby寄存器初始化4.1.4 启动从核4.1.5 硬件初始化4.1.5…

vector模拟实现迭代器失效

目录 1.vector和vector> 1.1两者的区别 1.2遍历的方法 2.vector模拟实现的准备 3.reserve出现的问题及解决方案 4.遍历vector的三种方式 5.关于typename的使用 6.insert导致的迭代其实失效问题 6.1因为扩容导致的迭代器失效 6.2因为插入数据倒置的迭代器失效 1.vec…

【精彩回顾·成都】成都 UG 生成式 AI 工作坊:AI 革命下的商业模式创新!

文章目录 前言一、活动介绍二、精彩分享内容及活动议程2.1、亚马逊云科技社区情况和活动介绍2.2、《浅谈 AIGC 商业化》2.3、《AI 浪潮下的产品落地》2.4、现场互动情况2.5、休息茶歇时间2.6、《AI 赋能商业革新&#xff1a;智能化转型的策略与实践》2.7、《动手实践&#xff1…

GAMES104:10+11游戏引擎中物理系统的基础理论算法和高级应用-学习笔记

文章目录 概览一&#xff0c;物理对象与形状1.1 对象 Actor1.2 对象形状Actor Shape 二&#xff0c;力与运动2.1 牛顿定律2.2 欧拉法2.2.1 显式欧拉法Explicit (Forward) Euler’s Method2.2.2 隐式欧拉法 Implicit (Backward) Euler’s Method2.2.3 半隐式欧拉法 Semi-implici…

【iOS】通过第三方库Masonry实现自动布局

目录 前言 约束 添加约束的规则 使用Masonry自动布局 Masonry的常见使用方法 补充 前言 在暑期完成项目时&#xff0c;经常要花很多时间在调试各种控件的位置上&#xff0c;因为每一个控件的位置都需要手动去计算&#xff0c;在遇到循环布局的控件时&#xff0c;还需要设…

使用文件系统管理硬件设备

1、描述一个文件系统 介绍如何使用文件系统来管理计算机系统中所有的硬件设计和磁盘 之前直接在sys_open/sys_read/sys_read中对具体的tty设备的打开、读写进行操作&#xff0c;并且只是非常粗浅地介绍了文件系统的一些概念。接下来将正式引入文件系统 由于文件系统需要考虑不…

从FasterTransformer源码解读开始了解大模型(2.4)代码通读05

从FasterTransformer源码解读开始了解大模型&#xff08;2.4&#xff09;代码解读05-ContextDecoder的前向01 写在前面的话 ContextDecoder部分是用于处理输入部分的组件层&#xff0c;在这一层中&#xff0c;会对所有输入的input ids进行处理&#xff0c;计算Attention&…

全国大学生数学建模比赛——关联规则

一、问题背景与关联规则适用性 在数学建模比赛中&#xff0c;常常会遇到需要分析大量数据以寻找变量之间潜在关系的问题。关联规则分析作为一种数据挖掘技术&#xff0c;特别适用于这种场景。例如&#xff0c;在一些实际问题中&#xff0c;可能需要从众多的因素中找出哪些因素之…

基于Python的量化交易回测框架Backtrader初识记录(一)

版权声明&#xff1a;本文为博主原创文章&#xff0c;如需转载请贴上原博文链接&#xff1a;基于Python的量化交易回测框架Backtrader初识记录&#xff08;一&#xff09;-CSDN博客 前言&#xff1a;近期以来&#xff0c;对股市数据获取及预处理算是告一段落&#xff0c;下一步…

Java-多线程机制

上篇我提到一些多线程的基本使用方法&#xff0c;但并没有说到底层原理&#xff0c;你或许会有一些疑问&#xff0c;为什么不直接调用Run方法而是要用start方法启动线程&#xff1f;多线程到底是怎样执行的&#xff1f;接下来我会详细带你了解多线程的机制原理。 多线程的底层…

Leetcode114将二叉树转换为链表(java实现)

来看下本题的题目描述&#xff1a; 本题想让我们将二叉树转换为单链表&#xff0c;可以发现&#xff0c;左边的二叉树转换为右边的链表是使用的中序遍历&#xff0c;根 左 右 所以本道题的思路就是可以先用一个集合以中序遍历收集元素&#xff0c;然后再构建单链表。 class S…