一文带你梳理常见的激活函数

本文详细介绍了激活函数的作用及其种类,包括Sigmoid、ReLU、Tanh等,并对比了它们的优缺点。此外,还介绍了几种较为先进的激活函数,如Mish、ELU、Swish等。

1. 为什么要有激活函数

若网络中不用激活函数,那么每一层的输出都是输入的线性组合。无论神经网络有多少层,网络的输出都是输入的线性组合,这种网络就是原始的感知机(PerceptronPerceptronPerceptron)。若网络没有激活函数,则每层就相当于矩阵相乘,深层神经网络,无非是多矩阵相乘。

激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。网络使用非线性激活函数后,可以增加神经网络模型的非线性因素,网络可以更加强大,表示输入输出之间非线性的复杂的任意函数映射。

网络的输出层可能会使用线性激活函数,但隐含层一般都是使用非线性激活函数。

2. 非零均值的问题(non-zero-centered)

部分激活函数是非零均值的,如ReLUReLUReLU, SigmoidSigmoidSigmoid等激活函数,他会造成网络收敛很慢。我们可以简单看下表示式:f=(wixi+b)f=(w_{i} x_{i}+b)f=(wixi+b),其中xix_{i}xisigmoidsigmoidsigmoid函数的输出。那么,在计算损失函数后,需要进行反向传播更新该权重wiw_{i}wi。这时候,对wiw_{i}wi进行求导,是直接与xix_{i}xi相关的,而因为xix_{i}xi是大于000的值,所以这时候的梯度方向就会完全取决于dLdf\frac{dL}{df}dfdL。这时候若dLdf\frac{dL}{df}dfdL恒正或者恒为负,那么就会出现zig−zaggingzig-zaggingzigzagging dynamicsdynamicsdynamics的问题,使得网络收敛变慢。

其中zig−zaggingzig-zaggingzigzagging 的图像就如下面图像:

下面开始我们介绍下常用的激活函数,其中对于部分激活函数,画图都是采用PytorchFunctional的默认参数来进行绘制的。

1. Sigmoid激活函数

sigmoid函数公式如下:

f(z)=11+exp⁡(−z)f(z)=\frac{1}{1+\exp (-z)} f(z)=1+exp(z)1

SigmoidSigmoidSigmoid函数也叫LogisticLogisticLogistic函数,用于用于隐层神经元输出,取值范围为(0,1)(0,1)(0,1),它可以将一个实数映射到(0,1)(0,1)(0,1) 的区间,可以用来做二分类或者生成AttentionAttentionAttention $ Mask$。在特征相差比较复杂或是相差不是特别大时效果比较好。

sigmoidsigmoidsigmoid 激活函数的缺点有:

  • 激活函数计算量大,反向传播求误差梯度时,求导涉及除法;
  • 反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练;
  • SigmoidSigmoidSigmoid 是非零均值的函数,收敛缓慢。
  • SigmoidSigmoidSigmoid函数运算量大。如我们用FLOPsFLOPsFLOPs(每秒浮点操作次数)来衡量模型的计算量指标。则ReLUReLUReLU运算量是1 FLOPsFLOPsFLOPs。那么Sigmoid包括了减、取幂、加、除共4 FLOPsFLOPsFLOPs.

sigmoidsigmoidsigmoid 激活函数出现梯度消失的原因如下:

反向传播算法中,要对激活函数求导,sigmoidsigmoidsigmoid 的导数表达式为:
ϕ′(x)=ϕ(x)(1−ϕ(x)) \phi^{\prime}(x)=\phi(x)(1-\phi(x)) ϕ(x)=ϕ(x)(1ϕ(x))
sigmoidsigmoidsigmoid 激活函数原函数及导数图形如下:由图可知,导数从0 开始很快就又趋近于0 了,易造成“梯度消失”现象。

2. TanH激活函数

TanHTanHTanH 激活函数的公式如下,也称为双切正切函数,取值范围为[-1,1]。
tanh⁡(x)=2sigmoid⁡(2x)−1f(z)=tanh⁡(z)=ez−e−zez+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+ezezez
TanhTanhTanh函数的反传公式为:
g′(z)=(ez−e−zez+e−z)′=4(ez+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+ezezez)=(ez+ez)24=1g(z)2
TanHTanHTanH函数的缺点sigmoidsigmoidsigmoid函数的缺点类似。当 z 很大或很小时,𝑔′(𝑧) 接近于 0 ,会导致梯度很小,权重更新非常缓慢,即梯度消失问题。从下面的图像也能看出来,靠近图像两端越平缓,梯度越小。

TanHTanHTanH 激活函数函数图像如图所示。

TanhTanhTanh 在特征相差明显时的效果会相对更好,在循环过程中会不断扩大特征效果。与sigmoidsigmoidsigmoid 的区别是,tanhtanhtanh000 均值的,因此实际应用中tanhtanhtanh 会比sigmoidsigmoidsigmoid 更好,不过需要具体尝试。

3. ReLU激活函数

ReLUReLUReLU (Rectified Liner Unit)激活函数主要用于隐层神经元输出,公式为f(x)=max(0,x)f(x)=max(0,x)f(x)=max(0,x),函数图像与其求导的导数图像如图所示:

  • ReLUReLUReLU 激活函数的特点是:输入信号小于时,输出都是0,输入信号大于0时,输出等于输入。

  • ReLUReLUReLU 的优点是使用ReLUReLUReLU 得到的SGDSGDSGD 的收敛速度会比使用sigmoid/tanhsigmoid/tanhsigmoid/tanhSGDSGDSGD 快很多。

  • ReLUReLUReLU 的缺点是神经网络训练的时候很“脆弱”,很容易就会出现神经元死亡。

    例如,一个非常大的梯度流过一个ReLUReLUReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了,那么这个神经元的梯度就永远都会是000。(Dead ReLU Problem)。

  • 非零均值,所以一般ReLUReLUReLU后会加BNBNBN

4. Softmax 激活函数

多用于多分类神经网络输出,公式为:

主要用于分类最后归一化到[0,1][0,1][0,1]j∈[1,K]j \in [1, K]j[1,K]。当然也与SigmoidSigmoidSigmoid一样,可以用在attention之中,学习到权重的矩阵。

5. Softplus激活函数

公式如下:
y=log⁡(1+ex) y=\log \left(1+e^{x}\right) y=log(1+ex)
ReLUReLUReLUSoftplusSoftplusSoftplus放在一起对比的话,则如图像所示:

可以看到,softplussoftplussoftplus可以看作是ReLUReLUReLU的平滑。其中,加了111是为了保证非负性。SoftplusSoftplusSoftplus可以看作是强制非负校正函数max(0,x)max(0,x)max(0,x)平滑版本。

6. Mish激活函数

MishMishMish函数的公式如下:
 Mish =x∗tanh⁡(ln⁡(1+ex)) \text { Mish }=x * \tanh \left(\ln \left(1+e^{x}\right)\right)  Mish =xtanh(ln(1+ex))
PytorchPytorchPytorchMishMishMish激活函数代码如下:

x = x * (torch.tanh(F.softplus(x)))

函数图像如图所示:

MishMishMish函数,以上无边界(即正值可以达到任何高度)避免了由于封顶而导致的饱和。理论上对负值的轻微允许允许更好的梯度流,而不是像ReLUReLUReLU中那样的硬零边界。

最后,可能也是最重要的,平滑的激活函数允许更好的信息深入神经网络,从而得到更好的准确性和泛化。

不过我 之前亲自训过MishMishMish这个激活函数,PytorchPytorchPytorch版本的MishMishMish很占显存。

7. Leaky ReLU与PReLU

LeakyLeakyLeaky ReLUReLUReLU的公式如下:

aia_{i}ai是一个(1,+∞)(1,+\infty)(1,+)区间内的固定参数。与 ReLUReLUReLU 相比 ,leakyleakyleaky ReLUReLUReLU 给所有负值赋予一个非零斜率aia_{i}ai。这样保留了一些负轴的值,使得负轴的信息不会全部丢失。

PReLUPReLUPReLU可以看作是LeakyLeakyLeaky ReLUReLUReLU的一个变体。在PReLUPReLUPReLU中,负值部分的斜率aia_{i}ai是根据网络学习来定的,而非预先定义的。作者称,在ImageNetImageNetImageNet分类(2015,Russakovsky等)上,PReLUPReLUPReLU是超越人类分类水平的关键所在。

LeakyLeakyLeaky ReLUReLUReLUPReLUPReLUPReLU主要的特点是:(1)计算简单,有效 (2)比SigmoidSigmoidSigmoidTanhTanhTanh收敛更快 (3) 解决了DeadDeadDead ReLUReLUReLU的问题。

8. RReLU激活函数

RReLURReLURReLU(Randomized leaky rectified linear unit)也是LeakyLeakyLeaky ReLUReLUReLU的一个变体。在RReLURReLURReLU中,ajia_{ji}aji是一个在一个给定的范围内随机抽取的值,这个值在测试环节就会固定下来

RReLURReLURReLU的亮点在于,在训练环节中,ajia_{ji}aji是从一个均匀的分布U(I,u)U(I,u)U(I,u)中随机抽取的数值。形式上来说,我们能得到以下结果:

where
aji∼U(l,u),l<u,u∈[0,1) a_{j i} \sim U(l, u), l < u, u \in [0, 1) ajiU(l,u),l<u,u[0,1)
该函数的图像如下图所示:

9. ELU激活函数

ELUELUELU同样是针对ReLUReLUReLU的负数部分进行的改进,ELUELUELU激活函数对xxx小于零的情况采用类似指数计算的方式进行输出:
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))

或者表达为:

对于ELUELUELU有这些特点:

  • ELUELUELU由于其正值特性,可以像ReLUReLUReLU,LeakyLeakyLeaky ReLUReLUReLU, PReLUPReLUPReLU一样缓解梯度消失的问题。
  • 相比ReLUReLUReLUELUELUELU存在负值,可以将激活单元的输出均值往000推近,达到接近BNBNBN的效果同时减少了计算量。

10. Swish激活函数

激活函数的公式如下:
f(x)=x⋅sigmoid⁡(βx) f(x)=x \cdot \operatorname{sigmoid}(\beta x) f(x)=xsigmoid(βx)
其函数图像如下:

其中,β\betaβ是常数或可训练的参数。SwishSwishSwish函数具备无上界有下界、平滑、非单调的特性。通过实验证明,对于深层模型, SwishSwishSwish的效果是优于ReLUReLUReLU的。

β=0\beta=0β=0时,SwishSwishSwish激活函数成为线性函数f(x)=x2f(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)=2max⁡(0,x)f(x)=2 \max (0, x)f(x)=2max(0,x)
SwishSwishSwish函数可以看做是介于线性函数与ReLUReLUReLU函数之间的平滑函数.

11. SELU激活函数

SELUSELUSELU是给ELUELUELU乘上系数 β\betaβ, 即$ SELU(x)=𝜆⋅ELU(x)$。

文章中主要证明是当取得λ≈1.0507,α≈1.6733\lambda \approx 1.0507, \alpha \approx 1.6733λ1.0507,α1.6733时,在网络权重服从标准正态分布的条件下,各层输出的分布会向标准正态分布靠拢,这种"自我标准化"的特性可以避免梯度消失于梯度爆炸,证明过程各位感兴趣的可以去看看90多页的原文

函数图像如图所示:

12. GELU激活函数

受启发于DropoutDropoutDropoutReLUReLUReLU等机制的影响,都意在将不重要的信息设置为0。对于输入的值,我们可以理解成是将输入的值乘以了一个0或者1。即对于每一个输入xxx,其服从于标准正态分布N(0,1)N(0,1)N(0,1),它也会乘以一个伯努利分布Bernoulli(ϕ(x))Bernoulli(\phi(x))Bernoulli(ϕ(x)),其中ϕ(x)=P(x≤x)\phi(x)=P(x \leq x)ϕ(x)=P(xx)

GELUGELUGELU(Gaussian error linear units)的表达式为GELU⁡(x)=xP(X≤x)=xΦ(x)\operatorname{GELU}(x)=x P(X \leq x)=x \Phi(x)GELU(x)=xP(Xx)=xΦ(x)

而上式函数是无法直接计算的,因此可以使用另外的方式来进行逼近,论文得到的表达式为:0.5x(1+tanh⁡[2/π(x+0.044715x3)])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)])。或者为GELU(x)=x1+e−1.702xGELU(x)=\frac{x}{1+e^{-1.702 x}}GELU(x)=1+e1.702xx

bertbertbert, TransformerTransformerTransformer中使用的激活函数,作者经过实验证明比relurelurelu等要好。原点可导,不会有DeadDeadDead ReLUReLUReLU问题。

其函数图像如图所示:

大家好,我是灿视。目前是位算法工程师 + 创业者 + 奶爸的时间管理者!

我曾在19,20年联合了各大厂面试官,连续推出两版《百面计算机视觉》,受到了广泛好评,帮助了数百位同学们斩获了BAT等大小厂算法Offer。现在,我们继续出发,持续更新最强算法面经。
我曾经花了4个月,跨专业从双非上岸华五软工硕士,也从不会编程到进入到百度与腾讯实习。
欢迎加我私信,点赞朋友圈,参加朋友圈抽奖活动。如果你想加入<百面计算机视觉交流群>,也可以私我。在这里插入图片描述

### 红黑树概念 红黑树是一种特殊的二叉搜索树,具有特定的颜色属性来保持树的近似平衡状态。这种特性使得红黑树能够在插入、删除和查找操作上提供较好的时间复杂度[^1]。 #### 性质描述 每棵红黑树都遵循以下五条基本性质: - 每个节点要么是红色,要么是黑色。 - 根节点总是黑色。 - 所有叶子(NIL节点)都是黑色。(注意这里的叶子指的是外部节点) - 如果一个内部节点是红色,则它的两个孩子节点必须是黑色。(即不存在连续两条红线相连的情况) - 对于任意给定的非叶节点,在该节点到其可达叶子的所有路径上的黑色节点数目相同。 这些规则确保了从根到最近叶子的最大距离不会超过最小距离的一倍以上,从而维持了一种较为均衡的状态[^3]。 ### 插入机制解析 当向红黑树中添加新的键值时,默认情况下新加入的节点会被标记成红色以减少违反上述条件的可能性。然而即便如此仍可能出现冲突情况——比如父级也为红色就违背了第四条原则;这时就需要通过一系列调整动作使整棵树恢复合法形态,主要包括颜色翻转以及左旋/右旋两种方式[^2]。 ```c // 定义RBTree结构体表示整个红黑树, Node代表单个节点. typedef struct RBTreeNode { int key; char color; // 'R' or 'B' struct RBTreeNode *left,*right,*parent; }Node; void insertFixup(Node* root, Node* z){ while (z != root && z->parent->color == RED) { ... } } ``` 此段伪代码展示了如何处理因插入而导致的不平衡状况的一部分逻辑流程,具体细节取决于实际应用场景下的需求设计。 ### 删除算法概览 移除某个指定元素的过程相对更为复杂一些,除了要考虑常规BST中的前驱后继关系外还需特别关注被删去位置处所遗留下来的空缺是否会引起连锁反应进而影响全局稳定性。为此通常采用替换法先找到合适替代品再做进一步修正工作直至完全消除负面影响为止。 ```c Node* treeMinimum(Node* node){ while(node->left!=NULL)node=node->left; return node; } void deleteFixup(RBTree T, Node x){...} ``` 这里给出了一些辅助函数用于支持完整的删除功能实现,其中`treeMinimum()`用来获取某子树中最左侧的那个节点作为候选接替者之一,“deleteFixup()”则负责后续必要的结构调整任务以确保存储结构依然符合预期标准。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值