1.sigmoid

Sigmoid激活函数在我们的网络模型中比较常用,也常作为二分类任务的输出层,函数的输出范围为(0 ,1)

表达式:
sigmoid函数求导曲线_Swish

其导数:
sigmoid函数求导曲线_激活函数_02

sigmoid图像如下:

sigmoid函数求导曲线_Mish_03


优点:

平滑、易于求导

缺点:

  1. 会有梯度消失
  2. 函数不是关于原点对称
  3. 计算exp比较费时

2.tanh

tanh为双曲正切函数,函数输出范围为(-1, 1)。

表达式:
sigmoid函数求导曲线_Mish_04

其图像如下图所示,可以看做是sigmoid函数的向下平移和拉伸。

sigmoid函数求导曲线_激活函数_05

tanh激活函数的特点:

相比Sigmoid函数:

  1. tanh函数输出范围是(-1, 1),解决了Sigmoid函数不是关于0点中心对称的问题;
  2. exp计算量大的问题依然存在;
  3. 相比于Sigmoid,梯度消失的问题得到一定的缓解,但仍然存在。

3.ReLU

ReLU激活函数中文名叫修正线性单元函数。

公式:
sigmoid函数求导曲线_Sigmoid_06

函数曲线:

sigmoid函数求导曲线_Sigmoid_07

优点:

  1. 解决了梯度消失问题,收敛快于Sigmoid和tanh,但要防范ReLU的梯度爆炸;
  2. 相比Sigmoid和tanh,ReLU计算简单,提高了运算速度;
  3. 容易得到更好的模型。

缺点:
输入负数时,ReLU输出总是0,神经元不被激活。

ReLU函数的变型

sigmoid函数求导曲线_Sigmoid_08

  • Leaky ReLU
    函数中的a为常数,一般设置为0.01
  • PReLU
    函数中a作为一个可学习的参数,会在训练过程中更新

4.Swish, SiLU

Swish激活函数具备无上界有下届、平滑、非单调的特性,Swish在深层模型上效果优于ReLU。

表达式:
sigmoid函数求导曲线_Swish_09

β是个常数或者可训练的参数,当β=1时,我们也称作SiLU激活函数。

sigmoid函数求导曲线_Swish_10

5.hard-Swish

该激活函数在MobileNetV3论文中提出,相较于swish函数,具有数值稳定性好,计算速度快等优点。

sigmoid函数求导曲线_sigmoid函数求导曲线_11

class Hswish(nn.Module):
    def __init__(self, inplace=True):
        super(Hswish, self).__init__()
        self.inplace = inplace

    def forward(self, x):
        return x * F.relu6(x + 3., inplace=self.inplace) / 6.

6.Mish

表达式:

sigmoid函数求导曲线_激活函数_12

sigmoid函数求导曲线_Sigmoid_13

class Mish(nn.Module):
    def __init__(self):
        super(Mish, self).__init__()

    def forward(self, x):
        return x * torch.tanh(F.softplus(x))

7.GELU

GELU叫叫高斯误差线性单元,这种激活函数加入了随机正则的思想,是一种对神经元输入的概率描述。公式如下:

sigmoid函数求导曲线_Sigmoid_14
其中Φ(x)指的是正态分布的概率函数。
对于假设为标准正态分布的GELU(x),论文中提供了近似计算的数学公式,如下:

sigmoid函数求导曲线_Sigmoid_15

代码:

def gelu(x):
    """Implementation of the gelu activation function.
        For information: OpenAI GPT's gelu is slightly different (and gives slightly different results):
        0.5 * x * (1 + torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3))))
        Also see https://arxiv.org/abs/1606.08415
    """
    return x * 0.5 * (1.0 + torch.erf(x / math.sqrt(2.0)))