ramy  2017-12-10 21:40:48  机器学习 |   查看评论   

      上回说完了卷积层的线性部分,这次来聊聊非线性部分。其实在此之前我们在聊全连接层的时候就已经说过两个非线性部分的函数:

  • Sigmoid
  • Tanh

      而且进入了深度网络学习的过程中,前辈们又发现了另一个好用的非线性函数,那就是ReLU,全称Rectify Linear Unit。它的函数形式是这样的:

def relu(x):     return x if x > 0 else 0 

      函数的形状大家也可以想象。在负数部分是一条和x轴平行的水平线,在正数部分是一条斜率为1的直线。这个函数一眼看去就觉得不是很复杂,很前面的两位比起来似乎只需要小学数学就可以明白,可是它却是现在最火的非线性函数,而且以它为基础,前辈们还演化出了一些变形函数。那些变形函数在这里就不提了。

      话说前面两个函数已经称霸江湖许多年了,为什么一个新来的简单到不行的函数会抢尽风头?这也就是我们下面要聊的话题。

梯度消失

      梯度消失是最让大家痛心的事情,这其中要数Sigmoid函数做得差了。早期的神经网络主要是浅层神经网络,在反向传导的过程中,因为中间经过的结构不算多,所以下层的网络得到的残差基本来还算是“新鲜”的。而随着深度学习的发展,网络层数的不断加深,反向传导逐渐变成了一个“漫长”的事情。从最上层的Loss开始向下传导,一路上会有各种各样的数据改变残差的数量,等到了下层的网络手上,这些被加工后的残差有时候会变得面目全非。

      那么是怎样的面目全非法呢?这主要体现在数值的范围上。我们回顾一下两种经典的非线性函数的求导公式:

      sigmoid:\frac{\partial f(x)}{x}=f(x) * (1 - f(x)) 其中函数值的范围是(0,1)

      tanh:\frac{\partial f(x)}{x}=1-f(x)^2 其中函数值的范围是(-1,1)

      我们把两个函数画出来,就是这个样子:

 

梯度消失

 

      从图上可以看出,tanh的导数的数值总体上还算不错,有大有小,但是终究是不大于1的。而sigmoid就比较可怜了,最大也就只有0.25。前面我们聊过关于多层神经网络求导的问题。当导数通过非线性部分到达下面的线性部分时,非线性的函数同样会改变导数的数值。上面的图就是他们改变的数量。

      这时候sigmoid就显得十分渺小了,因为它最好情况下也会把传递的导数数值除以4。对于不深的网络,这点损失还算不上什么,但是对于深层的神经网络,这将会产生巨大的灾难,上层的网络拿到的梯度是比较大的,下层网络拿到的梯度却明显小很多。这种别人吃肉我喝汤的事情自然会让底层网络发育不良,很容易让深层网络无法发挥出应有的效果。

为了验证这个事情,这次拿出一个不太深的网络先举个例子。为了节省时间这里没有自己写代码,而是采用了知名的开源项目caffe。在其给出的例子——MNist的求解模型lenet的基础上稍作改动。关于MNist的内容前面介绍过,关于模型的结构,可以看下面:

  • 输入:1*28*28
  • 卷积:20*5*5
  • 非线性:
  • Max Pooling:2*2
  • 卷积:50*5*5
  • 非线性:
  • Max Pooling:2*2
  • 全连接:500
  • 非线性:
  • 全连接:10
  • Softmax:

      简单来说,就是2层卷积,2层max pooling,2层全连接。其中的非线性部分将分别换成上面提到的三种非线性函数。除此之外,其他的参数设定与例子中完全一致,大家也可以自己去实验下。

      首先来看一下训练数据的Loss和迭代轮数的关系图:

 

Loss和迭代轮数

 

      可以看出,在这个问题上,sigmoid明显会弱一些,tanh和relu相近。当然到最后sigmoid似乎差得也不多。

      接下来是测试集的Loss:

 

除特别注明外,本站所有文章均为 赢咖4注册 原创,转载请注明出处来自卷积层(3)

留言与评论(共有 0 条评论)
   
验证码:
[lianlun]1[/lianlun]