1. 为什么要有激活函数
若网络中不用激活函数,那么每一层的输出都是输入的线性组合。无论神经网络有多少层,网络的输出都是输入的线性组合,这种网络就是原始的感知机( P e r c e p t r o n Perceptron Perceptron)。若网络没有激活函数,则每层就相当于矩阵相乘,深层神经网络,无非是多矩阵相乘。
激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。网络使用非线性激活函数后,可以增加神经网络模型的非线性因素,网络可以更加强大,表示输入输出之间非线性的复杂的任意函数映射。
网络的输出层可能会使用线性激活函数,但隐含层一般都是使用非线性激活函数。
2. 非零均值的问题(non-zero-centered)
部分激活函数是非零均值的,如 R e L U ReLU ReLU, S i g m o i d Sigmoid Sigmoid等激活函数,他会造成网络收敛很慢。我们可以简单看下表示式: f = ( w i x i + b ) f=(w_{i} x_{i}+b) f=(wixi+b),其中 x i x_{i} xi为 s i g m o i d sigmoid sigmoid函数的输出。那么,在计算损失函数后,需要进行反向传播更新该权重 w i w_{i} wi。这时候,对 w i w_{i} wi进行求导,是直接与 x i x_{i} xi相关的,而因为 x i x_{i} xi是大于 0 0 0的值,所以这时候的梯度方向就会完全取决于 d L d f \frac{dL}{df} dfdL。这时候若 d L d f \frac{dL}{df} dfdL恒正或者恒为负,那么就会出现 z i g − z a g g i n g zig-zagging zig−zagging d y n a m i c s dynamics dynamics的问题,使得网络收敛变慢。
其中 z i g − z a g g i n g zig-zagging zig−zagging 的图像就如下面图像:
下面开始我们介绍下常用的激活函数,其中对于部分激活函数,画图都是采用Pytorch中Functional的默认参数来进行绘制的。
1. Sigmoid激活函数
sigmoid函数公式如下:
f ( z ) = 1 1 + exp ( − z ) f(z)=\frac{1}{1+\exp (-z)} f(z)=1+exp(−z)1
S i g m o i d Sigmoid Sigmoid函数也叫 L o g i s t i c Logistic Logistic函数,用于用于隐层神经元输出,取值范围为 ( 0 , 1 ) (0,1) (0,1),它可以将一个实数映射到 ( 0 , 1 ) (0,1) (0,1) 的区间,可以用来做二分类或者生成 A t t e n t i o n Attention Attention $ Mask$。在特征相差比较复杂或是相差不是特别大时效果比较好。
s i g m o i d sigmoid sigmoid 激活函数的缺点有:
- 激活函数计算量大,反向传播求误差梯度时,求导涉及除法;
- 反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练;
- S i g m o i d Sigmoid Sigmoid 是非零均值的函数,收敛缓慢。
- S i g m o i d Sigmoid Sigmoid函数运算量大。如我们用 F L O P s FLOPs FLOPs(每秒浮点操作次数)来衡量模型的计算量指标。则 R e L U ReLU ReLU运算量是1 F L O P s FLOPs FLOPs。那么Sigmoid包括了减、取幂、加、除共4 F L O P s FLOPs FLOPs.
s i g m o i d sigmoid sigmoid 激活函数出现梯度消失的原因如下:
反向传播算法中,要对激活函数求导,
s
i
g
m
o
i
d
sigmoid
sigmoid 的导数表达式为:
ϕ
′
(
x
)
=
ϕ
(
x
)
(
1
−
ϕ
(
x
)
)
\phi^{\prime}(x)=\phi(x)(1-\phi(x))
ϕ′(x)=ϕ(x)(1−ϕ(x))
s
i
g
m
o
i
d
sigmoid
sigmoid 激活函数原函数及导数图形如下:由图可知,导数从0 开始很快就又趋近于0 了,易造成“梯度消失”现象。
2. TanH激活函数
T
a
n
H
TanH
TanH 激活函数的公式如下,也称为双切正切函数,取值范围为[-1,1]。
tanh
(
x
)
=
2
sigmoid
(
2
x
)
−
1
f
(
z
)
=
tanh
(
z
)
=
e
z
−
e
−
z
e
z
+
e
−
z
\begin{array}{l} \tanh (x)=2 \operatorname{sigmoid}(2 x)-1 \\ f(z)=\tanh (z)=\frac{e^{z}-e^{-z}}{e^{z}+e^{-z}} \end{array}
tanh(x)=2sigmoid(2x)−1f(z)=tanh(z)=ez+e−zez−e−z
而
T
a
n
h
Tanh
Tanh函数的反传公式为:
g
′
(
z
)
=
(
e
z
−
e
−
z
e
z
+
e
−
z
)
′
=
4
(
e
z
+
e
−
z
)
2
=
1
−
g
(
z
)
2
\begin{aligned} g^{\prime}(z) &=\left(\frac{e^{z}-e^{-z}}{e^{z}+e^{-z}}\right)^{\prime} \\ &=\frac{4}{\left(e^{z}+e^{-z}\right)^{2}} \\ &=1-g(z)^{2} \end{aligned}
g′(z)=(ez+e−zez−e−z)′=(ez+e−z)24=1−g(z)2
T
a
n
H
TanH
TanH函数的缺点同
s
i
g
m
o
i
d
sigmoid
sigmoid函数的缺点类似。当 z 很大或很小时,𝑔′(𝑧) 接近于 0 ,会导致梯度很小,权重更新非常缓慢,即梯度消失问题。从下面的图像也能看出来,靠近图像两端越平缓,梯度越小。
T a n H TanH TanH 激活函数函数图像如图所示。
T a n h Tanh Tanh 在特征相差明显时的效果会相对更好,在循环过程中会不断扩大特征效果。与 s i g m o i d sigmoid sigmoid 的区别是, t a n h tanh tanh 是 0 0 0 均值的,因此实际应用中 t a n h tanh tanh 会比 s i g m o i d sigmoid sigmoid 更好,不过需要具体尝试。
3. ReLU激活函数
R e L U ReLU ReLU (Rectified Liner Unit)激活函数主要用于隐层神经元输出,公式为 f ( x ) = m a x ( 0 , x ) f(x)=max(0,x) f(x)=max(0,x),函数图像与其求导的导数图像如图所示:
-
R e L U ReLU ReLU 激活函数的特点是:输入信号小于时,输出都是0,输入信号大于0时,输出等于输入。
-
R e L U ReLU ReLU 的优点是使用 R e L U ReLU ReLU 得到的 S G D SGD SGD 的收敛速度会比使用 s i g m o i d / t a n h sigmoid/tanh sigmoid/tanh的 S G D SGD SGD 快很多。
-
R e L U ReLU ReLU 的缺点是神经网络训练的时候很“脆弱”,很容易就会出现神经元死亡。
例如,一个非常大的梯度流过一个 R e L U ReLU ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了,那么这个神经元的梯度就永远都会是 0 0 0。(Dead ReLU Problem)。
-
非零均值,所以一般 R e L U ReLU ReLU后会加 B N BN BN。
4. Softmax 激活函数
多用于多分类神经网络输出,公式为:
主要用于分类最后归一化到 [ 0 , 1 ] [0,1] [0,1] , j ∈ [ 1 , K ] j \in [1, K] j∈[1,K]。当然也与 S i g m o i d Sigmoid Sigmoid一样,可以用在attention之中,学习到权重的矩阵。
5. Softplus激活函数
公式如下:
y
=
log
(
1
+
e
x
)
y=\log \left(1+e^{x}\right)
y=log(1+ex)
将
R
e
L
U
ReLU
ReLU与
S
o
f
t
p
l
u
s
Softplus
Softplus放在一起对比的话,则如图像所示:
可以看到, s o f t p l u s softplus softplus可以看作是 R e L U ReLU ReLU的平滑。其中,加了 1 1 1是为了保证非负性。 S o f t p l u s Softplus Softplus可以看作是强制非负校正函数 m a x ( 0 , x ) max(0,x) max(0,x)平滑版本。
6. Mish激活函数
M
i
s
h
Mish
Mish函数的公式如下:
Mish
=
x
∗
tanh
(
ln
(
1
+
e
x
)
)
\text { Mish }=x * \tanh \left(\ln \left(1+e^{x}\right)\right)
Mish =x∗tanh(ln(1+ex))
在
P
y
t
o
r
c
h
Pytorch
Pytorch中
M
i
s
h
Mish
Mish激活函数代码如下:
x = x * (torch.tanh(F.softplus(x)))
函数图像如图所示:
M i s h Mish Mish函数,以上无边界(即正值可以达到任何高度)避免了由于封顶而导致的饱和。理论上对负值的轻微允许允许更好的梯度流,而不是像 R e L U ReLU ReLU中那样的硬零边界。
最后,可能也是最重要的,平滑的激活函数允许更好的信息深入神经网络,从而得到更好的准确性和泛化。
不过我 之前亲自训过 M i s h Mish Mish这个激活函数, P y t o r c h Pytorch Pytorch版本的 M i s h Mish Mish很占显存。
7. Leaky ReLU与PReLU
L e a k y Leaky Leaky R e L U ReLU ReLU的公式如下:
a i a_{i} ai是一个 ( 1 , + ∞ ) (1,+\infty) (1,+∞)区间内的固定参数。与 R e L U ReLU ReLU 相比 , l e a k y leaky leaky R e L U ReLU ReLU 给所有负值赋予一个非零斜率 a i a_{i} ai。这样保留了一些负轴的值,使得负轴的信息不会全部丢失。
而 P R e L U PReLU PReLU可以看作是 L e a k y Leaky Leaky R e L U ReLU ReLU的一个变体。在 P R e L U PReLU PReLU中,负值部分的斜率 a i a_{i} ai是根据网络学习来定的,而非预先定义的。作者称,在 I m a g e N e t ImageNet ImageNet分类(2015,Russakovsky等)上, P R e L U PReLU PReLU是超越人类分类水平的关键所在。
如 L e a k y Leaky Leaky R e L U ReLU ReLU与 P R e L U PReLU PReLU主要的特点是:(1)计算简单,有效 (2)比 S i g m o i d Sigmoid Sigmoid与 T a n h Tanh Tanh收敛更快 (3) 解决了 D e a d Dead Dead R e L U ReLU ReLU的问题。
8. RReLU激活函数
R R e L U RReLU RReLU(Randomized leaky rectified linear unit)也是 L e a k y Leaky Leaky R e L U ReLU ReLU的一个变体。在 R R e L U RReLU RReLU中, a j i a_{ji} aji是一个在一个给定的范围内随机抽取的值,这个值在测试环节就会固定下来
R R e L U RReLU RReLU的亮点在于,在训练环节中, a j i a_{ji} aji是从一个均匀的分布 U ( I , u ) U(I,u) U(I,u)中随机抽取的数值。形式上来说,我们能得到以下结果:
where
a
j
i
∼
U
(
l
,
u
)
,
l
<
u
,
u
∈
[
0
,
1
)
a_{j i} \sim U(l, u), l < u, u \in [0, 1)
aji∼U(l,u),l<u,u∈[0,1)
该函数的图像如下图所示:
9. ELU激活函数
E
L
U
ELU
ELU同样是针对
R
e
L
U
ReLU
ReLU的负数部分进行的改进,
E
L
U
ELU
ELU激活函数对
x
x
x小于零的情况采用类似指数计算的方式进行输出:
ELU
(
x
)
=
max
(
0
,
x
)
+
min
(
0
,
α
∗
(
exp
(
x
)
−
1
)
)
\operatorname{ELU}(x)=\max (0, x)+\min (0, \alpha *(\exp (x)-1))
ELU(x)=max(0,x)+min(0,α∗(exp(x)−1))
或者表达为:
对于 E L U ELU ELU有这些特点:
- E L U ELU ELU由于其正值特性,可以像 R e L U ReLU ReLU, L e a k y Leaky Leaky R e L U ReLU ReLU, P R e L U PReLU PReLU一样缓解梯度消失的问题。
- 相比 R e L U ReLU ReLU, E L U ELU ELU存在负值,可以将激活单元的输出均值往 0 0 0推近,达到接近 B N BN BN的效果同时减少了计算量。
10. Swish激活函数
激活函数的公式如下:
f
(
x
)
=
x
⋅
sigmoid
(
β
x
)
f(x)=x \cdot \operatorname{sigmoid}(\beta x)
f(x)=x⋅sigmoid(βx)
其函数图像如下:
其中, β \beta β是常数或可训练的参数。 S w i s h Swish Swish函数具备无上界有下界、平滑、非单调的特性。通过实验证明,对于深层模型, S w i s h Swish Swish的效果是优于 R e L U ReLU ReLU的。
当
β
=
0
\beta=0
β=0时,
S
w
i
s
h
Swish
Swish激活函数成为线性函数
f
(
x
)
=
x
2
f(x)=\frac{x}{2}
f(x)=2x。
当
β
→
∞
,
σ
(
x
)
=
(
1
+
exp
(
−
x
)
)
−
1
\beta \rightarrow \infty, \sigma(x)=(1+\exp (-x))^{-1}
β→∞,σ(x)=(1+exp(−x))−1 为0或1. Swish变为ReLU:
f
(
x
)
=
2
max
(
0
,
x
)
f(x)=2 \max (0, x)
f(x)=2max(0,x)。
以
S
w
i
s
h
Swish
Swish函数可以看做是介于线性函数与
R
e
L
U
ReLU
ReLU函数之间的平滑函数.
11. SELU激活函数
S E L U SELU SELU是给 E L U ELU ELU乘上系数 β \beta β, 即$ SELU(x)=𝜆⋅ELU(x)$。
文章中主要证明是当取得 λ ≈ 1.0507 , α ≈ 1.6733 \lambda \approx 1.0507, \alpha \approx 1.6733 λ≈1.0507,α≈1.6733时,在网络权重服从标准正态分布的条件下,各层输出的分布会向标准正态分布靠拢,这种"自我标准化"的特性可以避免梯度消失于梯度爆炸,证明过程各位感兴趣的可以去看看90多页的原文。
函数图像如图所示:
12. GELU激活函数
受启发于 D r o p o u t Dropout Dropout、 R e L U ReLU ReLU等机制的影响,都意在将不重要的信息设置为0。对于输入的值,我们可以理解成是将输入的值乘以了一个0或者1。即对于每一个输入 x x x,其服从于标准正态分布 N ( 0 , 1 ) N(0,1) N(0,1),它也会乘以一个伯努利分布 B e r n o u l l i ( ϕ ( x ) ) Bernoulli(\phi(x)) Bernoulli(ϕ(x)),其中 ϕ ( x ) = P ( x ≤ x ) \phi(x)=P(x \leq x) ϕ(x)=P(x≤x)。
G E L U GELU GELU(Gaussian error linear units)的表达式为 GELU ( x ) = x P ( X ≤ x ) = x Φ ( x ) \operatorname{GELU}(x)=x P(X \leq x)=x \Phi(x) GELU(x)=xP(X≤x)=xΦ(x)。
而上式函数是无法直接计算的,因此可以使用另外的方式来进行逼近,论文得到的表达式为: 0.5 x ( 1 + tanh [ 2 / π ( x + 0.044715 x 3 ) ] ) 0.5 x\left(1+\tanh \left[\sqrt{2 / \pi}\left(x+0.044715 x^{3}\right)\right]\right) 0.5x(1+tanh[2/π(x+0.044715x3)])。或者为 G E L U ( x ) = x 1 + e − 1.702 x GELU(x)=\frac{x}{1+e^{-1.702 x}} GELU(x)=1+e−1.702xx。
b e r t bert bert, T r a n s f o r m e r Transformer Transformer中使用的激活函数,作者经过实验证明比 r e l u relu relu等要好。原点可导,不会有 D e a d Dead Dead R e L U ReLU ReLU问题。
其函数图像如图所示:
大家好,我是灿视。目前是位算法工程师 + 创业者 + 奶爸的时间管理者!
我曾在19,20年联合了各大厂面试官,连续推出两版《百面计算机视觉》,受到了广泛好评,帮助了数百位同学们斩获了BAT等大小厂算法Offer。现在,我们继续出发,持续更新最强算法面经。
我曾经花了4个月,跨专业从双非上岸华五软工硕士,也从不会编程到进入到百度与腾讯实习。
欢迎加我私信,点赞朋友圈,参加朋友圈抽奖活动。如果你想加入<百面计算机视觉交流群>,也可以私我。