relu函数_总结|激活函数之sigmoid、ReLU、ELU 以及更新的 Leaky ReLU、SELU、GELU

选自mlfromscratch

作者:Casper Hansen

文章授权转载机器之心

参与:熊猫、杜伟

激活函数对神经网络的重要性自不必多言, 本文关注的是激活函数。 来自丹麦技术大学的 Casper Hansen 通过公式、图表和代码实验介绍了 sigmoid、ReLU、ELU 以及更新的 Leaky ReLU、SELU、GELU 这些激活函数,并比较了它们的优势和短板。

fee0efeb57c3fc7010bcd55185866197.gif

在计算每一层的激活值时,我们要用到激活函数,之后才能确定这些激活值究竟是多少。根据每一层前面的激活、权重和偏置,我们要为下一层的每个激活计算一个值。但在将该值发送给下一层之前,我们要使用一个激活函数对这个输出进行缩放。本文将介绍不同的激活函数。   在阅读本文之前,你可以阅读我前一篇介绍神经网络中前向传播和反向传播的文章,其中已经简单地提及过激活函数,但还未介绍其实际所做的事情。本文的内容将建立在你已了解前一篇文章知识的基础上。 前一篇文章地址:https://mlfromscratch.com/neural-networks-explained/ Casper Hansen 目录
  • 概述

  • sigmoid 函数是什么?

  • 梯度问题:反向传播

  • 梯度消失问题

  • 梯度爆炸问题

  • 梯度爆炸的极端案例

  • 避免梯度爆炸:梯度裁剪/范数

  • 整流线性单元(ReLU)

  • 死亡 ReLU:优势和缺点

  • 指数线性单元(ELU)

  • 渗漏型整流线性单元(Leaky ReLU)

  • 扩展型指数线性单元(SELU)

  • SELU:归一化的特例

  • 权重初始化+dropout 

  • 高斯误差线性单元(GELU)

  • 代码:深度神经网络的超参数搜索

  • 扩展阅读:书籍与论文

概述 激活函数是神经网络中一个至关重要的部分。在这篇长文中,我将全面介绍六种不同的激活函数,并阐述它们各自的优缺点。我会给出激活函数的方程和微分方程,还会给出它们的图示。本文的目标是以简单的术语解释这些方程以及图。   我会介绍梯度消失和爆炸问题;对于后者,我将按照 Nielsen 提出的那个很赞的示例来解释梯度爆炸的原因。   最后,我还会提供一些代码让你可以自己在 Jupyter Notebook 中运行。

771ea9436c65d5f99b3a90bcba7725d0.gif

我会在 MNIST 数据集上进行一些小型代码实验,为每个激活函数都获得一张损失和准确度图。

6e5f213f09087adfe558d4c5dd419d9e.png

sigmoid 函数是什么? sigmoid 函数是一个 logistic 函数,意思就是说:不管输入是什么,得到的输出都在 0 到 1 之间。也就是说,你输入的每个神经元、节点或激活都会被缩放为一个介于 0 到 1 之间的值。

e526ce221eb33b5a35af0d70da9a4703.png

0dbdd3a69221bc4fd2e12b869356d719.png

sigmoid 函数图示。 sigmoid 这样的函数常被称为非线性函数,因为我们不能用线性的项来描述它。很多激活函数都是非线性或者线性和非线性的组合(有可能函数的一部分是线性的,但这种情况很少见)。   这基本上没什么问题,但值恰好为 0 或 1 的时候除外(有时候确实会发生这种情况)。为什么这会有问题?   这个问题与反向传播有关(有关反向传播的介绍请参阅我的前一篇文章)。在反向传播中,我们要计算每个权重的梯度,即针对每个权重的小更新。这样做的目的是优化整个网络中激活值的输出,使其能在输出层得到更好的结果,进而实现对成本函数的优化。   在反向传播过程中,我们必须计算每个权重影响成本函数(cost function)的比例,具体做法是计算成本函数相对于每个权重的偏导数。假设我们不定义单个的权重,而是将最后一层 L 中的所有权重 w 定义为 w^L,则它们的导数为: 5e17affb6d9647cff377a31a229f009d.png 注意,当求偏导数时,我们要找到 ∂a^L 的方程,然后仅微分 ∂z^L,其余部分保持不变。我们用撇号「'」来表示任意函数的导数。当计算中间项 ∂a^L/∂z^L 的偏导数时,我们有: c3674cb42618c07fd82e9f3f0e87d952.png 则 sigmoid 函数的导数就为: ac2673be4d2dfc0d404594249ebd4250.png 当我们向这个 sigmoid 函数输入一个很大的 x 值(正或负)时,我们得到几乎为 0 的 y 值——也就是说,当我们输入 w×a+b 时,我们可能得到一个接近于 0 的值。

f37bb5caa9ecc3a5e2d656e0ee913504.png

sigmoid 函数的导数图示。   当 x 是一个很大的值(正或负)时,我们本质上就是用一个几乎为 0 的值来乘这个偏导数的其余部分。 6fde679de85896f920f2f6722f97eea8.png 如果有太多的权重都有这样很大的值,那么我们根本就没法得到可以调整权重的网络,这可是个大问题。如果我们不调整这些权重,那么网络就只有细微的更新,这样算法就不能随时间给网络带来多少改善。对于针对一个权重的偏导数的每个计算,我们都将其放入一个梯度向量中,而且我们将使用这个梯度向量来更新神经网络。可以想象,如果该梯度向量的所有值都接近 0,那么我们根本就无法真正更新任何东西。 8e3f805430c0fc0742c01e1e77adb8d8.png 这里描述的就是梯度消失问题。这个问题使得 sigmoid 函数在神经网络中并不实用,我们应该使用后面介绍的其它激活函数。 梯度问题 梯度消失问题 我的前一篇文章说过,如果我们想更新特定的权重,则更新规则为: f6a0ca10558f503ca0e51390a01d0831.png 但如果偏导数 ∂C/∂w^(L) 很小,如同消失了一般,又该如何呢?这时我们就遇到了梯度消失问题,其中许多权重和偏置只能收到非常小的更新。

7fa4f1ec7abd1853cec4c9b1f6752d2f.png

可以看到,如果权重的值为 0.2,则当出现梯度消失问题时,这个值基本不会变化。因为这个权重分别连接了第一层和第二层的首个神经元,所以我们可以用 0072169716065abdbb00cfd77aa1be45.png的表示方式将其记为 5faac6469043acc182705052c0ec6c3f.png

c5c481eba729e1dd21a3a9e5fc0058e6.png

假设这个权重的值为 0.2,给定一个学习率(具体多少不重要,这里使用了 0.5),则新的权重为:

96110ea7871e6554b1e3b0f81a615b8c.png

这个权重原来的值为 0.2,现在更新为了 0.199999978。很明显,这是有问题的:梯度很小,如同消失了一样,使得神经网络中的权重几乎没有更新。这会导致网络中的节点离其最优值相去甚远。这个问题会严重妨碍神经网络的学习。   人们已经观察到,如果不同层的学习速度不同,那么这个问题还会变得更加严重。层以不同的速度学习,前面几层总是会根据学习率而变得更差。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值