飞桨PaddlePaddle零基础入门深度学习课程学习总结3(week_2)

卷积神经网络(CNN)

1.卷积(Convolution)
首先我们需要的是卷积核(filter),或者叫作滤波器,这是一个长宽分别为k_h,k_w 的矩形或正方形,我们通过这样的一个卷积核去匹配原输入图像数据中的每一块区域,从左上一直到右下。每个区域通过与卷积核中的权值按位相乘再相加的方式,得到卷积的一个输出,再将这些输出合并成一个完整的输出。OK,我觉得大家应该没有听懂,接下来上图。这里我直接挪用飞桨课程中的示例图,如下

那么在上面的例子中,卷积核就是我们的二维数组[[0,1],[2,3]], 我们的原始图片数据是[[1,2,3],[4,5,6],[7,8,9]]。首先拿我们的卷积核去对应原数据中左上角区域[[1,2],[4,5]],然后根据位置按位相乘再相加得到输出的第一个值,25。接下来不断移动我们的卷积核去遍历原数据的每一个区域,然后根据相同的运算规则得到对应的结果,依次放入卷积输出对应位置。这里有个需要注意的点是,一般我们在每次计算按位相乘再求和的过程中,会再加入一个偏置,比如1,也就是输出卷积的每个值会➕1。

OK,那我们经过这样的一步卷积变换后,数据从原来的3x3尺寸,变为了2x2的尺寸。也就是对于一张图片,经过一次卷积后,图片的尺寸变小了。当然这是一般的情况,具体的情况取决于卷积核的大小。但是,在卷积这一步中,我们不希望图片尺寸发生变化,所以我们会增加一个步骤,padding,也就是通过填充使卷积输出的尺寸和原始图片相等或接近。
具体来说,我们用如下公式来表示:
H_out=H+2p_h-k_h+1
W_out=W+2
p_w-k_w+1

其中,H_out 和 W_out分别表示卷积输出的长和宽,H和W分别表示原始图片的长和宽,p_h表示上下填充的size,比如上下各填充一行,那么p_h=1,当然你也可以选择在高度两侧填充不同的size,同理,p_w表示在宽度两侧填充的size。k_h和k_w分别表示卷积核的长与宽。

接下来我们考虑卷积过程中除卷积核大小之外,另一个重要的因素。那就是移动的步幅(stride)。我们之前所讨论的例子其实是比较常见的步幅为1的情况,也就是是卷积核每次移动一个像素单位(图像数据),那么我们根据不同的场景,也可以选择不同的步幅,比如每次移动2格,那么理所当然的,我们的卷积输出的尺寸也会相应地发生变化,下面为stride=2的卷积过程。(直接使用飞桨课程中的示例图)
在这里插入图片描述
所以,当我们将stride的变化也考虑进来的时候,我们输出卷积层尺寸的计算公式变为:
H_out=(H+2p_h-k_h)/s_h +1
W_out=(W+2
p_w-k_w)/s_w +1

其中s_h和s_w分别表示行步幅和列步幅。

以上就是卷积层形成的重要参数,接下来我想再总结一下我对卷积的理解。首先,引入一个概念—感受野(Receptive Field)。我们知道,输出卷积中每个点的数值,是由输入图片上大小为k_h x k_w的区域中的每个元素与卷积核每个对应元素相乘再相加得到的。所以当输入图片上这块区域中任一元素发生改变,卷积层的输出都会发生改变。我们把这块区域叫做输出卷积对应点的感受野。也就是说如果某块区域属于卷积层对应点的感受野,任何该区域的变化都会反映在卷积层对应点的变化上。其次,我想谈一下卷积的另一个特点。不知大家有没有发现,我们在上述的卷积过程中,对于图像的不同区域,使用的是相同的卷积核,对于图像的不同区域,我们都做相同的线性变换(假设这里不实用非线性激活),为什么?其实很简单,我们使用同一个卷积去检索整张图片的不同区域,目的是只想要检测一个特征。只是不同的卷积层神经元检索不同的区域罢了。在学术上,我们将这样的一个卷积层称为一个feature map。这样的想法不仅合理,同时有效减少来模型训练的参数个数。因为我们可以把它看作从原始输入到卷积层,每个卷积神经元的参数是共享的(share weights and biases)。当然在真实的案例中,只检测一个特征当然是不合理的,所以我们一般会有多个feature map,通过使用不同的卷积核去检测图像中不同的特征,这些feature map形成一个feature maps。

以上的介绍都是基于单输入通道以及单输出通道的情况,但是在实际应用中,我们往往需要处理多通道输入,比如彩色图片有RGB三个通道,同时输出特征图也会具有多个通道。
这里,我们首先考虑多输入通道的情况。比如在实际中,我们往往需要考虑RGB三个通道,更一般的我们假设输入通道为 C_in,那么输入数据的形状就会是C_inH_inW_in。而卷积核对应的形状为 C_ink_hk_w。具体的运行规律见下图。
在这里插入图片描述
总结来说,在上面的例子中,我们有3个通道。我们对每个通道均使用一个卷积核,然后得到3个形状相同的卷积输出,最后将三个卷积按位相加,得到最终的输出。

接下来考虑多输出通道的情况,也就是说我们需要多个feature map。那么对于卷积核而言,我们需要在上面多输入通道的基础上,对卷积核再增加一个维度,变为C_outC_ink_hk_w。以下是具体示例图。
在这里插入图片描述
最后我们来考虑批量操作的情况。
在具体神经网络的例子中,我们往往会选择将多个样本放在一起形成一个mini-batch进行所谓的批量操作。换句话说,我们的输入数据不再是一张图片,而是多张图片,具体维度表示为N
C_inH_inW_in。 其中N代表的就是具体图片的数量。对于卷积操作而言,实际上就是对每一张图片都运行上面多输入多输出操作。具体见下面的示例图。
在这里插入图片描述
以上我们一步一步从最基本的卷积概念拓展到实际多输入多输出的批量卷积,下面我们来看看如何在飞桨中使用卷积。飞桨卷积算子对应的API是

paddle.fluid.dygraph.Conv2D

需要的参数主要有:1.num_channels 表示输入图像的通道数。
2.num_filters 表示卷积核的个数,等价于输出的特征通道数。
3. filter_size 表示卷积核的大小,可以为整数,比如3,表示卷积核的高和宽均为3,或者输入一个list,比如[3,2], 对应卷积核的高和宽。
4.stride 表示步幅,可以为整数,比如1,代表垂直和水平滑动步幅均为1,也可以指定一个list。
5.padding 表示填充大小,可以为整数,比如1,表示垂直和水平边界填充均为1,也可以是一个list。
6. act 表示激活函数。

最后再来总结一下数据的维度:
输入数据维度[N,C_in,H_in,W_in],
输出数据维度[N,num_filters,H_out,W_out]
权重参数w的维度或者卷积核的维度[num_filters,C_in,filter_size_h,filter_size_w]
偏置参数b的维度[num_filters]

2.池化(Pooling)
池化是使用某一位置的相邻输出的总体统计代替网络在该位置的具体输出,相当于对卷积输出做了压缩,只保留核心特征。我们常用的是平均池化和最大池化。
平均池化:对池化区域内的像素取平均值,得到对应输出。
最大池化:对池化区域内的像素取最大值,得到对应输出。
在CNN中,我们一般使用2 x 2大小的池化窗口,步幅也为2,不使用填充,则输出特征图的尺寸为 H_out=H/2 , W_out=W/2。池化的作用在于对每个特征进行压缩,不会减少特征的通道数。

3.激活函数(activation function)
这里我们重点介绍ReLU。相比于Sigmoid, ReLU的好处在于避免了梯度衰减。那么为什么Sigmoid会造成梯度衰减呢?原因就隐藏在函数的导数中。我们知道在梯度更新的使用,应用反向传播算法,更进一步,遵照链式法则。那么当我们使用sigmoid作为激活函数的时候,它的导数是一个在整个实数域上值域很小的值,最大值仅为1/4。当x很小或很大的时候,导数值均趋近于0。那么可想而知,链式相乘中的这一项导致梯度十分接近于0,即衰减。那么为什么ReLU能够巧妙地避免这个问题呢?
我们来看一下ReLU的图像:
在这里插入图片描述
虽然在x<0的地方,ReLU的导数为0,但是在x>=0的地方,ReLU的导数为1,能够将y的梯度完整传递给x,而不会引起梯度消失。

4.批归一化(Batch Normalization)
这个方法被广泛应用于神经网络中,目的是对神经网络中间层的输出进行标准化处理,使得中间层的输出更加稳定。
BatchNorm的主要思路是在训练时按mini-batch为单位,对神经元的数值进行归一化,使数据的分布满足标准正态分布,具体过程如下:
1)计算mini-batch内样本每个维度的均值
2)计算mini-batch内样本每个维度的方差
3)对于每个样本,计算标准化后的输出,注意,考虑到存在方差为0的情况,我们在做标准化时,在方差部分加一个微小值,其主要作用是防止分母为0。
如果强行限制输出层的分布是标准化的,可能会导致某些特征模式的丢失,所以在标准化之后,BatchNorm会紧接着对数据做缩放和平移。
当然,在对预测样本进行归一化的时候,我们会使用在训练过程中保留的均值和方差,而不会重新计算测试集中的,不然就会出现对于同一个样本在不同mini-batch下预测结果不同的情况。

5.丢弃法(dropout)
作为深度学习中最常见的一种抑制过拟合的方法,其核心做法是将神经网络的每一次训练转变为如下步骤:
1)在训练开始之前,先从神经网络中随机剔除一些神经元,使之变成一个新的简化的神经网络。
2)基于简化的神经网络,使用反向传播算法更新神经元的参数,当然被剔除的部分神经元参数不更新。
3)每一次训练结束,神经网络的结构恢复,并进入下一次训练。

猜你喜欢

转载自blog.csdn.net/weixin_44607838/article/details/108105688