ReLU(Linear rectification function,修正线性单元)在图像处理任务中使用最广泛的激活函数,它虽然具有一定的优势,但是也存在一些不足,由此出现了一些变种函数,例如:SoftPlus、LeakyReLU、ELU、ReLU6.
1. ReLU 激活函数
ReLU 激活函数公式如下:
函数图像如下:
从上述函数图像可知,ReLU 激活函数将小于 0 的值映射为 0,而大于 0 的值则保持不变,它更加重视正信号,而忽略负信号,这种激活函数运算更为简单,能够提高模型的训练效率。
但是,如果我们网络的参数采用随机初始化时,很多参数可能为负数,这就使得输入的正值会被舍去,而输入的负值则会保留,这可能在大部分的情况下并不是我们想要的结果。
导数图像如下:
从上述的函数图像可以看到,当输入大于 0 时,ReLU 激活函数的导数恒等于 1,这一点相对于导数值范围 (0, 0.25) 的 sigmoid 函数一定程度上缓解了梯度消失的问题。
上述图像生成代码:
import torch import matplotlib.pyplot as plt import torch.nn.functional as F def test(): _, axes = plt.subplots(1, 2) # 函数图像 x = torch.linspace(-20, 20, 1000) y = F.relu(x) axes[0].plot(x, y) axes[0].grid() axes[0].set_title('ReLU 函数图像') # 导数图像 x = torch.linspace(-20, 20, 1000, requires_grad=True) F.relu(x).sum().backward() axes[1].plot(x.detach(), x.grad) axes[1].grid() axes[1].set_title('ReLU 导数图像') plt.show() if __name__ == '__main__': test()
2. SoftPlus 激活函数
SoftPlus 函数公式如下:
下面的函数图像 β=1 时的函数图像、导数图像:
下面的函数图像 β=0.1 时的函数图像、导数图像:
从上述图像,我们可以看到 SoftPlus 激活函数可以将输入的负值映射为较小的正值,参数 β 会影响到函数图像。
上述图像的生成代码如下:
import torch import matplotlib.pyplot as plt import torch.nn.functional as F def test(): _, axes = plt.subplots(1, 2) beta = 1 # 函数图像 x = torch.linspace(-20, 20, 1000) y = F.softplus(x, beta=beta) axes[0].plot(x, y) axes[0].grid() axes[0].set_title('SoftPlus 函数图像') # 导数图像 x = torch.linspace(-20, 20, 1000, requires_grad=True) F.softplus(x, beta=beta).sum().backward() axes[1].plot(x.detach(), x.grad) axes[1].grid() axes[1].set_title('SoftPlus 导数图像') plt.show() if __name__ == '__main__': test()
3. LeakyReLU 激活函数
LeakyReLU 激活函数的公式如下:
negative_slope 为 LeakyReLU 激活函数的参数,下图为 negative_slope=0.01 时函数图像、导数图像:
下图为 negative_slope=1 时函数图像、导数图像:
4. ELU 激活函数
ELU 激活函数公式如下:
α 为 ELU 激活函数的参数,当 α = 1 和 α = 10 时的函数图像、导数图像如下:
ELU 激活函数比 ReLU 函数收敛更快。在使用 ELU 激活函数时,不适用批处理比使用批处理可以获得更好的效果。