卷积神经网络——卷积层、池化层和激活函数

卷积神经网络——卷积层、池化层和激活函数,第1张

2018年11月20日,在看tensorflow的时候发现还是有很多概念没有理解透彻,发现一个很赞的资源(估计大家都知道的,只有我现在才发现),吴恩达老师在网易云课堂上开的深度学习的 课程 ,感觉很赞本文实际上是吴恩达卷积神经网络视频学习笔记。

2019年2月14日,再次温故这部分的内容,添加了11章节的自问自答,添加了对池化层实现反向传播的方式,添加了激活函数relu和sigmoid的对比。

通过一个3 3的每列值相同、第一列为1,第二列为0,第三列为-1的过滤器可以检测垂直的边沿。注意到1表示亮,-1表示暗。这样可以发现正负值的边沿。

对于垂直边缘过滤器而言,重要的是中间一列为0,左右两列的值可以相差尽可能的大。

这个过滤器的数值也是可以通过反向传播算法学习的,不一定需要在算法开始之前就决定。

深度学习甚至可以去学习其他的边沿,无论是45度、73度乃至是其他的角度,虽然比手工要复杂一些,但是确实具有这样的能力。

为什么需要填充?大家都知道,卷积就是用过滤器(f x f)从左到右、从上到下的扫描一个矩阵(n x n)。有两种卷积 *** 作,一种称为valid-conv,一种称为same-conv。每次卷积的时候,过滤器右侧碰到矩阵右边界就结束当前行的扫描,下侧碰到矩阵下边界就结束扫描,因此通过过滤器的图像都会缩小,变为(n-f+1) (n-f+1)。valid-conv就是这样的卷积 *** 作,而same-conv会在卷积之前填充原始图,使得卷积之后的大小不变。

一般来说,若原图像大小为n n,过滤器大小为f f,那么需要padding的大小为p=(f-1)/2。一般来说我们会设置f为奇数,很少看见偶数的过滤器。其中的原因之一就是为了对称填充。另一个原因可能是一般需要将过滤器的中间点用于定位卷积的位置,而偶数过滤器没有中间点。

上面的提到的卷积过程每次只移动一步。实际上过滤器可以移动不止一步,用s表示步长。那么n x n的矩阵输入, f x f的过滤器, p填充padding,以及s步长的情况下,输出的矩阵大小为 (n+2p-f)/2+1 x (n+2p-f)/2+1 ,这里是向下取整的,这意味过滤器只能在输入图像内部移动,不可以移动出边缘。

注意 在tensorflow中,有两种填充方式,一种是same,一种是valid。same是填充,而valid是不填充。如果遇到valid,那么实际计算矩阵大小的时候,是向上取整,而不是这里提到的向下取整。如果是same模式,那么最后的矩阵形状是n/s,也是向上取整

上面提到的卷积的输入是n x n的,这一般是灰度图像。对应彩色图像则存在RGB三个颜色channel,这样的是n x n x 3。此时的过滤器也必须存在第三个维度,即channel维度,且一个过滤器的channel维度必须和输入的channel维度一致。这样的卷积结果就是三个维度上,过滤器和输入的重叠位置乘积之和。最后的输出是(n - f + 1) x ( n - f +1)的。 注意,输出是二维的

我们可以使用N个不同的过滤器得到不同的N个二维输出,按照输入的格式将其叠起来,这样输出就是 (n - f + 1) x ( n - f +1) x N了。

在上面一节中已经讲了如何得到输入和一个过滤器卷积之后的结果。通常会给卷积的结果添加一个偏执,然后使用非线性的函数进行处理,得到的就是这层网络的输出。将过滤器的参数标记为W,偏置为 b(一个channel的输出矩阵Wa的偏置是一个实数,而非一个矩阵。一个layer的偏置b的维度和通道数channel一致) , 输入数据为上层的激活值。这样每个过滤器处理之后的结果就可以看成是经过了该layer一个节点之后的输出。

下面是每层的符号标记,以及根据上一层计算下一层输入大小的公式,右下角是使用BP学习更新的时候参数更新的次数。可以看到每层的参数的个数只和这层的filter的大小、数目有关,而和输入的规模无关。这样就可以通过控制参数的数量避免过拟合了。

可以从下面的课件中看到,卷积神经网络的趋势是长度和高度逐渐减少,而channel逐渐加深。最后一层会将卷积层平铺开来,形成一个全连接。全连接层会连接到最后一个判别函数上,判别函数可以是logistic或者softmax层,用于输出类别或者概率。

一般情况下,卷积网络除了卷积层之外,还会有池化层和全连接层,这些层可以提供更好的学习。

池化层一般在卷积层之后,可以也可以看成一个过滤器,实际上实现的一个采样的功能,其主要的思想是,着重提取具有某种倾向的特征,比如最大池化对应的是更显著的特征;平均池化对应的是更加平滑的特征。过滤器有几点不同

一般常用的池化层有max_pooling和average_poolingmax_pooling更加常用。 ,最大池化层意味着检测某个特征,并始终将这个特征留在池化层的输出中

池化层的输入n x n x nc,过滤器 f x f,步长s,输出 ((n-f)/s+1) x ((n-f)/s+1) nc。

一般取s=2,这意味着输入的长宽减小一半。

比较好奇的一个问题是,池化层的存在对反向传播有什么影响?我们都知道在传统的神经网络中,反向传播算法实际上就是利用函数的梯度进行反向传播的,那么池化层这种既改变了矩阵大小又不好求导的情况,怎么处理呢?

(下面的内容来自 迷川浩浩_ZJU 的博客 )

mean pooling的前向传播就是把一个patch中的值求取平均来做pooling,那么反向传播的过程也就是把某个元素的梯度等分为n份分配给前一层,这样就保证池化前后的梯度(残差)之和保持不变,还是比较理解的。mean pooling比较容易让人理解错的地方就是会简单的认为直接把梯度复制N遍之后直接反向传播回去,但是这样会造成loss之和变为原来的N倍,网络是会产生梯度爆炸的。

2、max pooling

max pooling也要满足梯度之和不变的原则,max pooling的前向传播是把patch中最大的值传递给后一层,而其他像素的值直接被舍弃掉。那么反向传播也就是把梯度直接传给前一层某一个像素,而其他像素不接受梯度,也就是为0。所以max pooling *** 作和mean pooling *** 作不同点在于需要记录下池化 *** 作时到底哪个像素的值是最大,也就是max id

一般概念上的一层包括卷积层和池化层,之所以不把池化层当做新的一层是因为池化层没有需要学习的参数,一般意义上的layer是有权重和参数需要学习的。

尽量不要自己设置超参数,而是尽量参考别人论文里面使用的超参数,选择一个在别人任务中效果很好的超参数。

下面的表中列举了上面的网络每一层的数据规模a^(l)以及参数数量。可以发现数据的规模逐渐减小。主卷积层的参数比较少,而进入全连接层之后参数数量很大。(表格中最后三列的参数数量可能存在错误,应该是48000 + 120, 120 84 + 84, 84 10 + 10)

以上的两个特征可以明显的减少参数。减少过拟合

(内容来自 迷川浩浩_ZJU 的博客 )

常用的激活函数有sigmoid函数和relu函数

Relu(x)={if x>0 then x;else 0}为了在反向传播算法中可以正常使用,将其在x=0x=0处的导数置为1,所以它的导数也就变为了 δRelu(x)={if x>0 then 1 else 0}

Relu是一个非常优秀的激活哈数,相比较于传统的Sigmoid函数,有三个作用

激活函数 : 神经网络神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数 Activation Function。

1 为什么要用激活函数?

神经网络中激活函数的主要作用是提供网络的非线性建模能力,如不特别说明,激活函数一般而言是非线性函数。 假设一个示例神经网络中仅包含线性卷积和全连接运算,那么该网络仅能够表达线性映射,即便增加网络的深度也依旧还是线性映射,难以有效建模实际环境中非线性分布的数据。 加入(非线性)激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。

激活函数通常有如下一些性质:

(1)非线性: 如果不用激励函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合。如果使用的话,激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。 当激活函数是非线性的时候,一个两层的神经网络就可以逼近基本上所有的函数了。但是,如果激活函数是恒等激活函数的时候(即),就不满足这个性质了,而且如果MLP使用的是恒等激活函数,那么其实整个网络跟单层神经网络是等价的。

(2)可微性: 当优化方法是基于梯度的时候,这个性质是必须的。

(3)单调性: 当激活函数是单调的时候,单层网络能够保证是凸函数。 当激活函数满足这个性质的时候,如果参数的初始化是random的很小的值,那么神经网络的训练将会很高效;如果不满足这个性质,那么就需要很用心的去设置初始值。

(4)输出值的范围: 当激活函数输出值是 有限 的时候,基于梯度的优化方法会更加 稳定,因为特征的表示受有限权值的影响更显著;当激活函数的输出是 无限 的时候,模型的训练会更加高效,不过在这种情况小,一般需要更小的learning rate。

2 激活函数如何选择?

从定义来看,几乎所有的连续可导函数都可以用作激活函数。但目前 常见的多是分段线性和具有指数形状的非线性函数 。

选择的时候,就是根据各个函数的优缺点来配置,例如:

如果使用 ReLU,要小心设置 learning rate, 注意不要让网络出现很多 “dead” 神经元 ,如果不好解决,可以试试 Leaky ReLU、PReLU 或者 Maxout。

最好不要用 sigmoid,你可以试试 tanh,不过可以预期它的效果会比不上 ReLU 和 Maxout。

一般来说,在分类问题上建议首先尝试 ReLU,其次ELU,这是两类不引入额外参数的激活函数。

然后可考虑使用具备学习能力的PReLU和MPELU,并 使用正则化技术 ,例如应该考虑在网络中增加Batch Normalization层。

通常来说,很少会把各种激活函数串起来在一个网络中使用的。

3 为什么引入非线性激励函数?

激活函数通常分为 线性激活函数 和 非线性激活函数 。一般情况下,如果神经网络中使用的是线性激活函数,那么每一层就相当于是上一层的线性组合,其输入和输出均是线性的,类似于感知机模型,则hidden layers没有存在的意义了,同时这种线性函数对于 复杂的非线性问题拟合欠佳 。当我们使用非线性激活函数时,模型可以拟合任意函数的输出,表现空间更大、使用该范围广、且效果更优。下图为单层的感知机,是常用的神经网络组合单元,用它可以画出一条线,把平面分开。

很容易联想到多个感知机组和,获得更强的分类能力,效果如下所示:

但是感知机的输出是线性的,如下所示。当然可以用无限条线性的线拟合曲线,然而复杂度较高。

如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层输出都是上层输入的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与只有一个隐藏层效果相当,这种情况就是多层感知机(MLP)了。

正因为上面的原因,我们决定引入非线性函数作为激励函数,这样深层神经网络就有意义了(不再是输入的线性组合,可以逼近任意函数)。

当拓展到多层的情况时,就会变成一个复杂的函数,可以轻松拟合非线性的复杂场景。最早的想法是sigmoid函数或者tanh函数,输出有界,很容易充当下一层输入(以及一些人的生物解释balabala)。

比较线性激活和非线性激活下的平滑分类平面,两者分别如下。

非线性激活函数可以拟合出曲线的边界。图像的非线性特点,可以理解为在一些应用中,其分布为非线性的,无法通过直线来完整的分离开。

4 为什么引入ReLU呢?

第一,采用sigmoid等函数,反向传播求误差梯度时,求导计算量很大,而Relu求导非常容易,使得训练时间短。

第二,对于深层网络,sigmoid函数反向传播时,很容易就会出现梯度消失的情况(在sigmoid接近饱和区时,变换太缓慢,导数趋于0),从而无法完成深层网络的训练。

第三,Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生(以及一些人的生物解释balabala)。

参考:

[1] 神经网络之激活函数 https://wwwcsuldwcom/2019/05/26/2019-05-26-activation-function/

[2] 激活函数的解释 https://wwwzhihucom/question/22334626

tanh是双曲函数中的一个,tanh()为双曲正切。在数学中,双曲正切“tanh”是由基本双曲函数双曲正弦和双曲余弦推导而来。

其实tanh(x)=2sigmoid(2x)-1

结果:

神经网络的激活函数是用来调整神经网络的非线性表现能力的函数。理论上,任意一个函数都可以作为神经网络的激活函数,但是一般情况下,神经网络的激活函数要满足一些性质,如单调性、可微性、连续性等,以保证神经网络的收敛性和学习效率。

常用的神经网络的激活函数包括:Sigmoid函数、tanh函数、ReLU函数、Leaky ReLU函数等。这些函数都具有较好的性质,在神经网络的应用中表现较为优良。

理论上讲任何一个连续的非多项式、常数函数都可以做为BP的激活函数,而且这都是已经在数学上证明过的问题。 

但sigmoid函数相对其他函数有它自身的优点,比如说光滑性,鲁棒性,以及在求导的时候可以用它自身的某种形式来表示 。

这一点在做数值试验的时候很重要,因为权值的反向传播,要求激活函数的导数 。

多层就有多个导数,如果用一般的连续函数,这对计算机的存储和运算都是一个问题,此外还要考虑整个模型的收敛速度,我上面提到连续函数都可以做激活函数 。

但是相应的Sigmoidal型函数的收敛速度还是比较快的,(相同的结构前提下) 

还有就是BP在做分类问题的时候,Sigmoidal函数能比较好的执行这一条件,关于连续函数可以做激活函数的证明,可以在IEEE trans on neural networks 和NeuralNetworks以及Neural Computating 和Neural Computation上找到。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12176621.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存