神经网络中的每个神经元节点接受上一层神经元的输出值作为本神经元的输入值,然后对其进行某种固定的数学操作。在多层神经网络中,上层节点的输出和下层节点的输入之间具有一个函数关系,这个函数称为激活函数(又称激励函数)。激活函数给神经元引入了非线性因素,如果不用激活函数的话,无论神经网络有多少层,输出都是输入的线性组合。
激活函数的发展经历了Sigmoid -> Tanh -> ReLU -> Leaky ReLU -> Maxout这样的过程,还有一个特殊的激活函数Softmax,因为它只会被用在网络中的最后一层,用来进行最后的分类和归一化。
如果不用激励函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合。
如果使用激活函数的话,激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。
26种神经网络激活函数可视化
非线性函数数学公式:
σ ( x ) = 1 1 + e − x \sigma(x)=\frac{1}{1+e^{-x}} σ(x)=1+e−x1
取值范围(0,1)
函数图像:
将输入实数值“挤压”到0到1范围内,如果是非常大的负数,那么输出就是0;如果是非常大的正数,输出就是1 ,适合输出为概率的情况,但是现在已经很少有人在构建神经网络的过程中使用sigmoid。
评价: 在特征相差比较复杂或是相差不是特别大时效果比较好。
存在问题一: Sigmoid函数饱和使梯度消失。当神经元的激活输出在接近0或1处时会饱和,从下图可以看到,其两侧导数逐渐趋近于0, lim x → ∞ f ′ ( x ) = 0 \lim _{x \rightarrow \infty} f^{\prime}(x)=0 limx→∞f′(x)=0 ,具有这种性质的称为软饱和激活函数。具体的,饱和又可分为左饱和与右饱和。与软饱和对应的是硬饱和,即 f ′ ( x ) = 0 , w h e n ∣ x ∣ > c f^{\prime}(x)=0, when |x|>c f′(x)=0,when∣x∣>c 。 sigmoid 的软饱和性,就会导致梯度消失,几乎就有没有信号通过神经传回上一层。解释如下: sigmoid 的导数表达式为:
σ ′ ( x ) = σ ( x ) ( 1 − σ ( x ) ) \sigma^{\prime}(x)=\sigma(x)(1-\sigma(x)) σ′(x)=σ(x)(1−σ(x))
sigmoid 原函数及导数图形如下:
由图可知,导数从 0 开始很快就又趋近于 0 了,易造成“梯度消失”现象。 一般来说, sigmoid 网络在 5 层之内就会产生梯度消失现象
存在问题二: Sigmoid函数的输出不是0为中心的。 这是不可取的,因为这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。 因为如果输入神经元的数据总是均值不为零,例如上一层使用sigmoid作为激活,输出为x,那么存在 x > 0 x>0 x>0,针对本层的权重和偏置进行计算 f = w T x + b f=w^{T}x+b f=wTx+b,那么关于 w , b w,b w,b 的梯度在反向传播的过程中,因为loss一样,更新到本层梯度也一样, x x x 均为相同符号,$ w$ 的梯度都是用 x x x 乘以 f f f 的梯度,因此如果神经元输出的梯度是正的,那么所有 w w w 的梯度就会是正的,反之亦然所以将会要么全部是正数,要么全部是负数, w w w要么都往正方向更新,要么都往负方向更新,导致有一种捆绑的效果,导致梯度下降权重更新时出现"z"字型的下降,使得收敛缓慢。
存在问题三: 其解析式中含有幂运算,计算机求解时相对来讲比较耗时。 激活函数计算量大,反向传播求误差梯度时,求导涉及除法
非线性函数数学公式:
tanh ( x ) = e x − e − x e x + e − x = 1 − e − 2 x 1 + e − 2 x = 2 1 + e − 2 x + − 1 − e − 2 x 1 + e − 2 x = 2 sigmoid ( 2 x ) − 1 = 2 σ ( 2 x ) − 1 \begin{aligned} \tanh (x)& =\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}} =\frac{1-e^{-2x}}{1+e^{-2x}} \\ & =\frac{2}{1+e^{-2x}} +\frac{-1-e^{-2x}}{1+e^{-2x}} \\ &=2 \operatorname{sigmoid}(2 x)-1 \\ &=2 \sigma(2 x)-1 \end{aligned} tanh(x)=ex+e−xex−e−x=1+e−2x1−e−2x=1+e−2x2+1+e−2x−1−e−2x=2sigmoid(2x)−1=2σ(2x)−1
函数图像:
将实数值压缩到[-1,1]之间
评价: tanh在特征相差明显时的效果会很好,在循环过程中会不断扩大特征效果。
解决问题一: Tanh解决了Sigmoid的输出是不是零中心的问题。实际使用中效果更好。
存在问题一: 仍然存在饱和问题。为了防止饱和,现在主流的做法会在激活函数前多做一步 batch normalization ,尽可能保证每一层网络的输入具有均值较小的、零中心的分布。
非线性函数数学公式:
f ( x ) = max ( 0 , x ) f(x)=\max (0, x) f(x)=max(0,x)
函数及其导数图像:
输入信号 <0 时,输出都是0,输入信号>0 的情况下,输出等于输入
评价:
比较: 对比sigmoid类函数主要变化是:单侧抑制,相对宽阔的兴奋边界,稀疏激活性
解决问题一:(收敛快)对比sigmoid、tanh类函数,ReLU对于随机梯度下降的收敛有巨大的加速作用;发现使用 ReLU 得到的 SGD 的收敛速度会比 sigmoid、tanh 快很多。
解决问题二:(导数计算快,运算速度快)sigmoid和tanh在求导时含有指数运算,而ReLU求导几乎不存在任何计算量。
解决问题三:(不存在梯度消失) sigmoid 的梯度消失问题,ReLU 的导数就不存在这样的问题
f ′ ( x ) = { 1 x > 0 0 x ≤ 0 f^{\prime}(x)=\left\{\begin{array}{ll}{1} & {x>0} \\ {0} & {x \leq 0}\end{array}\right. f′(x)={10x>0x≤0
存在问题一: ReLU单元比较脆弱并且可能“死掉”,而且是不可逆的,不是所有的‘’死掉‘’都不能复活,只有因为某一次更新的梯度过大,加入导致这个神经元更新后对所有的输入有一个很大的负偏置就会导致该神经元永远死掉,因此导致了数据多样化的丢失。通过合理设置学习率,会降低神经元“死掉”的概率。
存在问题二: ReLU的输出不是zero-centered。
讨论:神经网络中ReLU是线性还是非线性函数?为什么relu这种“看似线性”(分段线性)的激活函数所形成的网络,居然能够增加非线性的表达能力?
(1)relu是非线性激活函数。
(2)让我们先明白什么是线性网络?如果把线性网络看成一个大的矩阵M。那么输入样本A和B,则会经过同样的线性变换MA,MB(这里A和B经历的线性变换矩阵M是一样的)
(3)的确对于单一的样本A,经过由relu激活函数所构成神经网络,其过程确实可以等价是经过了一个线性变换M1,但是对于样本B,在经过同样的网络时,由于每个神经元是否激活(0或者Wx+b)与样本A经过时情形不同了(不同样本),因此B所经历的线性变换M2并不等于M1。因此,relu构成的神经网络虽然对每个样本都是线性变换,但是不同样本之间经历的线性变换M并不一样,所以整个样本空间在经过relu构成的网络时其实是经历了非线性变换的。
非线性函数数学公式:
Leaky ReLU:
f ( x ) = max ( α x , x ) f(x)=\max (\alpha x, x) f(x)=max(αx,x)
其中 α \alpha α 是很小的负数梯度值,比如0.01
Parametric ReLU:
f ( x ) = max ( α x , x ) f(x)=\max (\alpha x, x) f(x)=max(αx,x)
其中 α \alpha α 是反向传播学习得来的
Leaky ReLU函数及其导数图像:
左半边直线斜率非常接近0,所以看起来像是平的。
评价:
理论上来讲,Leaky ReLU有ReLU的所有优点,外加不会有Dead ReLU问题,但是在实际操作当中,并没有完全证明Leaky ReLU总是好于ReLU。
**解决问题一:**目的是解决ReLU神经元“死掉”的问题,使负轴信息不会全部丢失。
存在问题一: Leaky ReLU函数中的α,需要通过先验知识人工赋值。
“随机修正线性单元”。RReLU是Leaky ReLU的随机版本。
非线性函数数学公式:
y j i = { x j i if x j i ≥ 0 a j i x j i if x j i < 0 where a j i ∼ U ( l , u ) , l < u and l , u ∈ [ 0 , 1 ) \begin{aligned} y_{j i} &=\left\{\begin{array}{ll}{x_{j i}} & {\text { if } x_{j i} \geq 0} \\ {a_{j i} x_{j i}} & {\text { if } x_{j i}<0}\end{array}\right.\\ \text { where } \\ \qquad a_{j i} & \sim U(l, u), lyji where aji={xjiajixji if xji≥0 if xji<0∼U(l,u),l<u and l,u∈[0,1)
函数及其导数图像:
RReLU的核心思想是,在训练过程中,α是从一个高斯分布 U ( l , u ) U(l,u) U(l,u)中随机出来的值,然后再在测试过程中进行修正。在测试阶段,把训练过程中所有的取 a i j a_{ij} aij个平均值。
非线性函数数学公式:
f ( x ) = { x , if x > 0 α ( e x − 1 ) , otherwise f(x)=\left\{\begin{array}{ll}{x,} & {\text { if } x>0} \\ {\alpha\left(e^{x}-1\right),} & {\text { otherwise }}\end{array}\right. f(x)={x,α(ex−1), if x>0 otherwise
函数及其导数图像:
评价:
ELU也是为解决ReLU存在的问题而提出,显然,ELU有ReLU的基本所有优点,不会有Dead ReLU问题,输出的均值接近0,zero-centered。 它的一个小问题在于计算量稍大。类似于Leaky ReLU,理论上虽然好于ReLU,但在实际使用中目前并没有好的证据ELU总是优于ReLU。
这个函数可以参考论文《maxout networks》,Maxout是深度学习网络中的一层网络,就像池化层、卷积层一样等,我们可以把maxout 看成是网络的激活函数层,我们假设网络某一层的输入特征向量为: X = ( x 1 , x 2 , … x d ) X=(x_1,x_2,…x_d) X=(x1,x2,…xd),Maxout隐藏层每个神经元的计算公式如下:
h i ( x ) = max j ∈ [ 1 , k ] z i j h_{i}(x)=\max _{j \in[1, k]} z_{i j} hi(x)=j∈[1,k]maxzij
针对输入是 d d d 个神经元,输出第 i i i 个激活值。 k k k 就是maxout层所需要的参数了,由我们人为设定大小。就像dropout一样,也有自己的参数p(每个神经元dropout概率),maxout的参数是 k k k。公式中 z i j z_{ij} zij的计算公式为:
z i j = x T W i j + b i j z_{i j}=x^{T} W _ {i j}+b_{i j} zij=xTWij+bij
权重 W W W 是一个大小为 ( d , m , k ) (d,m,k) (d,m,k) 三维矩阵, b b b 是一个大小为 ( m , k ) (m,k) (m,k)的二维矩阵,这两个矩阵就是我们需要学习的参数。
类比于ReLU的理解:这里就是增加了一个映射的环节,在激活之前的输入已经准备好为 x x x,但是ReLU直接将他们每一个与0进行比较大小了,这里maxout也是一个比较大小的操作,可以理解为让网络去自行学习一个映射将 x x x自行映射一次然后针对映射后的值进行比较,更加多维并且复杂且适应性更强。
非线性函数数学公式:
f ( x ) = max ( w 1 T x + b 1 , w 2 T x + b 2 ) f(x)=\max \left(w_{1}^{T} x+b_{1}, w_{2}^{T} x+b_{2}\right) f(x)=max(w1Tx+b1,w2Tx+b2)
Maxout是对ReLU和leaky ReLU的一般化归纳(当 w 2 , b 2 w_{2} ,b_{2} w2,b2 退化为0时,即退化为ReLU)
函数图像:
评价:
优点: Maxout具有ReLU的优点,如计算简单,不会 saturation,同时又没有ReLU的一些缺点,如容易go die。
存在问题一: 每个神经元的参数double,这就导致整体参数的数量激增。
非线性函数数学公式:
σ ( z ) j = e z j ∑ k = 1 K e z k \sigma(z)_{j}=\frac{e^{z_{j}}}{\sum_{k=1}^{K} e^{z_{k}}} σ(z)j=∑k=1Kezkezj
Softmax,目的是让大的更大。 就是如果某一个 z j z_j zj大过其他 z i z_i zi, 那这个映射的分量就逼近于 1,其他就逼近于 0,主要应用就是多分类网络的输出。
示意图如下:
Softmax是Sigmoid的扩展,当类别数k=2时,Softmax回归退化为Logistic回归。
评价: 只会被用在网络中的最后一层,用来进行最后的分类和归一化。
讨论: 为什么要取指数
第一个原因是要模拟 max 的行为,所以要让大的更大。
第二个原因是需要一个可导的函数。
比较:
sigmoid将一个real value映射到(0,1)的区间,用来做二分类。
而 softmax 把一个 k 维的real value向量 ( a 1 , a 2 , a 3 , a 4 … ) (a_1,a_2,a_3,a_4… ) (a1,a2,a3,a4…)映射成一个 ( b 1 , b 2 , b 3 , b 4 … ) (b_1,b_2,b_3,b_4…) (b1,b2,b3,b4…)其中 b i b_i bi 是一个 0~1 的常数,输出神经元之和为 1,所以相当于概率值,然后可以根据 b i b_i bi 的概率大小来进行多分类的任务。
二分类问题时 sigmoid 和 softmax 是一样的,求的都是 cross entropy loss,而 softmax 可以用于多分类问题
softmax是sigmoid的扩展,因为,当类别数 k=2 时,softmax 回归退化为 logistic 回归。具体地说,当 k=2 时,softmax 回归的假设函数为:
h ( x ) = 1 e x 1 + e x 2 [ e x 1 e x 2 ] h(x)=\frac{1}{{e^{x_1}}+e^{x_2}} \left[ \begin{array}{c}{e^{x_1}} \\ {e^{x_2}}\end{array} \right] h(x)=ex1+ex21[ex1ex2]
设置参数 x 1 = θ 1 T x x_1={\theta_{1}}^{T} x x1=θ1Tx , x 2 = θ 2 T x x_2={\theta_{2}}^{T} x x2=θ2Tx(即为一个映射),得到
h θ ( x ) = 1 e θ 1 T x + e θ 2 T x [ e θ 1 T x e θ 2 T x ] h_{\theta}(x)=\frac{1}{e^{{\theta_{1}}^{T} x}+e^{{\theta_{2}}^{T} x}}\left[\begin{array}{c}{e^{{\theta_{1}}^{T} x}} \\ {e^{{\theta_{2}}^{T} x}}\end{array}\right] hθ(x)=eθ1Tx+eθ2Tx1[eθ1Txeθ2Tx]
利用softmax回归参数冗余的特点,从两个参数向量中都减去向量 θ 1 \theta_{1} θ1 ,得到:
h ( x ) = 1 e 0 → T x + e ( θ 2 − θ 1 ) T x [ e 0 → T x e ( θ 2 − θ 1 ) T x ] = [ 1 1 + e ( θ 2 − θ 1 ) T x e ( θ 2 − θ 1 ) T x 1 + e ( θ 2 − θ 1 ) T x ] = [ 1 1 + e ( θ 2 − θ 1 ) T x 1 − 1 1 + e ( θ 2 − θ 1 ) T x ] \begin{aligned} h(x) &=\frac{1}{e^{\overrightarrow{0}^{T} x}+e^{\left(\theta_{2}-\theta_{1}\right)^{T} x}}\left[\begin{array}{c}{e^{\overrightarrow{0}^{T} x}} \\ {e^{\left(\theta_{2}-\theta_{1}\right)^{T} x}}\end{array}\right] \\&=\left[\begin{array}{c}{\frac{1}{1+e^{{\left(\theta_{2}-\theta_{1}\right)^{T}} x}}} \\ {\frac{e^{\left(\theta_{2}-\theta_{1}\right)^{T} x}}{1+e^{\left(\theta_{2}-\theta_{1}\right)^{T} x}}}\end{array}\right]\\ &=\left[\begin{array}{c}{\frac{1}{1+e^{\left(\theta_{2}-\theta_{1}\right)^{T} x}}} \\ {1-\frac{1}{1+e^{\left(\theta_{2}-\theta_{1}\right)^{T} x}}}\end{array}\right] \end{aligned} h(x)=e0Tx+e(θ2−θ1)Tx1[e0Txe(θ2−θ1)Tx]=[1+e(θ2−θ1)Tx11+e(θ2−θ1)Txe(θ2−θ1)Tx]=[1+e(θ2−θ1)Tx11−1+e(θ2−θ1)Tx1]
这个问题目前没有确定的方法,凭一些经验吧。
1)深度学习往往需要大量时间来处理大量数据,模型的收敛速度是尤为重要的。所以,总体上来讲,训练深度学习网络尽量使用zero-centered数据 (可以经过数据预处理实现) 和zero-centered输出。所以要尽量选择输出具有zero-centered特点的激活函数以加快模型的收敛速度。
2)如果使用 ReLU,那么一定要小心设置 learning rate,而且要注意不要让网络出现很多 “dead” 神经元,如果这个问题不好解决,那么可以试试 Leaky ReLU、PReLU 或者 Maxout。
3)最好不要用 sigmoid,你可以试试 tanh,不过可以预期它的效果会比不上 ReLU 和 Maxout。
https://zhuanlan.zhihu.com/p/32610035
https://www.jianshu.com/p/22d9720dbf1a
https://blog.csdn.net/tyhj_sf/article/details/79932893
https://www.iteye.com/blog/daizj-2422614
https://juejin.im/entry/5ca186c4e51d4534624698ae
https://www.jiqizhixin.com/articles/2017-10-10-3