查看原文
其他

【强基固本】从Binary到Swish——激活函数深度详解

“强基固本,行稳致远”,科学研究离不开理论基础,人工智能学科更是需要数学、物理、神经科学等基础学科提供有力支撑,为了紧扣时代脉搏,我们推出“强基固本”专栏,讲解AI领域的基础知识,为你的科研学习提供助力,夯实理论基础,提升原始创新能力,敬请关注。

作者:知乎—帅比了白

地址:https://www.zhihu.com/people/he-chao-14-51

激活函数是神经网络中最精华的部分之一,它使得神经元有了非线性的拟合能力,这就意味着大规模的复杂参数学习成为了可能,本文将回顾所有常用的激活函数,并展示其python实现过程。
常见的激活函数有以下若干种
  • Binary
  • Linear
  • Sigmoid
  • Tanh
  • ReLU
  • Leaky ReLU (LReLU)
  • Parametric ReLU (PReLU)
  • Exponential Linear Unit (eLU)
  • ReLU-6
  • Softplus
  • Softsign
  • Softmax
  • Swish

01

Binary
Binary是最简单的激活函数,它的本质是一个二分类器。当值大于0时output为1,反之当值小于0时output为0
def binary_active_function(x): return 0 if x < 0 else 1
我们看一下binary激活函数的效果
for i in [-5,-3,-1,0,3,5]: print(binary_active_function(i))
output:000111
优点
  • 简单的二分类
缺点
  • 不适用于多分类情况
  • 其导数总是0,无法做到更新权重

02

Linear activation function
Linear function则是将线性回归的想法引入了激活函数,直接看代码
def linear_active_function(a,x): return a * x
同样看一下效果
x = numpy.linspace(-10,10,500)y_1 = [linear_active_function(1,i) for i in x] # a=1y_2 = [linear_active_function(2,1) for i in x] # a=2
y_1[-10.0,-9.9,-9.8,-9.7,... ...,9.7,9.8,9.9,10.0]
当a取1、2、3、4时我们可以对比一下效果
优点
即适用于二分类又可用于多分类
可解释
缺点
其导数为a,所以反向传播时weights和biaises为常数

03

Sigmoid
sigmoid和relu,tanh并称为最常用的激活函数,sigmoid又被称为logistic function,是一种非线性函数。output分布在0~1之间
def sigmoid_active_function(x): return 1/(1+numpy.exp(-x))
x = numpy.linspace(-10, 10, 5000)y = [sigmoid_active_function(i) for i in x] y> [4.5397868702434395e-05, 4.5854103946941324e-05, ... , 0.9999532196250409, 0.9999536850759906, 0.9999541458960531]
缺点
  • 在接近1.0和-1.0附近时值会被稀释掉
  • 它将所有的值都限制在了0到1之间,这会导致梯度消失

04

Tanh
Tanh类似与sigmoid激活函数类似,它在0附近对称,output在0到1的范围内。sigmoid在0附近时很敏感,但是在值较大时就会被稀释掉
def tanh_active_function(x): return 2*sigmoid_active_function(2*x)-1
x = numpy.linspace(-10, 10, 5000)y = [tanh_active_function(i) for i in x] y> [-0.9999999958776927, -0.9999999957944167, ... , 0.9999999956227836, 0.9999999957094583, 0.9999999957944166]
优点
  • 值分布在-1,1之间
  • 梯度比sigmoid更大,导数能扑捉到的范围同样也变大
缺点
  • 同样会存在梯度消失的问题

05

ReLU
设计relu的初衷在于解决梯度消失的问题。非线性部分保留了学习数据内在模式(pattern)的能力,而线性部分则保留了模型的可解释性。
模型分两段,小于0的部分取0而大于0的部分则保持不变
def relu_activate_function(x): return numpy.array([0,x]).max()
x = numpy.linspace(-10, 10, 5000)y = [relu_active_function(i) for i in x] y> [0.0, 0.0, ... , 9.97, 9.98, 9.99]
优点
  • 容易实施且运行快
  • 最常用的神经网络生态
缺点
  • 当值小于0时neuron失效
  • 不适用于RNN、LSTM、GRU相关模型

06

Leaky ReLU
leaky relu是relu的变种,是为了解决dying问题,即在小于0时神经元失效的问题
def leaky_relu_acvtive_function(x): return 0.01* x if x<0 else x
x = numpy.linspace(-10, 10, 5000)y = [leaky_relu_active_function(i) for i in x] y> [-0.1, -0.0999, ... , 9.97, 9.98, 9.99]
优点
  • 解决了dying relu的问题

07

Parametric ReLU
Parametric ReLU在leaky relu上进行了进一步改造,核心还是为了解决dying relu的问题
def parametric_relu_active_function(x): return a*x if x < 0 else x
x = numpy.linspace(-10, 10, 5000)y_1 = [parametric_relu_active_function(0.25, i) for i in x] y_2 = [parametric_relu_active_function(0.5, i) for i in x]y_3 = [parametric_relu_active_function(0.75, i) for i in x]y_4 = [parametric_relu_active_function(1, i) for i in x]y_1> [-2.5, -2.4975, ... , 9.97, 9.98, 9.99]a = 0.25、0.5、0.75、1
当 a = 0 时parametric ReLU 相当于 ReLU activation.
当 a=0.01 时 parametric ReLU 相当于 Leaky ReLU.
优点
  • 生成ReLU激活函数
  • 避免了“dying ReLU”的问题
  • 参数a能够被神经元学习

08

Exponential Linear Unit (eLU)

Exponential Linear Unit (eLU)

eLU是另一种relu function,数据的负向部分通过指数参数进行学习
def elu_activate_functino(a,x): return a*(numpy.exp(x)-1) if x <0 else x
x = numpy.linspace(-10, 10, 5000)y_1 = [elu_active_function(0.1, i) for i in x] y_2 = [elu_active_function(1, i) for i in x]y_3 = [elu_active_function(2, i) for i in x]y_4 = [elu_active_function(5, i) for i in x]y_1> [-0.09999546000702375, -0.09999541437933579, ... , 9.97, 9.98, 9.99]a = 0.1, 1, 2, 4:
优点
  • ELU 能够缓慢减小直到 -α,而RELU很陡峭
  • 不同于 ReLU, ELU 能够产生负值
缺点
  • x大于0的部分范围为0到无限大

09

ReLU-6
relu-6通过手工限定大于0的部分来控制大于0的部分的值
def relu_6_active_function(x): return numpy.array([0,x]).max() if x<6 else 6
y = [relu_6_active_function(i) for i in x]

10

Softplus
softplus是sigmoid 和 tanh的结合体
def softplus_active_function(x): return math.log(1+numpy.exp(x))
y = [softplus_active_function(i) for i in x]

11

Softsign
softsign是tanh的变种,但在实际中不常使用
def softsign_active_function(x): return x / (1+abs(x))
y = [softsign_active_function(i) for i in x]

12

Softmax
softmax和其他的激活函数不同,它输出的是一个概率分布,加起来的总和为1
def softmax(x): return numpy.exp(x)/numpy.sum(numpy.exp(x))
x = [0.8, 1.2, 2.4, 4.6]y = softmax_active_function(x)y> [0.01917691, 0.02860859, 0.09498386, 0.85723064]numpy.sum(y)> 1.0

13

Swish
swish是由Google于2017年研发出的最新的激活函数
def swish_active_function(x): return x/(1+numpy.exp(-x))
x = numpy.linspace(-10, 10, 5000)y = [swish_active_function(i) for i in x]y> [-0.0004539786870243439, -0.0004967044303692657, ..., 9.699405586525717, 9.799456604457717, 9.89950329556963]

14

总结
以上基本上是所有激活函数的代码及总结,希望大家在理解内容的时候能对应着代码一起研究,深入理解各个激活函数的原理及适用场景

本文目的在于学术交流,并不代表本公众号赞同其观点或对其内容真实性负责,版权归原作者所有,如有侵权请告知删除。



“强基固本”历史文章




分享、点赞、在看,给个三连击呗!

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存