机器学习-补充03 神经网络之**函数(Activation Function)

**函数(Activation Function)

1.为什么需要**函数?

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

  • 非线性: 当**函数是线性的时候,一个两层的神经网络就可以逼近基本上所有的函数了。但是,如果**函数是恒等**函数的时候(即f(x)=x),就不满足这个性质了,而且如果MLP使用的是恒等**函数,那么其实整个网络跟单层神经网络是等价的。
  • 可微性: 当优化方法是基于梯度的时候,这个性质是必须的。
  • 单调性: 当**函数是单调的时候,单层网络能够保证是凸函数。
  • f(x)≈x 当**函数满足这个性质的时候,如果参数的初始化是random的很小的值,那么神经网络的训练将会很高效;如果不满足这个性质,那么就需要很用心的去设置初始值。
  • 输出值的范围: 当**函数输出值是 有限 的时候,基于梯度的优化方法会更加 稳定,因为特征的表示受有限权值的影响更显著;当**函数的输出是 无限 的时候,模型的训练会更加高效,不过在这种情况小,一般需要更小的learning rate.

如果没有激励函数,那么神经网络的权重、偏置全是线性的仿射变换(affine transformation),有了非线性**函数以后, 神经网络的表达能力更加强大

 

2.常见的三种**函数:

(1)Sigmoid函数

它的数学形式如下:

 

它能够把输入的连续实值“压缩”到0和1之间。特别的,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1.

缺点

  • Sigmoids saturate and kill gradients. (saturate 这个词怎么翻译?饱和?)sigmoid 有一个非常致命的缺点,当输入非常大或者非常小的时候(saturation),这些神经元的梯度是接近于0的,从图中可以看出梯度的趋势。所以,你需要尤其注意参数的初始值来尽量避免saturation的情况。如果你的初始值很大的话,大部分神经元可能都会处在saturation的状态而把gradient kill掉,这会导致网络变的很难学习。
  • Sigmoid 的 output 不是0均值. 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。
    产生的一个结果就是:如果数据进入神经元的时候是正的(e.g. x>0elementwise in f=wTx+b),那么 w 计算出的梯度也会始终都是正的。

当然了,如果你是按batch去训练,那么那个batch可能得到不同的信号,所以这个问题还是可以缓解一下的。因此,非0均值这个问题虽然会产生一些不好的影响,不过跟上面提到的 kill gradients 问题相比还是要好很多的。

sigmoid的梯度

左端趋近于0,右端趋近于1,且两端都趋于饱和.

这里写图片描述

如果我们初始化神经网络的权值为 [0,1] 之间的随机值,由反向传播算法的数学推导可知,梯度从后向前传播时,每传递一层梯度值都会减小为原来的0.25倍,如果神经网络隐层特别多,那么梯度在穿过多层后将变得非常小接近于0,即出现梯度消失现象;当网络权值初始化为 (1,+∞) (1,+∞)(1,+∞) 区间内的值,则会出现梯度爆炸情况。

Sigmoid 的 output 不是0均值(即zero-centered)。这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。
其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间.

 

(2)Tanh函数

Tanh函数可以将元素的值变换到-1和1之间:

Tanh函数 的输出均值比 sigmoid 更接近 0,SGD会更接近natural gradient(一种二次优化技术),从而降低所需的迭代次数,主要解决了上面说到的sigmod函数的第二个不足。 当x为非常大或者非常小的时候,由导数推断公式可知,此时导数接近与0,会导致梯度很小,权重更新非常缓慢,从而导致所谓的梯度消失的问题。

tanh(x)及其导数的几何图像

它解决了Sigmoid函数的不是zero-centered输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。

 

(3) ReLu函数

relu(x)=max(x,0)

这里写图片描述

是个分段线性函数,显然其导数在正半轴为1,负半轴为0,这样它在整个实数域上有一半的空间是不饱和的。相比之下,sigmoid函数几乎全部区域都是饱和的.

ReLU虽然简单,但却是近几年的重要成果,有以下几大优点:
1) 解决了gradient vanishing问题 (在正区间)
2)计算速度非常快,只需要判断输入是否大于0
3)收敛速度远快于sigmoid和tanh

ReLu是分段线性函数,它的非线性性很弱,因此网络一般要做得很深。但这正好迎合了我们的需求,因为在同样效果的前提下,往往深度比宽度更重要,更深的模型泛化能力更好。所以自从有了Relu**函数,各种很深的模型都被提出来了,一个标志性的事件是应该是VGG模型和它在ImageNet上取得的成功.

ReLU也有几个需要特别注意的问题:
1)ReLU的输出不是zero-centered
2)某些神经元可能永远不会被**(Dead ReLU Problem),导致相应的参数永远不能被更新。有两个主要原因可能导致这种情况产生: (1) 非常不幸的参数初始化,这种情况比较少见 (2) learning rate太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用Xavier初始化方法,以及避免将learning rate设置太大或使用adagrad等自动调节learning rate的算法。

人们为了解决Dead ReLU Problem,提出了将ReLU的前半段设为αx 非0,通常α=0.01  (  Leaky ReLU函数: f(x)=max(αx,x)  )。为了解决zero-centered问题,提出了ELU (Exponential Linear Units) 函数,f(x)=x  if x>0  otherwise   a(e^x  −1).

 

(3)ReLU

ReLU函数当输入为正数时,输出导数恒为1,缓解了梯度消失的问题。为网络带来稀疏性,当输入值小于0,就会被稀疏掉。

由于ReLU函数只有线性关系,所以不管是前向传播还是反向传播,都比sigmod和tanh要快很多。。

ReLU处理了它的sigmoid、tanh中常见的梯度消失问题,同时也是计算梯度最快的激励函数。

 

(4) Swish函数(Google大脑团队)

定义为  swish(x)=x⋅Sigmoid

图像如下图所示:

Swish

 

从图像上来看,Swish函数跟ReLu差不多,唯一区别较大的是接近于0的负半轴区域, Google大脑做了很多实验,结果都表明Swish优于ReLu