首页 模式识别(经典神经网络)
文章
取消

模式识别(经典神经网络)

本文介绍了经典的人工神经网络,以及基于神经网络的分类器。人工神经网络(Artificial Neural Network,ANN)是模拟生物神经网络系统的一种计算模型,由大量计算节点(神经元)层层连接构成。通过改变神经元间的连接权重,ANN 可以对大量数据中的复杂映射关系进行建模。对于给定的任务,通过迭代训练进行计算节点权重参数更新,ANN 最终能够实现任务目标。


1. 神经元

1.1. 人工神经元

神经元是神经系统的基本组成单位,一个神经元就是一个神经细胞。人类大脑包含大约 1000 亿个神经元,这些神经元相互联系在一起,组成一个复杂的网络。一个生物神经元如下图所示:

neuron

对于信息传递而言,涉及到的生物神经元组成包括:

  • 树突:树突是细胞体外的微小分支,用于接收来自其他神经元的信号,这些信号就是神经元的输入;
  • 轴突:轴突是充当传输线的纤维,它将信号从细胞体传递到其他神经元,这些信号就是神经元的输出;
  • 突触:突触是一个神经元与另一个神经元相联系的特殊部位,通常是一个神经元轴突的端部靠化学接触或电接触将信号传递给下一个神经元的树突或细胞体。

基于生物神经元,建立人工神经元数学模型如下图所示:

artifical_neuron

如同生物神经元能够接收多个输入信号一样,人工神经元也有多个信号输入通道,这里我们将输入信号表示为 $x_i$,输入信号的属性(兴奋或抑制神经元)及重要程度(信号强度)则通过输入通道权重参数 $w_i$ 的符号及其绝对值大小来控制。所有输入信号的累计效果则通过输入信号与权重参数的加权求和进行量化。当量化的累计效果达到某个阈值时,人工神经元将被激活,并输出一个非零数值 $y$ 代表输出信号。这里,激活阈值通过偏置项 $b$ 进行控制,具体来说,通过调整该偏置项的数值,我们可以控制神经元对于不同输入的敏感程度。当偏置项的数值增加时,神经元更容易被激活,即更容易输出激活信号;而偏置项减小时,则意味着对输入信号的敏感度下降,相对更不容易激活。输出信号和输入信号的具体映射关系通过激活函数(Activation Function)$f$ 进行控制。经过上述过程,该神经元输出可表示为:

\[y=f\left(\sum_{i=1}^n x_iw_i+b\right)\]

1.2. 激活函数

神经元的激活函数通常选为非线性函数,这使得由神经元层层连接构成的神经网络具有了逼近任何非线性函数的能力。神经网络强大的非线性建模能力使其被广泛应用于各种复杂非线性建模场景。本节介绍传统神经网络中常用的一些激活函数。

可证明,当激活函数采用线性函数时,对于多层神经网络,无论网络中隐含层的层数为多少,其输出是输入的线性拟合。这表明没有引入非线性激活函数的神经网络和直接使用线性模型的最终效果相同,也就是说神经网络中的隐含层不起作用。

\[\begin{aligned} A^{[2]} &= g(Z^{[2]}) = \lambda(W^{[2]}A^{[1]} + B^{[2]}) \\ &= \lambda(W^{[2]}\lambda(W^{[1]}X + B^{[1]}) + B^{[2]}) \\ &= \lambda^2 W^{[2]}W^{[1]}X + \lambda^2 W^{[2]}B^{[1]} + \lambda B^{[2]} \end{aligned}\]

因此,要使神经网络能够发挥其作用,其激活函数必须是非线性函数。

1.2.1. 阶跃函数

阶跃函数又被称为阈值激活函数,是最简单的激活函数,输出取二进制值。当输入高于某一个阈值时,神经元被激活;当输入低于该阈值时,神经元不被激活。阈值激活函数的数学表达式为:

\[f(x) = \text{sgn}(x) = \begin{cases} 0,\; x\leq 0\\ 1,\; x> 0 \end{cases}\]

其函数图像为

step_function

当使用节约函数时,神经元输出的数学表达式为:

\[y=\text{sgn}\left(\sum_{i=1}^n x_i w_i+b\right)\]

通过阶跃函数,我们可以直观认识到偏置参数 $b$ 对神经元兴奋抑制的调节。当偏置项的数值增加时,神经元更容易被激活,即更容易输出激活信号;而偏置项减小时,则意味着对输入信号的敏感度下降,相对更不容易激活。

1.2.2. Sigmoid 函数

Sigmoid 函数是一个形似 S 的函数,又被称为 Logistic 函数,因为它是线性回归转换为Logistic(逻辑回归)的核心函数。其本身及其反函数都具有单调递增等的性质,因此常被用作人工神经元的激活函数。Sigmoid 函数将变量映射到 $(0,1)$ 范围内,其函数与其导数的数学表达式为:

\[\begin{aligned} f(x) &= \frac{1}{1+e^{-x}}\\ f^\prime(x) &= \frac{e^{-x}}{(1+e^{-x})^2} = f(x)(1-f(x)) \end{aligned}\]

函数及其导数的图像为

sigmoid

Sigmoid 函数是可微且梯度平滑的,避免了出现跳跃的输出函数值。该函数的值域为 $[0,1]$ 这使得其具备以下优势:

  • 概率分布:根据概率公理化定义知道,概率的取值范围在 $[0, 1]$ 之间,Sigmoid 函数的输出和概率分布的取值范围契合。这也是 Logistic(逻辑回归)使用 Sigmoid 函数的原因之一;

  • 信号强度:一般可以将 $0\sim 1$ 理解成某种信号的强度。由于RNN循环神经网络只能够解决短期依赖的问题,不能够解决长期依赖的问题,因此提出了 LSTM、GRU,这些网络相比于 RNN 最大的特点就是加入了门控制,通过门来控制是否允许记忆通过,而 Sigmoid 函数还能够代表门控值(Gate)的强度,当 Sigmoid 输出 $1$ 的时候代表当前门控全部开放(允许全部记忆通过),当 Sigmoid 输出 $0$ 的时候代表门控关闭(不允许任何记忆通过)。

观察 Sigmoid 函数及其导数可以发现,其导数可以用其函数值简单计算求得,规避了复杂的求导计算。这也是激活函数选取的重要因素之一。

Sigmoid 函数的缺点在于:

  • 包含指数项,计算量较大;
  • 函数输出不是以 $0$ 为中心正负分布的,导致网络权重都往正或都往负的方向更新,使得权重更新效率低;
  • 当输入远离原点时,函数的梯度趋近于0,导致梯度消失问题。

Sigmoid型函数的以上缺陷限制了其在现代神经网络模型中的应用。

1.2.3. Tanh 函数

Tanh 函数是双曲正切函数,由基本双曲函数中的双曲正弦函数和双曲余弦函数推导所得,其数学表达式为:

\[\tanh(x)=\frac{\sinh(x)}{\cosh(x)} = \frac{e^x-e^{-x}}{e^x+e^{-x}}\]

该函数可以看作是经过放大平移的Sigmoid型激活函数,两个函数数学表达式之间的关系为

\[\tanh(x) = \frac{2}{1+e^{-2x}}-1 = 2\times\text{Sigmoid}(2x)-1\]

Tanh 函数及其导数图像为

tanh

Tanh 函数的值域是 $(-1,1)$,且以 $0$ 为中心。相较于 Sigmoid 函数,Tanh 函数收敛速度较快。

优点:

  • 输出均值为 $0$。这是 tanh 非常重要的一个优点;
  • 在原点附近与 $y = x$ 函数形式相近,当激活值比较低的时候,训练相对比容易;
  • 变化敏感区间较宽,缓解梯度弥散的现象。tanh 导数取值范围在 0 到 1 之间,要优于 sigmoid 激活函数的 0 到 0.25,相比于Sigmoid 函数能够缓解梯度弥散的现象;

缺点:

  • 包含指数项,计算量比较大。

1.2.4. ReLU 系列函数

1.2.4.1. ReLU 函数

ReLU 全称是 Rectified Linear Unit,中文名称是线性整流函数,是在神经网络中常用的激活函数。通常意义下,其指代数学中的斜坡函数,即

\[\text{ReLU}(x) = max(0, x)\]

函数及其导数图像如下

ReLU函数

通过 ReLU 激活函数的函数图像可以看到,ReLU 对小于 $0$ 的值全部抑制为 $0$;对于正数则直接输出,这是一种单边抑制的特性,而这种单边抑制来源于生物学。ReLU 函数的导数计算也非常简单,$x$ 大于等于 $0$ 的时候,导数值为 $1$,在反向传播的过程中,它既不会放大梯度,造成梯度爆炸;也不会缩小梯度,造成梯度弥散的现象。

2012 年 ImageNet 竞赛的冠军模型是由 Hinton 和他的学生 Alex 设计的 AlexNet,其中使用了一个新的激活函数 ReLU(REctified Linear Unit,修正线性单元)。在这之前 Sigmoid 函数通常是神经网络激活函数的首选,上面也提到过,Sigmoid 函数在输入值较大或较小的时候容易出现梯度值接近于0的现象,也就是梯度弥散。出现梯度弥散现象,网络参数会长时间得不到更新,很容易导致训练不收敛或停滞不动的现象发生,网络层数较深的网络模型更容易发生梯度弥散现象,使得对神经网络的研究一直停留在浅层网络。值得一提的是,AlexNet是一个 8 层的网络,而后续提出的上百层的卷积神经网络也多是采用 ReLU 激活函数。

ReLU函数的优缺点。

优点:

  • 梯度不发散。当输入值为正的时候,梯度恒为 $1$,没有梯度发散的现象,收敛速度快;
  • 增大了网络的稀疏性。当输入值 $x < 0$ 的时候,该层的输出为 $0$,训练完成后为 $0$ 的神经元越来越多,稀疏性会变大,网络的协同性会被破坏,更够迫使网络学习到更一般性的特征,泛化能力会变强。这也正是 dropout 的原理;
  • 计算量变小。ReLU 函数和 Sigmoid 函数相比少了复杂的幂运算,且计算量变小;
  • 缺点:

  • 输出均值非 $0$;
  • ReLU 死亡。若遇到异常输入导致输出和真实标签差距很大,此时误差反向传播更新参数(如偏置 $b$)使得 $b < 0$,这使得后续正常输入经过该神经元后的输出值小于 $0$,此时神经元输出恒为 $0$, 对输出没有任何贡献,梯度反向传播时参数也得不到更新,那么此时该神经元就会 “死亡”。并且随着网络的训练,该层前面的神经元参数的更新幅度会随着模型的收敛而趋缓,输出变动会逐渐降低,这使得从概率上来说当前神经元完全复活的可能性极小, 也就可以称之为不可逆的死亡。
1.2.4.2. LeakyReLU 函数

LeakyReLU 函数用于环节 ReLU 神经元死亡的问题,它在激活函数输入 $x<0$ 区间给出一个很小的负数输出梯度值,而不是直接输出 $0$,计算公式为:

\[f(x) = \max(\alpha x, x)\]

其中 $\alpha$ 是一个很小的常数,通常可赋值为 $0.01$。

函数及其导数图像为

Leaky-ReLU函数

通过这个操作可以保留一些输入为负数时的信息,避免了输入为负数时神经元死亡的情况。

1.2.4.3. ELU 函数

ELU 函数(Exponential Linear Unit,指数线性单元)融合了 Sigmoid 函数和 ReLU 函数,该函数左侧具有软饱和性,右侧无饱和性。ELU 的定义为:

\[f(x) = \begin{cases} x & \text{if } x \ge 0 \\ \alpha(e^x - 1) & \text{if } x < 0 \end{cases}\]

函数图像为

ELU函数

1.2.5. Swish 函数

Swish 函数(Swish Activation Function)是 2017 年 Google Brain 团队提出的一种激活函数,该函数的数学定义为:

\[f(x) = x \cdot \text{Sigmoid}(\beta x)\]

Swish 函数的图像如下

Swish函数

  • 当 $\beta = 0$ 时,Swish 函数变为线性函数 $f(x) = \frac{x}{2}$;
  • 当 $\beta = \infty$ 时,Swish 函数变为 $0$ 或 $x$,相当于 ReLU 函数。

所以,Swish 函数可以看作是介于线性函数与 ReLU 函数之间的平滑函数。

Swish 函数的导数计算如下

\[\frac{d}{dx} \text{Swish}(x) = \beta\cdot \text{Swish}(x) + \text{Sigmoid}(\beta x) (1-\beta\cdot \text{Swish}(x))\]

Swish 函数的导数图像如下

Swish函数的导数

1.2.6. 恒等映射函数

恒等映射函数作为激活函数,通常被用于回归任务中的输出层,就是没有任何非线性变换,即

\[f(x) = x\]

这意味着网络输出层的激活值直接作为预测值,预测值是最后一层的线性组合结果。该激活函数。

1.2.7. softmax 函数

softmax 函数是常用的激活函数,一般用于分类任务的输出层。表达式如下:

\[\text{softmax}(x)_i = \frac{e^{x_i}}{\sum_{j=1}^n e^{x_j}}\]

它将输入向量映射到 $[0,1]$ 区间,因此很好吻合分类任务中的概率输出。

2. 神经网络

2.1. 感知机

感知机是最简单的前馈式人工神经网络,它是由美国心理学家 Frank Roseblatt 在 1957 年提出,是一种单层的前馈神经网络,包含一个输入层和一个输出节点,且神经元的激活函数为 阶跃函数。使用阶跃函数作为激活函数时,神经元就是前面介绍过的 感知机模型

感知机模型如图:

单层感知机

数学模型如下:

\[y = f(\boldsymbol{W}^\top\boldsymbol{x}+b),\quad f(z)=\begin{cases} 1 & \text{if } z\geq 0,\\ 0 & \text{if } z< 0. \end{cases}\]

1969年 , Marvin Minsky 和 Seymour Papert 出版了《感知机:计算几何学导论》(Perceptrons: An Introduction to Computational Geometry),从数学上证明了单层前馈感知机的局限性,感知机只能解决「线性可分问题」,甚至不能解决简单的 “异或” 逻辑问题。此后,神经网络的研究几乎处于休眠状态,直到上世纪 80 年代才又被从历史的角落重新拾起。

假设分离超平面的误分类点集合为 $Y_e$,则所有误分类点到超平面的总距离为:

\[\frac{1}{\Vert\boldsymbol{W}\Vert}\sum_{\boldsymbol{x}_i\in Y_e}\vert \boldsymbol{W}^\top\boldsymbol{x}_i+b\vert\]

如果不考虑系数,感知机学习的算法是通过学习找到一组参数 $(\boldsymbol{W}^\star,b^\star)$ ,使得以下损失函数最小:

\[\min L(\boldsymbol{W},b) = -\sum_{\boldsymbol{x}_i\in Y_e} y_i(\boldsymbol{W}^\top\boldsymbol{x}_i+b)\]

(1)当误分类时,满足 $-y_i(\boldsymbol{W}^\top\boldsymbol{x}_i+b) \geq 0$,因此可设计上述损失函数(思考:为什么?)

(2)感知机的一般推导会使用增广变换(消除偏置)和规范化(负样本取反),但此处没有使用;

如果样本集非常大,每次都要计算所有误分样本,这需要耗费非常大的计算资源,实际应用中通常使用随机梯度下降算法代替,即每次随机选取一个误分样本更新参数。感知机学习算法本质是随机梯度下降的变种

\[\min L(\boldsymbol{W},b) = -y_i(\boldsymbol{W}^\top\boldsymbol{x}_i+b),\quad \boldsymbol{x}_i\in Y_e\]

对应的参数更新式为

\[\begin{aligned} \boldsymbol{W} &\leftarrow \boldsymbol{W} + \eta y_i \boldsymbol{x}_i\\ b &\leftarrow b + \eta y_i \end{aligned}\]

Novikoff 定理保证,若规范化增广训练数据集是线性可分的,则随机梯度下降法在规范化增广训练数据集上的误分类次数一定小于某个值,即感知机训练过程可在有限轮迭代内完成,即感知机训练算法是收敛的。


例:某个训练数据集,其正样本为:$\boldsymbol{x}_1=[3,3]^\top, \boldsymbol{x}_2=[4,3]^\top$,负样本为:$\boldsymbol{x}_3=[1,1]^\top$,试用感知准则函数求解感知机模型 $g(x) = f(\boldsymbol{W}^\top\boldsymbol{x}+b),\; \boldsymbol{W}=[w_1, w_2]^\top$。

Perception_classifier

构建最优问题:$\min \; L(\boldsymbol{W},b)=-\sum_{\boldsymbol{x}\in Y_e} y_i(\boldsymbol{W}^\top\boldsymbol{x}+b)$;

设学习率 $\eta=1$,初始权值和偏置 $\boldsymbol{w}=[0,0]^\top, b=0$;

对于 $\boldsymbol{x}_1=[3,3]^\top$,计算得到 $y_1(\boldsymbol{W}^\top\boldsymbol{x}_1+b) = 0$,判定为错误分类,利用该点更新参数

\[\begin{aligned} \boldsymbol{W} &\leftarrow \boldsymbol{W} + \eta y_1\boldsymbol{x}_1 \Rightarrow \boldsymbol{w} = [3,3]^\top\\ b &\leftarrow b + \eta y_1 \Rightarrow b = 1 \end{aligned}\]

对于 $\boldsymbol{x}_1,\boldsymbol{x}_2$,计算判定分类正确;

对于 $\boldsymbol{x}_3=[1,1]^\top$,计算得到判定分类错误,更新参数如下:

\[\begin{aligned} \boldsymbol{W} &\leftarrow \boldsymbol{W} + \eta y_3\boldsymbol{x}_3 \Rightarrow \boldsymbol{w} = [2,2]^\top\\ b &\leftarrow b + \eta y_3 \Rightarrow b = 0 \end{aligned}\]

不断遍历误分类点,使用误分类样本更新参数,直到误分类点为空集。

Perception_classification_process

最终得到参数为

\[\boldsymbol{W} = [1,1]^\top,\; b = -3\]

此时分类超平面为 $x^{(1)}+x^{(2)}-3 = 0$, 感知机模型为 $g(\boldsymbol{x})=f(x^{(1)}+x^{(2)}-3)$,如图

Perception_classifier-result

注意到,选取误分类点时不同的选择会导致最终得到的分类面不同,如在上述计算中误分类点时:

  • 先后取 $x_1,x_3,x_3,x_3,x_1,x_3,x_3$,分离超平面为红色实线。
  • 先后取 $x_1,x_3,x_3,x_3,x_2,x_3,x_3,x_3,x_1,x_3,x_3$,分离超平面为绿色实线。

Perception_classifier-result


2.2. 多层感知机

在前面介绍的单层感知机中,采用阶跃函数只能更新「一层」神经元的参数,因为多层感知机的权重梯度需要依赖链式法则求解,其中涉及到激活函数的导数,而阶跃函数的激活函数几乎处处为零,度无法通过隐藏层传播到更早的层(梯度消失),导致前面的层参数无法更新。

\[f(z) = \begin{cases} 1 & \text{if } z \geq 0, \\ 0 & \text{if } z < 0. \end{cases}, \quad f'(z) = \begin{cases} \text{未定义} & \text{at } z = 0, \\ 0 & \text{otherwise}. \end{cases}\]

1986 年,David Rumelhart、Geoffrey Hinton 和 Ronald Williams 等科学家提出了误差反向传播算法,解决了具有隐藏层的多层感知机的训练问题。多层感知机使用 Sigmoid 函数替代了阶跃函数作为激活函数。从此,神经网络研究掀起第二次浪潮。

多层感知机是具有一个或多个隐藏层的神经网络模型,具有学习复杂非线性关系的能力。多层感知机包含三个层级:输入层、隐藏层、输出层。其中,输入层的节点严格来说并不是神经元,因为它们没有参数,也没有激活函数;隐藏层是多层感知机的核心组成部分,可以有一个或多个隐藏层,且每个隐藏层包含多个节点(神经元),这些节点通过权重与输入层或前一隐藏层的节点相连。隐藏层的引入使得网络深度增加,增强了网络的学习能力和非线性模式表达能力。

2.2.1. 网络结构

多层感知机是具有一个或多个隐藏层的神经网络模型,具有学习复杂非线性关系的能力。下图所示为多层感知机的示例,示例中的多层感知机包含三个层级:输入层、隐藏层、输出层。其中:

  • 输入层的节点严格来说并不是神经元,因为它们没有参数,也没有激活函数;
  • 隐藏层是多层感知机的核心组成部分,可以有一个或多个隐藏层,且每个隐藏层包含多个节点(神经元),这些节点通过权重与输入层或前一隐藏层的节点相连。隐藏层的引入使得网络深度增加,增强了网络的学习能力和非线性模式表达能力;
  • 输出层最可以看作是最后一层隐藏层,但其输出需要与样本标签进行比较,计算损失函数并通过反向传播来更新神经网络的参数。

DNN

注意到,多层感知机的每一层神经元均与前一层所有神经元都进行连接,因此多层感知机又被称为「全连接神经网络」。又因为多层感知机得以实现的前提是采用反向传播(BP)算法,因此又被称为「BP 神经网络」。

2.2.2. 信号前向推理

神经网络的前向推理过程就是从输入样本特征开始,逐一套用每个神经元的数学模型,一步步往前递推得到输出层的神经网络输出结果的过程。以第 $L_2$ 层隐层的第 $q$ 个神经元为例:

\[x_2^{q} = f(\sum_{i=1}^p w_2^{q,i} x_i + b_2^i)\]

写成矩阵形式有

\[\boldsymbol{x}_2 = f(\boldsymbol{W}_2 \boldsymbol{x}_1 + \boldsymbol{b}_2)\]

以此类推,整个神经网络的前向推理过程可以写成

\[\boldsymbol{x}_l = f(\boldsymbol{W}_l \boldsymbol{x}_{l-1} + \boldsymbol{b}_l)\]

其中,权重矩阵的维度为

\[\boldsymbol{W}\in \mathbb{R}^{n^l\times n^{l-1}}\]

其中 $n^{l}$ 表示第 $l$ 层神经元的个数,$n^l$ 表示第 $l$ 层神经元的个数。

2.2.3. 误差反向传播

对于神经网络的每一层神经元,需要采用链式求导法则得到损失函数对各层神经元权重、阈值参数的梯度。这个过程就是「反向传播」(Back Propagation,BP)。为了推导简便,约定各个符号如下图所示:

neuron-model

则前向传播过程改写为:

\[\begin{aligned} \boldsymbol{z}^l &= \boldsymbol{W}^l \boldsymbol{a}^{l-1} + \boldsymbol{b}^l\\ \boldsymbol{a}^l &= f(\boldsymbol{z}^l) \end{aligned}\]
2.2.3.1. 损失函数

一个多层感知机或者一个前馈神经网络可以看作是一个复杂的非线性多元函数。在进行网络参数优化前,我们需要设置一个衡量误差的量化函数,该函数除了用于评判当前网络对于目标任务的性能外,其最重要的功能就是指导网络参数的优化方向及优化量,这个量化函数就是我们常说的「损失函数」。网络学习过程就是以当前输入数据为固定参数,以权重、偏置为自变量的,寻找函数局部极小值点的过程。这里的极小值点是指使得损失函数值取极小的网络权重、偏置参数解。

  • 对于 回归任务,希望在 $n$ 个样本点上的预测输出 $a^L_i$ 与真实标签 $y_i$ 尽可能接近($i=1,2,\cdots,n$),采用「均方误差」(Mean Square Error,MSE)来衡量相似性,即需要最小化

    \[L = \frac{1}{n}\sum_{i=1}^n\Vert a^L_i - y_i \Vert_2^2\\\]
  • 对于 $k$ 分类任务,设第 $i$ 个样本的标签向量 $\boldsymbol{y}_i = [y_i^{1},y_i^{2},\cdots, y_i^k]^\top$(一般为独热编码),那么我们希望神经网络的输出 $\boldsymbol{a}^L_i$ 与标签 $\boldsymbol{y}_i$ 尽可能的相似,采用 CE (交叉熵)来衡量相似性,即需要最小化

    \[L = -\frac{1}{n}\sum_{i=1}^n \sum_{j=1}^k y_i^j \ln a^{L,j}_i\]

上述损失函数是批量梯度下降法(BGD)或小批量梯度下降法(MBGD)的损失函数。后文为了简化起见,均采用随机梯度下降法(SGD),因此不考虑多个样本的损失函数求和。关于梯度下降法的介绍,详见 此处

2.2.3.2. 反向传播

由于神经网络及其损失函数构成了一个非常复杂的多元函数,求解其局部最小值点的解析解在绝大多数情况下是不可行的,需采用数值优化方法来寻找其局部极小值点,这里要介绍的 误差反向传播算法」(BP算法)就是其中之一,其核心是采用「梯度下降法」来更新网络参数,从而达到网络参数的优化。

这里的「误差」是一个新的概念 $\delta$,其定义为损失函数 $L$ 关于某层神经元预激活值 ${z}^L$ 的梯度。根据误差可以将反向传播过程写成十分简洁的递推形式,这也是为什么反向传播又被称为「误差反向传播」的原因。注意该误差并不是损失函数计算中的“误差”,本质是梯度。

根据前面关于激活函数的讨论,我们知道多层感知机的隐层和输出层的激活函数是不同的,因此反向传播过程也需要针对输出层和隐层分别讨论。

==================== 输出层误差 ====================

在计算输出层误差时,需要进一步针对回归问题和分类问题分别讨论。

  • 回归问题

    回归问题输出层结构

    采用「MSE + 恒等函数$f$」组合的输出层 $L$,有

    \[{a}^{L} = {z}^L\\\]

    损失函数为

    \[L = \Vert a^L - y \Vert_2^2\]

    输出层 $L$ 的误差为(忽略常数系数)

    \[\delta^{L} \triangleq \frac{\partial L}{\partial {z}^L} = \frac{\partial L}{\partial {a}^L} = \textcolor{red}{a^L-y}\]
  • 分类问题

    分类问题输出层结构

    采用「CE + softmax函数」组合的输出层,损失函数为

    \[L = -\sum_{j=1}^k y_j \ln a^L_j\]

    对于第 $j$ 个神经元有

    \[a^L_j = \text{softmax}(z^L) = \frac{e^{z_j^L}}{\sum_{i=1}^k e^{z^L_i}}\]

    输出层 $L$ 第 $j$ 个神经元的误差为

    \[\delta^{L}_j \triangleq \frac{\partial L}{\partial z_j^L} = \sum_{i=1}^k\frac{\partial L}{\partial a_i^L} \frac{\partial a_i^L}{\partial z_j^L}\]

    注意此处需要对 $i$ 进行遍历,因为根据 softmax 函数定义,每个输出 $a_i$ 都和第 $j$ 个神经元预激活值 $z_j$ 有关。

    第一项

    \[\frac{\partial L}{\partial a^L_i} = -\frac{y_i}{a^L_i}\]

    第二项(也即 softmax 函数的导数),又因为 softmax 分子和分母都含有预激活值,需要根据其下标取值分两种情况讨论:

    (a) 当 $i=j$ 时

    \[\frac{\partial a^L_i}{\partial z^L_j} = a^L_i(1-a^L_i)\]
    展开详细推导

    为了表述方便,省去上标 $L$

    \[\begin{aligned} \frac{\partial a_i}{\partial z_i} &= \frac{\partial a_i}{\partial z_i} \\ &= \frac{\partial}{\partial z_i} \left( \frac{e^{z_i}}{\sum_k e^{z_k}} \right) \\ &= \frac{(e^{z_i})' (\sum_k e^{z_k}) - e^{z_i} (\sum_k e^{z_k})'}{(\sum_k e^{z_k})^2} \\ &= \frac{e^{z_i} \cdot (\sum_k e^{z_k}) - e^{z_i} \cdot e^{z_i}}{(\sum_k e^{z_k})^2} \\ &= \frac{e^{z_i}}{\sum_k e^{z_k}} - \frac{e^{z_i}}{\sum_k e^{z_k}} \cdot \frac{e^{z_i}}{\sum_k e^{z_k}} \\ &= a_i - a_i \cdot a_i \\ &= a_i (1 - a_i) \end{aligned}\]

    (b) 当 $i\neq j$ 时

    \[\frac{\partial a^L_i}{\partial z^L_j} = -a^L_i a^L_j\]
    展开详细推导

    为了表述方便,省去上标 $L$

    \[\begin{aligned} \frac{\partial a_i}{\partial z_j} &= \frac{\partial}{\partial z_j} \left( \frac{e^{z_i}}{\sum_k e^{z_k}} \right) \\ &= \frac{(e^{z_i})' (\sum_k e^{z_k}) - e^{z_i} (\sum_k e^{z_k})'}{(\sum_k e^{z_k})^2} \\ &= \frac{0 \cdot (\sum_k e^{z_k}) - e^{z_i} \cdot e^{z_j}}{(\sum_k e^{z_k})^2} \\ &= \frac{-e^{z_i} \cdot e^{z_j}}{(\sum_k e^{z_k})^2} \\ &= -\frac{e^{z_i}}{\sum_k e^{z_k}} \cdot \frac{e^{z_j}}{\sum_k e^{z_k}} \\ &= -a_i \cdot a_j \end{aligned}\]

    合并上述结果,误差为 $\textcolor{red}{\delta_j^L = a_j^L-y_j}$。

    展开详细推导
    \[\begin{aligned} \delta^{L}_j &= -\frac{y_j}{a^L_i} \cdot a^L_i(1-a^L_i) - \sum_{i\neq j} \frac{y_i}{a^L_i} (-a^L_i a^L_j)\\ &= - y_j+y_ja_i^L+\sum_{i\neq j} y_ia_j^L\\ &= -y_j+\sum_{i} y_ia_j^L\\ &=-y_j + a_j^L\sum_i y_i \end{aligned}\]

    注意到 $y_i$ 是独热编码的概率值,其和为 $1$,因此有

    \[\delta^{L}_i = -y_i + a_j^L\]

    又因为 $y_i$ 是独热编码的概率值,只有一个位置(假设是第 $i$ 个位置)是 $1$, 其他位置都是 $0$,因此对于 $k$ 分类任务,输出层误差可写为

    \[\begin{bmatrix} a_1^L\\ a_2^L\\ \vdots\\ a_i^L - 1\\ \vdots\\ a_k^L \end{bmatrix}\]

    结果十分优美。

    则权重的梯度为

    \[\frac{\partial L}{\partial \boldsymbol{W}^L} = \frac{\partial L}{\partial \boldsymbol{z}^L} \cdot \frac{\partial \boldsymbol{z}^L}{\partial \boldsymbol{W}^L} = \delta^{L} \cdot (a^{L-1})^\top\quad\in\mathbb{R}^{n^L\times n^{L-1}}\]

    偏置的梯度为

    \[\frac{\partial L}{\partial \boldsymbol{b}^L} = \frac{\partial L}{\partial \boldsymbol{z}^L} \cdot \frac{\partial \boldsymbol{z}^L}{\partial \boldsymbol{b}^L} = \delta^{L}\quad\in\mathbb{R}^{n^L\times 1}\]

==================== 隐层误差 ====================

对于隐层 $l$,有

\[\begin{aligned} \boldsymbol{a}^{l} &= f(\boldsymbol{z}^l)\\ \boldsymbol{z}^{l} &= \boldsymbol{W}^l \boldsymbol{a}^{l-1} + \boldsymbol{b}^l \end{aligned}\]

定义隐层 $l$ 的误差为损失函数关于隐层预激活值 $\boldsymbol{z}^l$ 的梯度,根据链式法则有

\[\delta^l \triangleq \frac{\partial L}{\partial \boldsymbol{z}^l} = \frac{\partial L}{\partial \boldsymbol{z}^{l+1}} \cdot \frac{\partial \boldsymbol{z}^{l+1}}{\partial \boldsymbol{a}^{l}}\cdot \frac{\partial \boldsymbol{a}^{l}}{\partial \boldsymbol{z}^l}\quad\in \mathbb{R}^{n^{l}\times 1}\]

第一项

\[\frac{\partial L}{\partial \boldsymbol{z}^{l+1}} = \delta^{l+1}\quad\in\mathbb{R}^{n^{l+1}\times 1}\]

第二项

\[\boldsymbol{z}^{l+1} = \boldsymbol{W}^{l+1} \boldsymbol{a}^l + \boldsymbol{b}^{l+1}\quad\Rightarrow \quad\frac{\partial \boldsymbol{z}^{l+1}}{\partial \boldsymbol{a}^l} = \boldsymbol{W}^{l+1}\in\mathbb{R}^{n^{l+1}\times n^l}\]

最后项

\[\boldsymbol{a}^{l} = f(\boldsymbol{z}^{l}) \quad\Rightarrow \quad\frac{\partial \boldsymbol{a}^{l}}{\partial \boldsymbol{z}^{l}} = f'(\boldsymbol{z}^{l})\in\mathbb{R}^{n^{l}\times 1}\]

最终得到(权重矩阵转置是因为需要维度匹配)

\[\textcolor{red}{\delta^{l} = (\boldsymbol{W}^{l+1})^\top\delta^{l+1} \odot f'(\boldsymbol{z}^{l})}\]

其中 $\odot$ 表示 Hadamard 积,即逐元素相乘。

则权重的梯度为

\[\begin{aligned} \frac{\partial L}{\partial \boldsymbol{W}^l} &= \frac{\partial L}{\partial \boldsymbol{z}^l} \cdot \frac{\partial \boldsymbol{z}^l}{\partial \boldsymbol{W}^l}= \delta^{l} \cdot (\boldsymbol{a}^{l-1})^\top \end{aligned}\]

偏置的梯度为

\[\frac{\partial L}{\partial \boldsymbol{b}^l} = \frac{\partial L}{\partial \boldsymbol{z}^l} \cdot \frac{\partial \boldsymbol{z}^l}{\partial \boldsymbol{b}^l}= \delta^{l} \cdot 1 = \delta^{l}\]

========================================

综上,输出误差(由损失函数刻画)通过隐含层向输入层逐层反向传播,并将误差分摊给各层所有节点(获得所有层的误差估计),采用梯度下降的方式,按误差函数的负梯度方向修改各节点连接权重和偏置。

\[\begin{aligned} \boldsymbol{W} &\leftarrow \boldsymbol{W}-\alpha\frac{\partial L}{\partial \boldsymbol{W}}\\ \boldsymbol{b} &\leftarrow \boldsymbol{b}-\alpha\frac{\partial L}{\partial \boldsymbol{b}} \end{aligned}\]
2.2.3.3. 梯度消失

梯度消失问题通常发生在使用 Sigmoid 或 Tanh 等饱和激活函数时,这些激活函数的导数本身就小于 $0$,在输入很大或很小时趋近于 $0$。

分析权重的梯度

\[\begin{aligned} \frac{\partial L}{\partial \boldsymbol{W}^l} &= \textcolor{red}{\delta^{l}} \cdot (\boldsymbol{a}^{l-1})^\top\\ &=\textcolor{red}{(\boldsymbol{W}^{l+1})^\top\delta^{l+1} \odot f'(\boldsymbol{z}^{l})}\cdot (\boldsymbol{a}^{l-1})^\top\\ &= \textcolor{red}{(\boldsymbol{W}^{l+1})^\top} \textcolor{blue}{(\boldsymbol{W}^{l+2})^\top\delta^{l+2} \odot f'(\boldsymbol{z}^{l+1})} \textcolor{red}{\odot f'(\boldsymbol{z}^{l})}\cdot (\boldsymbol{a}^{l-1})^\top\\ &= \textcolor{red}{(\boldsymbol{W}^{l+1})^\top} \textcolor{blue}{(\boldsymbol{W}^{l+2})^\top } \underbrace{\cdots \textcolor{blue}{\odot f'(\boldsymbol{z}^{l+1})} \textcolor{red}{\odot f'(\boldsymbol{z}^{l})}}_{\text{sigmoid}^\prime(z)_{\max} = 0.25} \textcolor{red}{\cdot (\boldsymbol{a}^{l-1})^\top} \end{aligned}\]

可以看出,在神经网络层数很深的情况下,当大量小于或趋近于 $0$ 的激活函数导数相乘时,会导致梯度在反向传播过程中迅速减小,从而使得网络中较早层的权重更新非常缓慢或几乎不更新。这种情况随着网络层数的增加而更加严重,被称为「梯度消失」。

另外,当权重矩阵的元素较小时,也会导致梯度消失。

可以通过如下方式缓解梯度消失:

  • 使用合适的激活函数:
    • ReLU(Rectified Linear Unit):导数为0或1,避免连乘导致的梯度消失。
    • Leaky ReLU、Parametric ReLU:解决ReLU的“死亡”问题。
  • 权重初始化:合理的初始化(如Xavier、He初始化)可以避免初始权重过小。
  • Batch Normalization:通过规范化每一层的输入,使得激活函数的输入分布在较稳定的范围内,避免梯度消失。
  • 残差连接(ResNet):引入跳跃连接(skip connections),使得梯度可以直接绕过某些层传播,缓解梯度消失。
2.2.3.4. 梯度爆炸

与梯度消失相反,梯度爆炸指的是梯度在反向传播过程中指数级增长,导致参数更新过大,模型无法收敛。这主要是由于:

  1. 权重矩阵的范数较大:如果权重矩阵的元素较大,其转置的乘积会导致梯度迅速增大。
  2. 激活函数的导数较大:如果激活函数的导数较大,则反向传播过程中梯度会快速放大,这一般出现在使用 ReLU 函数时可能出现。

可以通过如下方式缓解梯度爆炸:

  • 梯度裁剪(Gradient Clipping):设定梯度的阈值,超过时进行缩放,防止梯度爆炸。
  • 权重正则化:L1或L2正则化,限制权重的范数,防止其过大。
  • 使用更小的学习率:降低学习率可以减少参数更新的幅度。
  • 权重初始化:合理的初始化(如Xavier、He初始化)可以避免初始权重过大。

2.3. 自组织神经网络

2.3.1. 自组织竞争神经网络

自组织竞争神经网络(Self-Organizing Competitive Neural Networks)是一类「无监督」学习神经网络模型,能够通过竞争机制自动发现输入数据中的模式或特征。自组织神经网络是早期无监督学习网络模型的代表,模拟了生物神经系统侧抑制现象。

在生物神经系统中,存在着一种「侧抑制现象」,即一个神经细胞兴奋以后,会对周围其他神经细胞产生抑制作用。这种抑制作用会使神经细胞之间出现竞争,竞争获胜的神经细胞兴奋,失败的神经细胞被抑制。

与感知机相比,自组织竞争神经网络的单层网络又被称为竞争层,如图所示:

SOCNN

输入层:接收外界信息,将输入模式向竞争层传递。竞争层对输入模型进行分析比较,寻找规律,并进行归类处理。竞争层神经元之间相互竞争激活,在任意时刻只有一个神经元被激活。被激活的神经元被称为胜利者神经元(winner-takes-all neuron),而其它神经元的状态被抑制,故称为 Winner Take All(赢者通吃,简称 WTA)。

WTA 的具体步骤如下:

  • 向量归一化:对网络当前输入向量 $X$ 和竞争层中各神经元对应的权重向量 $W_j$(对应 $j$ 神经元)全部进行归一化,使得二者的模为 $1$;
  • 寻找获胜神经元:
    • 计算输入向量与每个输出神经元权重向量的相似度,如采用欧式距离;
    • 选择相似度最大的神经元为获胜神经元; \(c = \arg\min_j(||X - W_j||^2)\)
  • 更新获胜神经元权重,其他神经元权重保持不变
    • $W_c = W_c + \eta(X-W_c) = \eta X + (1 - \eta) W_c$;
    • 学习率 $0<\eta<1$ 随着迭代的进行逐渐减小;
  • 将更新后的权重向量重新归一化(保持单位长度);
  • 重复上述步骤,直到权重变化小于阈值或达到最大迭代次数。

WTA竞争学习是许多自组织神经网络的基础,通过这种简单的竞争机制,网络能够自动发现数据中的主要模式。

思考:最终权重收敛到什么位置?

2.3.2. 自组织映射神经网络

自组织特征映射网络(Self-Organizing Feature Maps,SOFM)又称自组织映射网络(SOM),由 Kohonen 于 1981 年提出。与竞争性网络非常相似,SOM 也是单层网络结构,神经元都具有竞争性,都采用无监督学习方式,但在输出层引入网络的「拓扑结构」,可以更好地模拟生物学中的侧抑制现象,如图所示:

SOM

  • 假设一个输入样本为 $x_i$ 是一个 $n$ 维向量,则输入层神经元个数为 $n$ 个;
  • 输入神经元和输出神经元也通过权值相连;
  • 输出神经元一般以二维拓扑结构排列,神经元数量和训练集样本的类别数相关,比如要分成 $4$ 类,那可以将输出层(竞争层)设计为 $2\times2$。若不清楚类别数,尽可能地设定较多的节点数,以便较好地映射样本的拓扑结构,如果分类过细再适当减少输出节点;
  • 一般而言输出层神经元个数小于样本特征维度,从而达到降维的目的。

SOM 的训练过程与 自组织竞争神经网络类似,但也有不同:

  1. 初始化权值矩阵 $\boldsymbol{w}$,即每个神经元的权值向量;
  2. 输入样本 $\boldsymbol{x}$,计算 $\boldsymbol{x}$ 与每个输出层神经元权重 $\boldsymbol{w}_i$ 的距离,并找到距离最小的神经元 $c_i$,称之为最佳匹配单元(Best Matching Unit,BMU);
  3. 最佳匹配单元及其近邻神经元的权向量将被调整。

上述步骤中,如何确定邻近神经元以及如何计算邻域神经元更新权重的方式是 SOM 的核心。

  • 邻域距离度量

对于最佳匹配单元 BMU,假设其网格坐标为 $(c_i,c_j)$,其他神经元$(c_i^\prime,c_j^\prime)$与其的网格距离可以采用:

  1. 欧式距离:$d = \sqrt{(c_i - c_i^\prime)^2 + (c_j - c_j^\prime)^2}$
  2. 曼哈顿距离:$d = \vert c_i - c_i^\prime\vert + \vert c_j - c_j^\prime \vert$
  • 邻域影响程度

确定距离后,就需要根据距离来计算邻域的影响程度,用以确定邻域神经元权向量更新的幅度(实现距离近的神经元被同步激活的程度高,距离远的激活程度低),可采用:

  1. 高斯邻域函数:$h(d) = e^{-d^2/2\sigma^2}$,其中 $\sigma$ 是邻域半径参数,随时间衰减;
  2. 墨西哥草帽函数:$h(d) = (1 - (d/\sigma)^2) \cdot e^{-d^2/(2\sigma^2)}$,其中 $\sigma$ 是邻域半径参数,随时间衰减;
  3. 大礼帽函数:如图;
  4. 矩形邻域函数(厨师帽函数):$h(d) = 1 \; \text{if}\; d < R\; \text{else}\; 0$,其中 $R$ 是邻域半径参数,随时间衰减;

邻域函数

  • 权重更新规则

和自组织竞争神经网络类似,唯一区别在于邻域神经元需要额外考虑与距离有关的影响:

\[\begin{aligned} W_{ij} &= W_{ij} + \eta \cdot h(d_{ij}) \cdot (x - W_{ij}) \\ \end{aligned}\]

在训练开始时,学习率 $\eta$ 可以选取较大的值,之后以较快的速度下降,这样有利于很快地捕捉到输入向量的大致结构,然后学习率在较小的值上缓降至0值,可以精细地调整权值,使得符合输入空间的样本分布结构。常见的学习率函数为

\[\eta(t) = \eta(t)e^{-t}\]

其中 $t$ 为迭代次数。

思考:SOM 与 K-均值算法对比?

(1) K-均值算法为每个输入数据找到一个最相似的类后,只更新这个类的参数(重新计算该类的聚类中心);自组织映射神经网络则会更新邻近节点。

(2) K-均值算法受噪声影响较大,而自组织映射神经网络的准确性可能会比 K 均值算法低(因为也更新了邻近节点,噪声点所对应的神经元节点同样被更新,加大了噪声干扰)

SOM 尤为适合高维数据的低维(二维)可视化。

下图使用两个热图说明平均教育水平和失业率之间的关系

SOM可视化0

输出层神经元的权重向量 代表/相似于 映射到该节点的样本。通过可视化整个图上的权重向量,可以看到样本和变量分布中的模型。权重向量的默认可视化是一个“扇形图”,其中为每个节点显示了权重向量中每个变量的大小的各个扇形表示。

SOM可视化1

某个五分类任务中的 SOM 可视化结果如下:

SOM可视化2

观察如上结果,发现其采用六边形邻域,好处在于邻域神经元的个数更多($6-12-\cdots$),性能更好。

SOM六边形邻域

思考:用曼哈顿距离时,邻域神经元个数是多少?

答案:$4-8-\cdots$

3. 参考文献

[1] R语言使用自组织映射神经网络(SOM)进行客户细分

本文由作者按照 CC BY 4.0 进行授权

模式识别(无监督分类器)

-