一、什么是激活函数?
简单的说,激活函数就是在神经网络的神经元上运行的函数,负责将神经元的输入映射到输出端,它的作用是为了增加神经网络模型的非线性变化。
神经元(Neuron)内右侧的函数,就是激活函数(Activation)
二、深度学习(Deep learning)中的激活函数
- 饱和激活函数问题
假设h(x)是一个激活函数。
1. 当我们的n趋近于正无穷,激活函数的导数趋近于0,那么我们称之为右饱和。
2. 当我们的n趋近于负无穷,激活函数的导数趋近于0,那么我们称之为左饱和。
当一个函数既满足左饱和又满足右饱和的时候我们称之为饱和。
不满足上述两个条件的,称为不饱和激活函数。
2.常用的激活函数
在深度学习中,目前常用的激活函数主要有:sigmoid、tanh、ReLU、PReLU、Swish、Mish,下面一一简要介绍:
(1)Sigmoid
该函数是将取值为 (−∞,+∞) 的数映射到(0,1)之间。
sigmiod函数公式
函数图像
对于sigmoid函数的求导推导为:
梯度消失。
from matplotlib import pyplot as plt
import numpy as np
import math
def sigmoid_function(z):
fz = []
for num in z:
fz.append(1/(1 + math.exp(-num)))
return fz
if __name__ == '__main__':
z = np.arange(-10, 10, 0.01)
fz = sigmoid_function(z)
plt.title('Sigmoid Function')
plt.xlabel('z')
plt.ylabel('σ(z)')
plt.plot(z, fz)
plt.show()
(2)tanh
相较于sigmoid函数要常见一些,该函数是将取值为 (−∞,+∞) 的数映射到 (−1,1) 之间。
tanh函数公式
tanh函数图像:在 0 附近很短一段区域内可看做线性的。由于tanh函数均值为 0 ,因此弥补了sigmoid函数均值为 0.5 的缺点。
对于tanh函数的求导推导为:
梯度消失问题。
(3)ReLU
又称为修正线性单元(Rectified Linear Unit),是一种分段线性函数,其弥补了sigmoid函数以及tanh函数的梯度消失问题。
Relu函数公式
Relu函数图像
对于ReLU函数的求导为:
ReLU函数的优点:
1. 在输入为正数的时候(对于大多数输入 z 空间来说),不存在梯度消失问题。
2. 计算速度要快很多。ReLU函数只有线性关系,不管是前向传播还是反向传播,都比sigmod和tanh要快很多。(sigmod和tanh要计算指数,计算速度会比较慢) ReLU函数的缺点:
当输入为负时,梯度为0,会产生 梯度消失问题。
(4)Leaky ReLU
它是一种对ReLU函数改进的函数,又称为PReLU函数。
PReLU函数公式,其中 a 取值在 (0,1) 之间。
PReLU函数图像
Leaky ReLU函数的导数为:
输入为负的情况下产生的梯度消失问题。
(5)Swish
Swish 在深层模型上的效果优于 ReLU。可以看做是介于线性函数与ReLU函数之间的平滑函数.例如,仅仅使用 Swish 单元替换 ReLU 就能把 Mobile NASNetA 在 ImageNet 上的 top-1 分类准确率提高 0.9%,Inception-ResNet-v 的分类准确率提高 0.6%。
函数公式:
β是个常数或可训练的参数,Swish 具备无上界有下界、平滑、非单调的特性。
Swish函数图像
(6)Mish
一种自正则的非单调神经激活函数,平滑的激活函数允许更好的信息深入神经网络,从而得到更好的准确性和泛化。根据论文实验,该函数在最终准确度上比Swish(+0.494%)和ReLU(+ 1.671%)都有提高。
Mish: A Self Regularized Non-Monotonic Neural Activation Functionarxiv.org
函数公式:
函数图像:
Mish函数图像
# torch中代码实现
class Mish(nn.Module):
def __init__(self):
super().__init__()
print("Mish avtivation loaded...")
def forward(self,x):
x = x * (torch.tanh(F.softplus(x)))
return x
三、常见激活函数对比