神经网络的知识
- **函数
常用的**函数有sigmoid、tanh、ReLu、LeakyReLU等
为什么需要**函数(这里说的**函数一般指非线性**),假设不用**函数(相当于**函数fx=x),这是每一层的节点的输入都是上一层输出的线性函数,很容易证明,无论神经网络有多少层,输出都是输入的线性组合,与没有隐含层的效果相当,这种情况就是原始的感知器(Perceptron),那么网络的逼近能力是相当有限的。因此,需要引入非线性函数作为**函数,这样深层的神经网络具有更强的逼近能力(不在是输入的线性组合,理论上神经网络基本可以逼近任意函数)
Sigmoid函数:
Sigmoid函数值常用的非线性**函数,它的数学形式如下:
几何图像如下:
特点:它能把输入的连续实值变换为0和1之间的输出,特别地,当输入如果是非常大的负数,那么输出就是0,反之,如果输入非常大的正数,输出就是1.。且sigmoid的导数为fz(1-f(z))
缺点:(1)在深度神经网络中梯度的反向传播是导致梯度爆炸/梯度消失,梯度爆炸发生的概率较少,梯度消失的概率很大。
如果我们初始化神经网络的权值为 [0,1] 之间的随机值,由反向传播算法的数学推导可知,梯度从后向前传播时,每传递一层梯度值都会减小为原来的0.25倍,如果神经网络隐层特别多,那么梯度在穿过多层后将变得非常小接近于0,即出现梯度消失现象;当网络权值初始化为 (1,+∞) (1,+∞)(1,+∞) 区间内的值,则会出现梯度爆炸情况。
(2)其解析式中含有幂运算,计算机求解时相对来讲比较耗时。对于规模比较大的深度网络,这会较大地增加训练时间。
适用于:当我们尝试将值分类到特定的类时,使用Sigmoid函数非常理想。
ReLU函数
数学表达式:.
Relu函数及其导数的图像如下图所示:
ReLU函数其实就是一个取最大值函数,注意这并不是全区间可导的,但是我们可以取sub-gradient,如上图所示。ReLU虽然简单,但却是近几年的重要成果,有以下几大优点:
1) 解决了gradient vanishing问题 (在正区间)
2)计算速度非常快,只需要判断输入是否大于0
3)收敛速度远快于sigmoid和tanh
ReLU也有几个需要特别注意的问题:
1)ReLU的输出不是zero-centered
2)Dead ReLU Problem,指的是某些神经元可能永远不会被**,导致相应的参数永远不能被更新。有两个主要原因可能导致这种情况产生: (1) 非常不幸的参数初始化,这种情况比较少见 (2) learning rate太高导致在训练过程中参数更新太大,不幸使网络进入这种状态。解决方法是可以采用Xavier初始化方法,以及避免将learning rate设置太大或使用adagrad等自动调节learning rate的算法。
尽管存在这两个问题,ReLU目前仍是最常用的activation function,在搭建人工神经网络的时候推荐优先尝试!
优点:不会同时**所有的神经元,这意味着,在一段时间内,只有少量的神经元被**,神经网络的这种稀疏性使其变得高效且易于计算。
缺点:x<0时,梯度是零。随着训练的进行,可能会出现神经元死亡,权重无法更新的情况。也就是说,ReLU神经元在训练中不可逆地死亡了。
Tanh函数
数学表达式:
tanh函数及其导数的几何图像如下图:
tanh读作Hyperbolic Tangent,它解决了Sigmoid函数的不是zero-centered输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。解决了sigmoid的大多数缺点,仍然有两边学习率太低的缺点
如何选择正确的**函数?
根据问题的性质,我们可以为神经网络更快更方便地收敛作出更好的选择。
用于分类器时,Sigmoid函数及其组合通常效果更好。
由于梯度消失问题,有时要避免使用sigmoid和tanh函数。
ReLU函数是一个通用的**函数,目前在大多数情况下使用。
如果神经网络中出现死神经元,那么PReLU函数就是最好的选择。
请记住,ReLU函数只能在隐藏层中使用。
一点经验:你可以从ReLU函数开始,如果ReLU函数没有提供最优结果,再尝试其他**函数。