PyTorch教程(八):常见激活函数与Loss的梯度

如果不用激活函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合,这种情况就是最原始的感知机。

如果使用的话,激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。
在这里插入图片描述
上图就是一个最简单的激活函数,当 ∑ i = 0 N > 0 \sum_{i=0}^N>0 i=0N>0时节点才会激活。
但是这个激活函数有一个问题是不可导,在 ∑ i = 0 N = 0 \sum_{i=0}^N=0 i=0N=0处是处于不连续的情况下,因此不可以求导,因此这个函数无法直接使用梯度下降的方式来优化,当时使用了启发式搜索的方式来求解单层感知机最优解的情况。

为了解决单层激活函数阶梯不可导的情况,科学家提出了sigmoid函数(Logistic函数):
f ( x ) = σ ( x ) = 1 1 + e − x f(x) =\sigma(x)= \frac{1}{1+e^{-x}} f(x)=σ(x)=1+ex1
在这里插入图片描述
x → ∞ x \to \infty x时, f ( x ) → 1 f(x) \to 1 f(x)1,当 x → − ∞ x \to -\infty x时, f ( x ) → 0 f(x) \to 0 f(x)0。而且可以看出倒数是连续可导的。
在这里插入图片描述
实际上sigmoid激活函数使用的非常多,最主要的是因为它连续光滑,而且值压缩在(0,1)的范围内,我们很多时候都需要(0,1)这样一个范围,比如概率和RGB。

但是sigmoid存在一个致命的权限,当 f ( x ) → ∞ f(x) \to \infty f(x) f ( x ) → − ∞ f(x) \to -\infty f(x)时,导数都为0,因此当值处在这部分区间时,参数 θ ′ = θ − ∇ = θ − 0 = θ \theta'=\theta-\nabla=\theta-0=\theta θ=θ=θ0=θ长时间得不到更新,出现梯度离线现象。

sigmoid在PyTorch实现

import torch

z = torch.linspace(-100,100,10)
# tensor([-100.0000,  -77.7778,  -55.5556,  -33.3333,  -11.1111,   11.1111,
#          33.3333,   55.5556,   77.7778,  100.0000])

torch.sigmoid(z)
# tensor([0.0000e+00, 1.6655e-34, 7.4564e-25, 3.3382e-15, 1.4945e-05, 9.9999e-01,
#        1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00])

或者使用from torch.nn import functional as F的方式:

from torch.nn import functional as F

F.sigmoid(z)
# tensor([0.0000e+00, 1.6655e-34, 7.4564e-25, 3.3382e-15, 1.4945e-05, 9.9999e-01,
#        1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00])

可以看出当 z = − 100 z=-100 z=100的时候,sigmoid的值已经是非常小的了,接近于0了;当 z = 100 z=100 z=100的时候,sigmoid的值也接近于0了

Tanh激活函数

Tanh激活函数在RNN中用的比较多。
f ( x ) = t a n h ( x ) = e x − e − x ( e x + e − x ) = 2 s i g m o i d ( 2 x ) − 1 f(x) = tanh(x)=\frac{e^x-e^{-x}}{(e^x+e^{-x})}=2sigmoid(2x)-1 f(x)=tanh(x)=(ex+ex)exex=2sigmoid(2x)1
在这里插入图片描述
所以Tanh的取值范围是(-1,1)。
在这里插入图片描述

z = torch.linspace(-1,1,10)
torch.tanh(z)
#tensor([-0.7616, -0.6514, -0.5047, -0.3215, -0.1107,  0.1107,  0.3215,  0.5047,
#         0.6514,  0.7616])

Rectified Linear Unit (ReLU)激活函数

非常简单,但是可以说是现在深度学习的奠基石的激活函数。现在深度学习使用最多的激活函数就是ReLU激活函数。

f ( x ) = { 0 for x<0 x , x ≥ 0 f(x)=\begin{cases} 0 & \text {for x<0} \\ x, & \text{x}\geq 0 \end{cases} f(x)={0x,for x<0x0
在这里插入图片描述
ReLU函数的导数:
f ′ ( x ) = { 0 for x<0 1 , x ≥ 0 f'(x)=\begin{cases} 0 & \text {for x<0} \\ 1, & \text{x}\geq 0 \end{cases} f(x)={01,for x<0x0
因为当 x ≥ 0 x\ge0 x0时,梯度是1,因此在向后传播时,梯度计算起来非常方便,不会放大也不会缩小,不会出现梯度离散和梯度爆炸的情况。

z = torch.linspace(-1,1,10)
torch.relu(z)
# tensor([  0.0000,   0.0000,   0.0000,   0.0000,   0.0000,  11.1111,  33.3333,
#         55.5556,  77.7778, 100.0000])
F.relu(z)
# tensor([0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.1111, 0.3333, 0.5556, 0.7778,
#        1.0000])

一般在做research的时候,通常都是用ReLU激活函数。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值