神经网络训练细节(一)

一、激励函数的选取


 常见的激励层函数有sigmoid、tanh、Relu、Leaky Relu、ELU、Maxout

sigmoid函数如下所示:

sigmoid函数是早期用的比较多的激励函数,但现在已经不常用了。主要是当输入特别大或者特别小时,sigmoid函数的偏导数趋于0,这样在使用反向传播算法时将会出现问题,并且sigmoid函数不是关于原点对称的,这样在进行反向传播时w的梯度要么全为正,要么全负(w的梯度即为x乘以上一层的梯度,x恒为正,所以梯度的正负一直不变),收敛速度会非常慢。tanh函数与sigmoid函数图像类似,但是它比sigmoid函数好的一点是tanh函数是关于原点对称的,这样可以减少数据的倾斜。

神经网络训练细节(一)_第1张图片

现在比较常用的激励函数为ReLu(The Rectified Linear Unit/修正线性单元),函数表达式为:f(x)=max(0,x),其函数图像如下所示:

神经网络训练细节(一)_第2张图片

ReLu函数的有点是收敛非常快,因为在原点右侧它的偏导数为1,求导简单,这样在做反向传播时速度比较快。缺点时较为脆弱,原点左侧的函数具有的sigmoid相似的问题,即导数等于0。

Leaky ReLu在是ReLu的“增强版”,其函数表达式为:f(x)=max(ax,x),a通常为一个比较小的数,比如0.01,线面是a=0.01时的图像:

可以看到,相比ReLu,Leaky ReLu在原点左侧的表达式中对x乘以了一个比较小的系数,这样保证了在做反向传播时不会挂掉,并且其计算也很快。

ELU指数线性单元

神经网络训练细节(一)_第3张图片

ELU不会挂掉,计算速度比较快,并且输出的均值趋于0,但是由于指数的存在,计算量略大。

Maxout:

两条直线拼接而成,计算是线性的,比较快,不会饱和不会挂,但是参数比较多。

激励函数使用总结:

1.尽量不要用sigmoid函数

2.首选ReLu,速度快,但是需要小心,有可能会挂掉

3.ReLu不行的话再选用Leaky ReLu或者Maxout


二、权重初始化


    权重一般都会进行随机初始化(如果不随机的话,比如将所有的权重设置为0,这样所有的神经元都是相同的,在反向传播时做相同的计算,明显不是一个好的方式)。

而如果设置一个比较小的随机值,比如将w设置为一个均值为0,方差为0.01的高斯分布:

当神经网络比较小时会有不错的效果,但是当神经网络比较大时,比如训练一个10层,每层有500个神经元的神经网络,选用tanh做为激励函数,打印出每层的均值和方差如下:

神经网络训练细节(一)_第4张图片

可以看到均值和方差会很快的坍缩到0.这是因为在进行反向传播时,我们要求x的梯度,即w乘以上一层的梯度,而w是一个比较小的值,每层乘以一个w会使梯度很快减小,最终趋于0,这就是梯度弥散。

这时,你也许会想调大w的值,比如将w的系数由0.01改变为1:

不过这时你会发现几乎所有的神经元都会饱和,因为w取值在1附近,输入数据会比较大或比较小,tanh函数会处于两端比较平的那部分,这时求tanh的梯度会趋于0,一些神经元可能不会工作。

对于tanh为激励函数的神经网络,下面的w或许会是一个好的选择:

而对于ReLu激励函数,还要再除以二(因为ReLu的方差会减小一半):


Batch Normalization

   从上面可以看出,神经网络对权重的初始化是非常敏感的。当w取值较大时,前向运算的值会发散(值趋近与-1或1),反向运算的导数值趋于0;而当w取值较小时,会坍缩到0,反向传播求得的梯度也会趋于0(两种情况下做反向传播时梯度趋于0的情况是不一样的,当前的梯度等于w乘以上一层的梯度,w较大时是因为tanh的偏导数趋于0,即上一层的梯度趋于0,w较小时是因为每层梯度都乘以一个较小的数,最终会收敛到0)。当w取值不合适时,神经网络会非常脆弱,那有没有方法能够改进一下呢?这就是接下来要说的Batch Normalization。我们希望经过激励函数后的x的值服从高斯分布(而不是分散或者坍缩),或许我们可以手动修改一下,使得输出值符合高斯分布,对输出值做如下处理:

神经网络训练细节(一)_第5张图片

但是我们在训练过程中不能去手动修改输出值,通常会在全连接层后加一层BN层,对输出的数据做如下处理:

神经网络训练细节(一)_第6张图片

是一个比较下的值,加入是为了防止分母为0. 并不是手动指定的超参数,它们也是需要在神经网络训练过程中学习得到的,这两个参数对正则化后的输出数据进行了平移和缩放。

神经网络训练细节(一)_第7张图片

可能学到的值。对做正则化后的数据进行缩放和平移是因为在进行正则化时可能会丢失一些信息,对其进行线性映射可以在一定程度上还原之前数据所带有的信息。

加入BN层后的好处:

1.可以降低对w初始化的依赖

2.在一定程度上可以防止过拟合

3.加入BN层后可以将学习率设置的高一些



你可能感兴趣的:(Deep,Learning,Deep,Learning)