一、激活函数的作用
激活函数的作用是:引入非线性因素,提高了模型的表达能力。
如果没有激活函数,那么模型就只有线性变换,可想而知线性模型能表达的空间是有限的。而激活函数引入了非线性因素,比线性模型拥有更大的模型空间。
二、激活函数详解
激活函数 | 公式 | 图形 | 适用范围 |
---|---|---|---|
tanh |
导数
|
| tanh激活函数是0均值的,tanh激活函数相比sigmoid函数更'陡峭'了,对于有差异的特征区分得更开了,tanh也不能避免梯度消失问题。 |
softmax |
| softmax函数常用在分类网络的最后一层,把网络输出转化为各类别的概率。 | |
sigmoid |
| ![]() | 优点:sigmoid函数可以将实数映射到 (0,1) 区间内。平滑、易于求导。 缺点:1. 激活函数含有幂运算和除法,计算量大;2. 反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练;3. sigmoid的输出不是0均值的,这会导致后一层的神经元将得到上一层输出的非0均值的信号作为输入。 |
ReLU | ![]() | ![]() | 优点:1.计算量小;2.激活函数导数维持在1,可以有效缓解梯度消失和梯度爆炸问题;3.使用Relu会使部分神经元为0,这样就造成了网络的稀疏性,并且减少了参数之间的相互依赖关系,缓解了过拟合问题的发生。 缺点:输入激活函数值为负数的时候,会使得输出为0,那么这个神经元在后面的训练迭代的梯度就永远是0了(由反向传播公式推导可得),参数w得不到更新,也就是这个神经元死掉了。这种情况在你将学习率设得较大时(网络训练刚开始时)很容易发生(波浪线一不小心就拐到负数区域了,然后就拐不回来了)。 解决办法:一些对Relu的改进,如ELU、PRelu、Leaky ReLU等,给负数区域一个很小的输出,不让其置0,从某种程度上避免了使部分神经元死掉的问题。 |
LeakyReLU | ![]() | ![]() | LeakyReLU在神经元未激活时,它仍允许赋予一个很小的梯度,避免ReLU死掉的问题。值得注意的是LeakyReLU是确定的标量,不可学习。 注意区分PReLU和LeakyReLU,PReLU的 alpha 是一个可学习的数组,尺寸与 x 相同。 PReLU是针对ReLU的一个改进型,在负数区域内,PReLU有一个很小的斜率,这样也可以避免ReLU死掉的问题。相比于ELU,PReLU在负数区域内是线性运算,斜率虽然小,但是不会趋于0,这算是一定的优势 |
hard_sigmoid | ![]() | ![]() | 特点:计算量小,非平滑。 |
ELU | ![]() | ![]() | 优点:右侧线性部分使得elu能够缓解梯度消失,而左侧软饱部分能够让ELU对输入变化或噪声更鲁棒。elu的输出均值接近于零。 |
GELU | GELU(x)=x∗Φ(x) | | 就是我们常说的高斯误差线性单元,它是一种高性能的神经网络激活函数,因为gelu的非线性变化是一种符合预期的随机正则变换方式 |
Maxout |
三、激活函数常见问题
1 transformer FFN层用的激活函数是什么?为什么?
ReLU.
2 出现死神经元的原因及解决方案:
-
初始化参数的问题。 --> 采用Xavier初始化方法。
-
learning rate太高导致在训练过程中参数更新太大 。==>避免将learning rate设置太大,或者使用Adam等自动调节learning rate的方法。
-
更换激活函数。 --> Leaky ReLU、PReLU、ELU等都是为了解决死神经元的问题。
3 Bert、GPT、GPT2中用的激活函数是什么?为什么?
Gelu.
使用Gelu时,一般优化器都会选择动态更新lr的方法。Bert、GPT、GPT2、RoBERTa、ALBERT都是用的Gelu。
直观理解:x做为神经元的输入,P(X<=x)越大,x就越有可能被保留;否则越小,激活函数输出就趋近于0.
参考文献:
1 算法面试问题二(激活函数相关)【这些面试题你都会吗】 - 知乎