机器学习笔记11—机器学习/深度学习之激活函数及python代码实现

ML/DL之激活函数

  • 1、概述
  • 2、激活函数性质
  • 3、常用的激活函数
    • 3.1 Sigmoid函数(Logistic函数)
    • 3.2 Tanh函数
    • 3.3 ReLU函数
    • 3.4 Leaky ReLU函数
    • 3.5 PReLU函数
    • 3.6 ELU函数
    • 3.7 Softplus函数
  • 4、激活函数的选择

1、概述

神经网络神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数 Activation Function。
机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第1张图片
为什么要使用激活函数?

激活函数的作用

  • 加入非线性因素( 不使用激活函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合。)
  • 充分组合特征

神经网络中激活函数的主要作用是提供网络的非线性建模能力,如不特别说明,激活函数一般而言是非线性函数。假设一个示例神经网络中仅包含线性卷积和全连接运算,那么该网络仅能够表达线性映射,即便增加网络的深度也依旧还是线性映射,难以有效建模实际环境中非线性分布的数据。加入(非线性)激活函数之后,深度神经网络才具备了分层的非线性映射学习能力。

在神经网络中,激活函数不是真的去激活什么,而是用激活函数给神经网络加入一些非线性因素,使得网络可以更好地解决较为复杂的问题。比如有些问题是线性可分的,而现实场景中更多问题不是线性可分的,若不使用激活函数则难以拟合非线性问题,测试时会有低准确率。所以激活函数主要是非线性的,如sigmoid、tanh、relu。sigmoid函数通常用于二分类,但要防止梯度消失,故适合浅层神经网络且需要配备较小的初始化权重,tanh函数具有中心对称性,适合于有对称性的二分类。注意:不能在隐藏层里用线性激活函数,唯一可以使用线性激活函数的通常就是输出层。

在深度学习中,relu是使用最多的激活函数,简单又避免了梯度消失。

2、激活函数性质

非线性处理单元。激活函数使神经网络具有非线性。它决定感知机是否激发。

  • 非线性:激活函数的这种非线性,赋予了深度网络学习复杂函数的能力。
  • 可微性:除了在0点的修正单元以外,大多数激活函数都是连续并可导。
  • 激活函数及其导函数要尽可能的简单,有利于提高网络计算效率。
  • 激活函数的导函数的值域要在一个合适的区间内,不能太大也不能太小,否则会影响训练的效率和稳定性。

3、常用的激活函数

  • Sigmoid函数
  • tanh函数
  • ReLU函数
  • Leaky ReLU函数
  • ELU函数
  • Softmax函数

在这里插入图片描述

3.1 Sigmoid函数(Logistic函数)

Sigmoid函数是一个在生物学中常见的S型函数,也称为S型生长曲线。 在信息科学中,由于其单增以及反函数单增等性质,Sigmoid函数常被用作神经网络的阈值函数,将变量映射到0,1之间,因此有时被称为“挤压函数”。

Sigmoid函数定义:
f ( x ) = 1 1 + e − x f(x)=\frac{1}{1+e^{-x}} f(x)=1+ex1

Sigmoid函数图像:

机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第2张图片
python实现之

import numpy as np
import matplotlib.pyplot as plt 
def sigmoid(z):
    return 1/(1+np.exp(-z))

nums=np.arange(-10,10,step=1)
fig,ax=plt.subplots(figsize=(12,8))
ax.plot(nums,sigmoid(nums),'r')
plt.title('sigmoid函数曲线图')
plt.show()

机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第3张图片

Sigmoid函数求导:

f ′ ( x ) = ( 1 1 + e − x ) ′ = e − x ( 1 + e − x ) 2 = f ( x ) ( 1 − f ( x ) ) f^{'}(x)=(\frac{1}{1+e^{-x}})^{'}=\frac{e^{-x}}{(1+e^{-x})^2}=f(x)(1-f(x)) f(x)=(1+ex1)=(1+ex)2ex=f(x)(1f(x))

优点:

  • 是能够控制数值的幅度,在深层网络中可以保持数据幅度不会出现大的变化

  • 主要用于二分类

  • 因可解释为神经元的饱和激发率(firing rate) ,历史上比较流行。

缺点:

  • 饱和神经元 会“kill” 梯度(引起梯度消失):指离中心点较远的x处的导数接近于0,停止反向传播的学习过程。

  • Sigmoid输出不是零中心的,这样在求权重w的梯度时,梯度总是正或负的。

  • . exp() 运算导致计算较复杂。

注:软饱和和硬饱和

sigmoid 在定义域内处处可导,且两侧导数逐渐趋近于0。Bengio 教授等[1]将具有这类性质的激活函数定义为软饱和激活函数。与极限的定义类似,饱和也分为左饱和(左边的导数逐渐趋于0)与右饱和(右边的导数逐渐趋于0)。

与软饱和相对的是硬饱和激活函数,即:f’(x)=0,当 |x| > c,其中 c 为常数。同理,硬饱和也分为左饱和和右饱和。常见的 ReLU 就是一类左侧硬饱和激活函数。

3.2 Tanh函数

Tanh函数是sigmoid函数的一种变体,又称双曲正切激活函数。

Tanh函数定义:
t a n h ( x ) = e x p ( x ) − e x p ( − x ) e x p ( x ) + e x p ( − x ) tanh(x)=\frac{exp(x)-exp(-x)}{exp(x)+exp(-x)} tanh(x)=exp(x)+exp(x)exp(x)exp(x)
t a n h ( x ) = 2 s i g m o i d ( 2 x ) − 1 tanh(x)=2sigmoid(2x)−1 tanh(x)=2sigmoid(2x)1

  • 定义域:R,
  • 值域:(-1,1)。
  • y = t a n h x y=tanh x y=tanhx是一个奇函数,其函数图像为过原点并且穿越Ⅰ、Ⅲ象限的严格单调递增曲线,其图像被限制在两水平渐近线y=1和y=-1之间。
  • tanh函数的值域是[-1,1]。双曲正切“tanh”是由基本双曲函数双曲正弦和双曲余弦推导而来。

Tanh函数及其导数图像

在这里插入图片描述

python实现之

import numpy as np
import matplotlib.pyplot as plt 
def tanh(x):
    return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(111)

x = np.linspace(-10, 10)
y = tanh(x)


ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')

ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.set_xticks([-10, -5, 0, 5, 10])
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
ax.set_yticks([-1, -0.5, 0.5, 1])

plt.plot(x, y, label="Tanh", color="red")
plt.legend()
plt.show()

机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第4张图片
Tanh函数求导

t a n h ′ ( x ) = [ e x p ( x ) − e x p ( − x ) e x p ( x ) + e x p ( − x ) ] ′ = 1 − t a n h ( x ) 2 tanh'(x)=[\frac{exp(x)-exp(-x)}{exp(x)+exp(-x)}]^{'}=1-tanh(x)^2 tanh(x)=[exp(x)+exp(x)exp(x)exp(x)]=1tanh(x)2

python实现之图像:

import numpy as np
import matplotlib.pyplot as plt 
def dtanh(x):
    return 1-pow((np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x)),2)
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(111)

x = np.linspace(-10, 10)
y = dtanh(x)


ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')

ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.set_xticks([-10, -5, 0, 5, 10])
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
ax.set_yticks([-1, -0.5, 0.5, 1])

plt.plot(x, y, label="dTanh(x)/dx", color="red")
plt.legend()
plt.show()

机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第5张图片
优点:

  • tanh在特征相差明显时的效果会很好,在循环过程中会不断扩大特征效果。

  • 输出零中心。

  • tanh相比sigmoid收敛更快

    • 梯度消失问题程度
      tanh′(x)=1−tanh(x)2∈(0,1)
      sigmoid: s′(x)=s(x)×(1−s(x))∈(0,1/4)
      可以看出tanh(x)的梯度消失问题比sigmoid要轻.梯度如果过早消失,收敛速度较慢.
    • 以零为中心的影响
      如果当前参数(w0,w1)的最佳优化方向是(+d0, -d1),则根据反向传播计算公式,我们希望 x0 和 x1 符号相反。但是如果上一级神经元采用 Sigmoid 函数作为激活函数,sigmoid不以0为中心,输出值恒为正,那么我们无法进行最快的参数更新,而是走 Z 字形逼近最优解
  • 与 sigmoid 的区别是,tanh(x)的梯度消失问题比sigmoid要轻;tanh 是 0 均值的,因此实际应用中 tanh 会比 sigmoid 更好。一般优化算法里,大部分会选择tanh函数(但在二分类问题中,选用sigmoid函数使输出值介于0和1之间)。因为 tanh 的输出均值比 sigmoid 更接近 0,SGD会更接近 natural gradient[4](一种二次优化技术),从而降低所需的迭代次数。

缺点:

  • 饱和神经元仍然会“kill” 梯度。
  • tanh读作Hyperbolic Tangent,它解决了Sigmoid函数的不是zero-centered输出问题,然而,梯度消失(gradient vanishing)的问题和幂运算的问题仍然存在。

hard-tanh、hard-logistic

Logistic函数和Tanh函数都是Sigmoid函数,具有饱和性,但是计算开销较大。因为这两个函数都是在中间(0附近)近似线性,两端饱和。因此,这两个函数可以分别通过分段函数hard-tanh、hard-logistic来近似。

硬双曲正切函数(hard tanh),和 tanh 以及整流线性单元类似,但是不同于后者,它是有界的。

定义:
h a r d − t a n h ( x ) = m a x ( m i n ( x , 1 ) , − 1 ) hard-tanh(x)=max(min(x,1),-1) hardtanh(x)=max(min(x,1),1)

也可以写为:

机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第6张图片
h a r d − l o g i s t i c ( x ) = m a x ( m i n ( 0.25 x + 0.5 , 1 ) , 0 ) hard-logistic(x)=max(min(0.25x+0.5,1),0) hardlogistic(x)=max(min(0.25x+0.5,1),0)

机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第7张图片

3.3 ReLU函数

ReLU(Rectified Linear Unit),又称修正线性单元ReLU,是一种分段函数。通常指代以斜坡函数及其变种为代表的非线性函数,是目前深度神经网络中最常用的激活函数。

ReLU函数定义:
R e L U ( x ) = m a x ( 0 , x ) ReLU(x)=max(0,x) ReLU(x)=max(0,x)
ReLU函数求导:

R e L U ′ ( x ) = { 0 x<0 1 x ≥  0 ReLU'(x)= \begin{cases} 0& \text{x<0}\\ 1& \text{x$\geq$ 0} \end{cases} ReLU(x)={01x<0x 0

通常在 x = 0 x=0 x=0处,取其导数为1。因为 x = 0 x=0 x=0的概率很小很小。

ReLU函数图像:
机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第8张图片

【python代码】

import numpy as np
import matplotlib.pyplot as plt 
def ReLU(x):
    return np.maximum(0,x)
fig = plt.figure(figsize=(6, 4))
ax = fig.add_subplot(111)

x = np.linspace(-10, 10)
y = ReLU(x)


ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')

ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.set_xticks([-10,10])
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
ax.set_yticks([0, 10])

plt.plot(x, y, label="ReLU(x)", color="red")
plt.legend()
plt.show()

为了克服梯度弥散,2006年Hinton提出ReLU,不再依赖于无监督学习逐层进行预训练,直接通过监督学习来训练网络,并在2012年的竞赛中ILSVRC中取得里程碑式突破。

优点:

  • 减轻梯度消失问题 相比非线性激活函数,RELU有效克服了梯度弥散在反向传播中的问题,使网络可以训练得更深,收敛更快。由于x>0时偏导数为1, ReLU能够在x>0时保持梯度不衰减缓解梯度消失问题,加速梯度下降的收敛速度。
  • 速度快 采用ReLU的神经元只需进行加、乘和比较的操作,计算效率高。
  • 实际应用中比sigmoid/tanh收敛速度快很多。
  • 稀疏性 通过对大脑的研究发现,大脑在工作的时候只有大约5%的神经元是激活的,而采用sigmoid激活函数的人工神经网络,其激活率大约是50%。有论文声称人工神经网络在15%-30%的激活率时是比较理想的。因为relu函数在输入小于0时是完全不激活的,因此可以获得一个更低的激活率。

缺点:

  • 输出具有偏移现象,即输出均值恒大于零,给后一层的神经网络引入偏置偏移,会影响梯度下降的速率。
  • 神经元死亡现象 由于ReLU在x < 0时梯度为0,这样就导致负的梯度在这个ReLU被置零,而且这个神经元有可能再也不会被任何数据激活,称为神经元“坏死”。例子:一个非常大的梯度流过一个 ReLU 神经元,更新过参数之后(lz:参数很可能变为一个很大的负值,之后正向传播时很大概率会使激活aj为0,就死了δj = σ’(aj)∑δkwkj中aj为0之后δj也一直为0),这个神经元可能再也不会对任何数据有激活现象了。

偏移现象和 神经元死亡会共同影响网络的收敛性。

在实际应用中,为了避免上述情况,有几种ReLU的变种也会被广泛使用。


ReLU的变种

3.4 Leaky ReLU函数

带泄露的ReLU(Leaky ReLU)在输入x<0时,保持一个很小的梯度 γ \gamma γ。这样当神经元非激活时也能有一个非零的梯度可以更新参数,避免不能被激活。

Leaky ReLU函数定义:
L e a k y R e L U ( x ) = { x x>0 γ x x<0 = m a x ( 0 , x ) + m i n ( 0 , x ) LeakyReLU(x)=\begin{cases} x& \text{x>0}\\ \gamma x& \text{x<0} \end{cases}=max(0,x)+min(0,x) LeakyReLU(x)={xγxx>0x<0=max(0,x)+min(0,x)

其中, γ \gamma γ是一个很小的常数,比如0.01,当 γ < 1 \gamma<1 γ<1时,
L e a k y R e L U ( x ) = m a x ( x , γ x ) LeakyReLU(x)=max(x,\gamma x) LeakyReLU(x)=max(x,γx)

通常来说, L e a k y R e L U ( x ) = m a x ( x , 0.01 x ) LeakyReLU(x)=max(x,0.01 x) LeakyReLU(x)=max(x,0.01x)

3.5 PReLU函数

带参数的ReLU(PReLU),就是在ReLU函数基础上引入一个可学习的参数 α \alpha α,不同的神经元可以有不同的参数,对于第i个神经元,其 PReLU定义为:
P R e L U i ( x ) = { x x>0 α i x x<=0 = m a x ( 0 , x ) + α i m i n ( 0 , x ) PReLU_i(x)=\begin{cases} x& \text{x>0}\\ \alpha_i x& \text{x<=0} \end{cases}=max(0,x)+\alpha_imin(0,x) PReLUi(x)={xαixx>0x<=0=max(0,x)+αimin(0,x)

其中 α i \alpha_i αi为斜率。因此,PReLU为非饱和函数,如果 α i = 0 \alpha_i=0 αi=0,就退化为ReLU;如果 α i = 0.01 \alpha_i=0.01 αi=0.01,就为 Leaky ReLU函数。PReLU可以允许不同神经元具有不同的参数,也可以一组神经元共享一个参数。

优点:

  • 不会过拟合(saturate)
  • 计算简单有效
  • 比sigmoid/tanh收敛快
  • 与ReLU相比,PReLU收敛速度更快。因为PReLU的输出更接近0均值,使得SGD更接近natural gradient。

ReLU家庭像
机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第9张图片
Leaky ReLU α是固定的;PReLU的α不是固定的,通过训练得到;RReLU的α是从一个高斯分布中随机产生,并且在测试时为固定值,与Noisy ReLU类似(但是区间正好相反)。

3.6 ELU函数

ELU(指数线性单元)是一个近似的零中心化的非线性函数。

ELU函数定义:

f ( x ) = { x x>0 α ( e x p ( x ) − 1 ) x<=0 = m a x ( 0 , x ) + m i n ( 0 , α ( e x p ( x ) − 1 ) ) f(x)=\begin{cases} x& \text{x>0}\\ \alpha(exp(x)-1)& \text{x<=0} \end{cases}=max(0,x)+min(0,\alpha(exp(x)-1)) f(x)={xα(exp(x)1)x>0x<=0=max(0,x)+min(0,α(exp(x)1))

ELU函数求导:
f ( x ) = { 1 x>0 f ( x ) + α x<=0 f(x)=\begin{cases} 1& \text{x>0}\\ f(x)+\alpha& \text{x<=0} \end{cases} f(x)={1f(x)+αx>0x<=0

其中, α > = 0 \alpha>=0 α>=0是一个超参数,决定 x < = 0 x<=0 x<=0的饱和曲线,并调整输出均值在0附近。

ELU被证实有较高的噪声鲁棒性,同时能够使得使得神经元
的平均激活均值趋近为 0,同时对噪声更具有鲁棒性。由于需要计算指数,计算量较大。

优点:

  • 具有ReLU函数的所有优点。
  • 输出均值接近零。
  • 负饱和区域,相比Leaky ReLU增加了对噪声的鲁棒性。

机器学习笔记11—机器学习/深度学习之激活函数及python代码实现_第10张图片

3.7 Softplus函数

未完待续

参考资料:
深度学习

4、激活函数的选择

选择激活函数的经验法则:
1、如果输出是0、1值(二分类问题),则输出层选择sigmoid函数,然后其他的所有神经单元都选择Relu函数。
2、sigmoid函数:除了输出层是一个二分类问题,基本不会用它。
3、tanh函数:tanh是非常优秀的,几乎适合所有场合。
4、ReLU激活函数:最常用的默认函数,如果不确定用哪个激活函数,就使用ReLu或者Leaky ReLU。
5、如果ReLU效果欠佳,尝试Leaky ReLU或Maxout等变种。
6、在浅层神经网络中,如不超过4层的,可选择使用多种激励函数,没有太大的影响。

如果不确定哪个激活函数效果更好,可以都试试,然后在验证集上进行评价。

你可能感兴趣的:(机器学习,#,深度学习,激活函数,机器学习,神经网络)