1、激活函数的作用

激活函数是连接感知机和神经网络的桥梁,在神经网络中起着至关重要的作用。

如果没有激活函数,整个神经网络就等效于单层线性变换,不论如何加深层数,总是存在与之等效的“无隐藏层的神经网络”。激活函数必须是非线性函数,也正是激活函数的存在为神经网络引入了非线性,使得神经网络能够学习和表示复杂的非线性关系。

2、阶跃(Binary step)函数

它是最简单的激活函数,它可以为输入设置一个“阈值”;一旦超过这个阈值,就切换输出(0或者1)。这种函数被称为“阶跃函数”。
在这里插入图片描述
阶跃函数的导数恒为0。

阶跃函数可以用代码实现如下:

def step_function(x):
    if x > 0:
        return 1
    else:
        return 0

这里的x只能取一个数值(浮点数)。如果我们希望直接传入Numpy数组进行批量化的操作,可以改进如下:

def step_function(x):
    return np.array(x > 0, dtype=int)

3、Sigmoid函数

Sigmoid(也叫Logistic函数)是平滑的、可微的,能将任意输入映射到区间(0,1)。常用于二分类的输出层。但因其涉及指数运算,计算量相对较高。
在这里插入图片描述

  • Sigmoid的输入在[-6,6]之外时,其输出值变化很小,可能导致信息丢失。
  • Sigmoid的输出并非以0为中心,其输出值均>0,导致后续层的输入始终为正,可能影响后续梯度更新方向。
  • Sigmoid的导数范围为(0,0.25),梯度较小。当输入在[-6,6]之外时,导数接近0,此时网络参数的更新将会极其缓慢。使用Sigmoid作为激活函数,可能出现梯度消失(在逐层反向传播时,梯度会呈指数级衰减)。
    Sigmoid函数可以用代码实现如下:
def sigmoid(x):
    return 1 / (1 + np.exp(-x))  

4、Tanh函数

在这里插入图片描述
在这里插入图片描述

  • Tanh(双曲正切)将输入映射到区间(-1,1)。其关于原点中心对称。常用在隐藏层。
  • 输入在[-3,3]之外时,Tanh的输出值变化很小,此时其导数接近0。
  • Tanh的输出以0为中心,且其梯度相较于Sigmoid更大,收敛速度相对更快。但同样也存在梯度消失现象。

5、ReLU函数

在这里插入图片描述
在这里插入图片描述

  • 注意:x=0时ReLU函数不可导,此时我们默认使用左侧的函数。
  • ReLU(Rectified Linear Unit,修正线性单元)会将小于0的输入转换为0,大于等于0的输入则保持不变。ReLU定义简单,计算量小。常用于隐藏层。
  • ReLU作为激活函数不存在梯度消失。当输入小于0时,ReLU的输出为0,这意味着在神经网络中,ReLU激活的节点只有部分是“活跃”的,这种稀疏性有助于减少计算量和提高模型的效率。
  • 当神经元的输入持续为负数时,ReLU的输出始终为0。这意味着神经元可能永远不会被激活,从而导致“神经元死亡”问题。这会影响模型的学习能力,特别是如果大量的神经元都变成了“死神经元”。为解决此问题,可使用Leaky ReLU来代替ReLU作为激活函数。Leaky ReLU在负数区域引入一个小的斜率来解决“神经元死亡”问题。

ReLU函数可以用代码实现如下:

def relu(x):
    return np.maximum(0, x)

6、Softmax函数

在这里插入图片描述

  • Softmax将一个任意的实数向量转换为一个概率分布,确保输出值的总和为1,是二分类激活函数Sigmoid在多分类上的推广。Softmax常用于多分类问题的输出层,用来表示类别的预测概率。
  • Softmax会放大输入中较大的值,使得最大输入值对应的输出概率较大,其他较小的值会被压缩。即在类别之间起到了一定的区分作用。
    在这里插入图片描述
    Softmax函数可以用代码实现如下:
def softmax(x):
    return np.exp(x) / np.sum(np.exp(x))

考虑到x较大时,指数函数的值会非常大,容易溢出,可以改进为:

def softmax(x):
    x = x - np.max(x) # 溢出对策
    return np.exp(x) / np.sum(np.exp(x))

考虑到x为二维数组(矩阵)的情况,可以进一步写为:

def softmax(x):
    if x.ndim == 2:
        x = x.T
        x = x - np.max(x, axis=0)
        y = np.exp(x) / np.sum(np.exp(x), axis=0)
        return y.T 

    x = x - np.max(x) # 溢出对策
    return np.exp(x) / np.sum(np.exp(x))

7、其他常见激活函数

7.1 Identity(恒等函数)

在这里插入图片描述

7.2 Leaky ReLU(Leaky Rectified Linear Unit)

在这里插入图片描述

7.3 PReLU(Parametric Rectified Linear Unit)

在这里插入图片描述

7.4 RReLU(Randomized Leaky ReLU)

在这里插入图片描述

7.5 ELU(Exponential Linear Unit)

在这里插入图片描述
在这里插入图片描述

7.6 Swish(也称Sigmoid Linear Unit,SiLU)

在这里插入图片描述

7.7 Softplus

在这里插入图片描述

8、如何选择激活函数

8.1 隐藏层

  • 首选ReLU,如果效果不好可尝试Leaky ReLU等。
  • Sigmoid在隐藏层易导致梯度消失,应尽量避免。
  • Tanh的输出均值为0,对中心化数据更友好,但仍可能引发梯度消失,仅适用于浅层网络。

8.2 输出层

  • 二分类选择Sigmoid。
  • 多分类选择Softmax。
  • 回归默认选择Identity。
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐