人工神经网络( Artificial Neural Network,ANN)是指一系列受生物学和神经科学启 发的数学模型。这些模型主要是通过对人脑的神经元网络进行抽象,构建人工神经元,并按 照一定的拓扑结构来建立人工神经元之间的连接,进而模拟生物神经网络。在人工智能领域, 人工神经网络也常常简称为神经网络( Neural Network,NN)或神经模型( neural model)。 神经网络最早是作为一种主要的连接主义模型。 20世纪 80年代中后期,最流行的一 种连接主义模型是分布式并行处理( Parallel Distributed Processing,PDP)模型,其有如 下 3个主要特性。 (1)信息表示是分布式的(非局部的)。 (2)记忆和知识是存储在单元之间的连接上。 (3)通过逐渐改变单元之间的连接强度来学习新的知识。 连接主义的神经网络有着多种多样的网络结构以及学习方法,虽然早期模型强调模型 的生物学合理性( biological plausibility),但后期更关注对某种特定认知能力的模拟,如 物体识别、语言理解等。尤其在引入误差反向传播来改进其学习能力之后,神经网络也越 来越多地应用在各种机器学习任务上。随着训练数据的增多以及(并行)计算能力的增强, 神经网络在很多机器学习任务上已经取得了很大的突破,特别是在语音、图像等感知信号 的处理上,神经网络表现出了卓越的学习能力。 在本章中,主要关注采用误差反向传播来进行学习的神经网络,即作为一种机器学习 模型的神经网络。从机器学习的角度来看,神经网络一般可以看作一个非线性模型,其基 本组成单元为具有非线性激活函数的神经元,通过大量神经元之间的连接,使神经网络成 为一种高度非线性的模型。神经元之间的连接权重就是需要学习的参数,可以在机器学习 的框架下通过梯度下降方法来进行学习。 3.1神经元 人工神经元( artificial neuron),简称神经元( neuron),是构成神经网络的基本单元, 主要是模拟生物神经元的结构和特性,接收一组输入信号并产生输出。生物学家在 20世纪 初就发现了生物神经元的结构。一个生物神经元通常具有多个树突和一条轴突。树突用来 接收信息,轴突用来发送信息。当神经元所获得的输入信号的积累超过某个阈值时,它就 处于兴奋状态,产生电脉冲。轴突尾端有许多末梢可以给其他神经元的树突产生连接(突 触),并将电脉冲信号传递给其他神经元。 1943年,心理学家 McCulloch和数学家 Pitts 根据生物神经元的结构,提出了一种非常简单的神经元模型 ——MP神经元。现代神经网 络中的神经元和 MP神经元的结构并无太多变化。不同的是, MP神经元中的激活函数 f 为 0或 1的阶跃函数,而现代神经元中的激活函数通常要求是连续可导的函数。假设一个 神经元接收 D个输入 x1,x2, ··· ,xD,令向量 x =[x1,x2, ··· ,xD]来表示这组输入,并用 净输入(net input)z ∈ R表示一个神经元所获得的输入信号 x的加权和。 D . z = wdxd + b d=1 (3-1) T = wx + b 其中, w =[w1,w2, ··· ,wD] ∈ RD是 D维的权重向量, b ∈ R是偏置。净输入 z在经过 一个非线性函数 f(·)后,得到神经元的活性值(activation)a: a = f(z) (3-2) 其中,非线性函数 f(·)称为激活函数(activation function)。 图 3-1给出了一个典型的神经元结构示例。 图 3-1典型的神经元结构示例 激活函数在神经元中是非常重要的。为了增强网络的表示能力和学习能力,激活函数 需要具备以下几点特性。 (1)连续并可导(允许少数点上不可导)的非线性函数。可导的激活函数可以直接利 用数值优化的方法来学习网络参数。 (2)激活函数及其导函数要尽可能简单,有利于提高网络计算效率。 (3)激活函数的导函数的值域要在一个合适的区间内,不能太大也不能太小,否则会 影响训练的效率和稳定性。 下面介绍几种在神经网络中常用的激活函数。 3.1.1 Sigmoid型函数 Sigmoid型函数是指一类 S型曲线函数,为两端饱和函数。常用的 Sigmoid型函数有 Logistic函数和 Tanh函数。 52 1. Logistic函数 Logistic函数的定义为 σ(x)= 1 (3-3) 1+ exp(.x) Logistic函数可以看成是一个“挤压”函数,把一个实数域的输入“挤压”到 (0, 1)。 当输入值在 0附近时, Sigmoid型函数近似为线性函数;当输入值靠近两端时,对输入进 行抑制。输入越小,越接近于 0;输入越大,越接近于 1。这样的特点也和生物神经元类似, 对一些输入会产生兴奋(输出为 1),对另一些输入产生抑制(输出为 0)。和感知器使用的 阶跃激活函数相比,Logistic函数是连续可导的,其数学性质更好。 因为 Logistic函数的性质,使得装备了 Logistic激活函数的神经元具有如下两点性质。 (1)其输出直接可以看作概率分布,使神经网络可以更好地和统计学习模型进行结合。 (2)可以看作一个软性门(soft gate),用来控制其他神经元输出信息的数量。 2. Tanh函数 Tanh函数也是一种 Sigmoid型函数,其定义为 exp(x) . exp(.x) tanh(x)= (3-4) exp(x)+ exp(.x) Tanh函数可以看作放大并平移的 Logistic函数,其值域是 (.1, 1)。 tanh(x)=2σ(2x) . 1 (3-5) 图 3-2给出了 Logistic函数和 Tanh函数的形状。 Tanh函数的输出是零中心化的 (zero-centered),而 Logistic函数的输出恒大于 0。非零中心化的输出会使其后一层的神经 元的输入发生偏置偏移(bias shift),并进一步使得梯度下降的收敛速度变慢。 图 3-2 Logistic函数和 Tanh函数 53 3. Hard-Logistic函数和 Hard-Tanh函数 Logistic函数和 Tanh函数都是 Sigmoid型函数,具有饱和性,但是计算开销较大。因 为这两个函数都是在中间(0附近)近似线性,两端饱和。因此,这两个函数可以通过分段 函数来近似。 以 Logistic函数 σ(x)为例,其导数为 σ ′ (x)= σ(x)(1 . σ(x))。Logistic函数在 0附 近的一阶泰勒展开(Taylor expansion)为 gl(x) ≈ σ(0) + x × σ ′ (0) (3-6) =0.25x +0.5 这样 Logistic函数可以用分段函数 hard-logistic(x)来近似。 . . >> <1 gl(x) . 1 hard-logistic (x) = gl 0 < gl(x) < 1. >> :0 gl(x) . 0 (3-7) = max (min (gl(x), 1) , 0) = max(min(0.25x +0.5, 1), 0) 同样,Tanh函数在 0附近的一阶泰勒展开为 gt(x) ≈ tanh(0) + x × tanh′ (0) (3-8) = x Tanh函数也可以用分段函数 hard-tanh(x)来近似。 hard . tanh(x)= max (min (gt(x), 1) , .1) (3-9) = max(min(x, 1), .1) 图 3-3给出了 Hard-Logistic函数和 Hard-Tanh函数的形状。 图 3-3 Hard-Sigmoid型激活函数 54 3.1.2 ReLU函数 ReLU(Rectified Linear Unit,修正线性单元),也叫作 Rectifier函数,是目前深度神 经网络中经常使用的激活函数。ReLU实际上是一个斜坡(ramp)函数,定义为 xx . 0 ReLU(x)= 0 x< 0 (3-10) = max(0,x) ReLU函数的优点如下。 1 .采用 ReLU的神经元只需要进行加、乘和比较的操作,计 算上更加高效。 2,如单侧 . ReLU函数被认为具有生物学合理性( biological plausibility) 抑制、宽兴奋边界(即兴奋程度可以非常高)。在生物神经网络中,同时处于兴奋状态的神 8. . 1%4%Sigmoid经元非常稀疏。人脑中在同一时刻大概只有 的神经元处于活跃状态。 型~ 8. . 激活函数会导致一个非稀疏的神经网络,而 ReLU却具有很好的稀疏性,大约 50%的神 经元会处于激活状态。 3 .在优化方面,相比于 Sigmoid型函数的两端饱和,ReLU函数为 左饱和函数,且在 x> 0时导数为 1,在一定程度上缓解了神经网络的梯度消失问题,加 速梯度下降的收敛速度。 ReLU函数的缺点如下。 1 . ReLU函数的输出是非零中心化的,给后一层的神经网络 引入偏置偏移,会影响梯度下降的效率。 2。在训 . ReLU神经元在训练时比较容易“死亡” 练时,如果参数在一次不恰当的更新后,第一个隐藏层中的某个 ReLU神经元在所有的训 练数据上都不能被激活,那么这个神经元自身参数的梯度永远都是 0,在以后的训练过程 中永远不能被激活。这种现象称为死亡 ReLU问题( dying ReLU problem),并且有可能 会发生在其他隐藏层。 在实际使用中,为了避免上述缺点,有几种 ReLU的变种可能会被广泛使用。 1.带泄露的 ReLU 带泄露的 ReLU(leaky ReLU)在输入 x< 0时,保持一个很小的梯度 γ。当神经元 非激活时也能有一个非零的梯度可以更新参数,避免永远不能被激活。带泄露的 ReLU的 定义如下: x x> 0 LeakyReLU (x)= γx x . 0 (3-11) = max(0,x)+ γ min(0,x) 其中,γ是一个很小的常数,如 0.01。当 γ <1时,带泄露的 ReLU可以写为 LeakyReLU(x)= max(x, γx) (3-12) 这相当于一个比较简单的 maxout单元。 55 2.带参数的 ReLU 带参数的 ReLU(Parametric ReLU,PReLU)引入一个可学习的参数,不同神经元可 以有不同的参数。对于第 i个神经元,其 ( PReLU的定义为 x x> 0 PReLUi(x)= γixx . 0 (3-13) = max(0,x)+ γi min(0,x) 其中,γ为 x . 0时函数的斜率。因此, PReLU是非饱和函数。如果 γ =0,那么 PReLU 就退化为 ReLU。如果 γ为一个很小的常数,则 PReLU可以看作带泄露的 ReLU。PReLU 可以允许不同神经元具有不同的参数,也可以一组神经元共享一个参数。 3. ELU函数 ELU(Exponential Linear Unit,指数线性单元)是一个近似的零中心化的非线性函 数,其定义为 ( x x> 0 ELU(x)= γ(exp(x) . 1) x . 0 (3-14) = max(0,x)+ min(0,γ(exp(x) . 1)) 其中,γ . 0是一个超参数,决定 x . 0时的饱和曲线,并调整输出均值在 0附近。 4. Softplus函数 Softplus函数可以看作 Rectifier函数的平滑版本,其定义为 Softplus(x)= log(1 + exp(x)) (3-15) Softplus函数的导数恰好是 Logistic函数。 Softplus函数虽然也具有单侧抑制、宽兴 奋边界的特性,却没有稀疏激活性。 图 3-4给出了 ReLU、Leaky ReLU、ELU以及 Softplus函数的示例。 图 3-4 ReLU、Leaky ReLU、ELU以及 Softplus函数示例 56 3.1.3 Swish函数 Swish函数是一种自门控(self-gated)激活函数,定义为 swish(x)= xσ(βx) (3-16) 其中,σ(·)为 Logistic函数,β为可学习的参数或一个固定超参数。σ(·) ∈ (0, 1)可以看作 一种软性的门控机制。当 σ(βx)接近于 1时,门处于“开”状态,激活函数的输出近似于 x本身;当 σ(βx)接近于 0时,门的状态为“关”,激活函数的输出近似于 0。 图 3-5给出了 Swish函数的示例。当 β =0时,Swish函数变成线性函数 x/2。当 β =1时,Swish函数在 x> 0时近似线性,在 x< 0时近似饱和,同时具有一定的非单 调性。当 β → +∞时,σ(βx)趋向于离散的 0-1函数,Swish函数近似为 ReLU函数。因 此,Swish函数可以看作线性函数和 ReLU函数之间的非线性插值函数,其程度由参数 β 控制。 图 3-5 Swish函数示例 3.1.4 GELU函数 GELU(Gaussian Error Linear Unit,高斯误差线性单元)是一种通过门控机制来调 整其输出值的激活函数,和 Swish函数比较类似。 GELU(x)= xP (X . x) (3-17) 其中,P (X . x)是高斯分布 N (μ, σ2)的累积分布函数,μ, σ为超参数,一般设 μ =0,σ =1 即可。由于高斯分布的累积分布函数为 S型函数,因此 GELU函数可以用 Tanh函数或 Logistic函数来近似: r!! GELU(x) ≈ 0.5x1+ tanhπ2 ..x +0.044715x 3或 (3-18) GELU(x) ≈ xσ(1.702x) 当使用 Logistic函数近似时,GELU相当于一种特殊的 Swish函数。 57 3.1.5 Maxout单元 Maxout单元是一种分段线性函数。Sigmoid型函数、ReLU等激活函数的输入是神经 元的净输入 z,是一个标量。而 Maxout单元的输入是上一层神经元的全部原始输出,是 一个向量 x =[x1,x2, ··· ,xD]。 每个 Maxout单元有 K个权重向量 wk ∈ RD和偏置 bk(1 . k . K)。对于输入 x, 可以得到 K个净输入, 1 . k . K。 T zk = wk x + bk (3-19) 其中, wk =[wk,1,wk,2, ··· ,wk,D] T为第 k个权重向量。 Maxout单元的非线性函数定 义为 maxout(x)= max (zk) (3-20) Maxout单元不单是净输入到输出之间的非线性映射,而且是整体学习输入到输出之 间的非线性映射关系。 Maxout激活函数可以看作任意凸函数的分段线性近似,并且在有 限的点上是不可微的。 3.2网络结构 生物神经细胞的功能比较简单,而人工神经元只是生物神经细胞的理想化和简单实现, 功能更加简单。要想模拟人脑的能力,单一的神经元是远远不够的,需要通过很多神经元 一起协作来实现复杂的功能。这样通过一定的连接方式或信息传递方式进行协作的神经元 可以看作一个网络,就是神经网络。到目前为止,研究者已经发明了各种各样的神经网络 结构,常用的神经网络结构有如下 3种。 3.2.1前馈网络 前馈网络中各神经元按接收信息的先后分为不同的组,每一组可以看作一个神经层,每 一层中的神经元接收前一层神经元的输出,并输出到下一层神经元。整个网络中的信息是 朝一个方向传播,没有反向的信息传播,可以用一个有向无环路图表示。前馈网络包括全 连接前馈网络和卷积神经网络等。 前馈网络可以看作一个函数,通过简单、非线性函数的多次复合,实现输入空间到输 出空间的复杂映射。这种网络结构简单,易于实现。 3.2.2记忆网络 记忆网络,也称为反馈网络,网络中的神经元不但可以接收其他神经元的信息,也可 以接收自己的历史信息。和前馈网络相比,记忆网络中的神经元具有记忆功能,在不同的 时刻具有不同的状态。记忆神经网络中的信息传播可以是单向或双向传播,因此,可以用 58 一个有向循环图或无向图来表示。记忆网络包括循环神经网络、 Hopfield网络、玻尔兹曼 机、受限玻尔兹曼机等。 记忆网络可以看作一个程序,具有更强的计算和记忆能力。 为了增强记忆网络的记忆容量,可以引入外部记忆单元和读写机制,用来保存一些网 络的中间状态,称为记忆增强神经网络( Memory Augmented Neural Network,MANN), 如神经图灵机和记忆网络等。 3.2.3图网络 前馈网络和记忆网络的输入都可以表示为向量或向量序列。但实际应用中很多数据是 图结构的数据,如知识图谱、社交网络、分子( molecular)网络等。前馈网络和记忆网络 很难处理图结构的数据。 图网络是定义在图结构数据上的神经网络。图中每个节点都由一个或一组神经元构成。 节点之间的连接可以是有向的,也可以是无向的。每个节点可以收到来自相邻节点或自身 的信息。图网络是前馈网络和记忆网络的泛化,包含很多不同的实现方式,如图卷积网络 (Graph Convolutional Network,GCN)、图注意力网络( Graph Attention Network,GAT)、 消息传递神经网络(Message Passing Neural Network,MPNN)等。 图 3-6给出了前馈网络、记忆网络和图网络的网络结构示例,其中圆形节点表示一个 神经元,方形节点表示一组神经元。 图 3-6 3种不同的网络结构示例 3.3前馈神经网络 给定一组神经元,就可以将神经元作为节点来构建一个网络。不同的神经网络模型有 着不同网络连接的拓扑结构。一种比较直接的拓扑结构是前馈网络。前馈神经网络( Feed- forward Neural Network,FNN)是最早发明的简单人工神经网络。前馈神经网络经常被 称为多层感知器( Multi-Layer Perceptron,MLP)。但多层感知器的叫法并不是十分合理, 因为前馈神经网络其实是由多层的 Logistic回归模型(连续的非线性函数)组成,而不是 由多层的感知器(不连续的非线性函数)组成。 在前馈神经网络中,各神经元分别属于不同的层。每一层的神经元可以接收前一层神 59 经元的信号,并产生信号输出到下一层。第 0层称为输入层,最后一层称为输出层,其他 中间层称为隐藏层。整个网络中无反馈,信号从输入层向输出层单向传播,可用一个有向 无环图表示。 图 3-7给出了多层前馈神经网络的示例。 图 3-7多层前馈神经网络 表 3-1给出了描述前馈神经网络的记号。 表 3-1前馈神经网络的记号 记号含义 L神经网络的层数 Ml第 l层神经元的个数 fl(·)第 l层神经元的激活函数 W (l) ∈ RMl×Ml.1第 l-1层到第 l层的权重矩阵 b(l) ∈ RMl第 l-1层到第 l层的偏置 z(l) ∈ RMl第 l层神经元的净输入(净活性值) a(l) ∈ RMl第 l层神经元的输出(活性值) 令 a(0) = x,前馈神经网络通过不断迭代下面的公式进行信息传播: (l)(l.1) z= W (l)a+ b(l) (3-21) .. (l)(l) a= flz(3-22) 首先根据第 l.1层神经元的活性值( activation)a(l.1)计算出第 l层神经元的净活性 值( net activation)z(l),然后经过一个激活函数得到第 l层神经元的活性值。因此,可以 把每个神经层看作一个仿射变换(affine transformation)和一个非线性变换。 式 (3-21)和式 (3-22)可以合并写为 .. (l) = W (l)(l.1)+ b(l) zfl.1z(3-23) 或者 (l) W (l)(l.1) + b(l) a= fla(3-24) 60 这样,前馈神经网络可以通过逐层的信息传递,得到网络最后的输出 a(L)。整个网络 可以看作一个复合函数 .(x; W ,b),将向量 x作为第 1层的输入 a(0),将第 L层的输出 a(L)作为整个函数的输出。 (0) → z(1) → a(1) → z(L.1) → z(L) → a(L) x = a(2) → · ·· → a= .(x; W ,b) (3-25) 其中,W ,b表示网络中所有层的连接权重和偏置。 3.3.1通用近似定理 前馈神经网络具有很强的拟合能力,常见的连续非线性函数都可以用前馈神经网络来 近似。 定理 3.1通用近似定理( Universal Approximation Theorem):令 .(·)是一个 非常数、有界、单调递增的连续函数, JD是一个 D维的单位超立方体 [0, 1]D,C (JD)是 定义在 JD上的连续函数集合。对于任意给定的一个函数 f ∈ C (JD),存在一个整数 M, 和一组实数 Vm, bm ∈ R以及实数向量 wm ∈ RD,m =1, 2, ··· ,M,可以定义函数 M F (x)= . vm...w T x + bm(3-26) m m=1 作为函数 f的近似实现,即 |F (x) . f(x)| < ., .x ∈JD (3-27) 其中,.> 0是一个很小的正数。 通用近似定理在实数空间 RD中的有界闭集上依然成立。 根据通用近似定理,对于具有线性输出层和至少一个使用“挤压”性质的激活函数的 隐藏层组成的前馈神经网络,只要其隐藏层神经元的数量足够,它可以以任意精度来近似 任何一个定义在实数空间 RD中的有界闭集函数。所谓“挤压”性质的函数是指像 Sigmoid 函数的有界函数,但神经网络的通用近似性质被证明对于其他类型的激活函数 (如 ReLU) 也是适用的。 通用近似定理只是说明了神经网络的计算能力可以去近似一个给定的连续函数,但并 没有给出如何找到这样一个网络,以及是否是最优的。此外,当应用到机器学习时,真实 的映射函数并不知道,一般是通过经验风险最小化和正则化来进行参数学习。因为神经网 络的强大能力,反而容易在训练集上过拟合。 3.3.2应用到机器学习 根据通用近似定理,神经网络在某种程度上可以作为一个“万能”函数来使用,可以 用来进行复杂的特征转换,或逼近一个复杂的条件分布。 在机器学习中,输入样本的特征对分类器的影响很大。以监督学习为例,好的特征可 以极大提高分类器的性能。因此,要取得好的分类效果,需要将样本的原始特征向量 x转 换到更有效的特征向量 .(x),这个过程叫作特征抽取。 多层前馈神经网络可以看作一个非线性复合函数 . : RD → RD ′,将输入 x ∈ RD映射 到输出 .(x) ∈ RD ′。因此,多层前馈神经网络可以看成是一种特征转换方法,其输出 .(x) 作为分类器的输入进行分类。 给定一个训练样本 (x),先利用多层前馈神经网络将 x映射到 .(x),然后再将 .(x) 输入到分类器 g(·),即 y.= g(.(x); θ) (3-28) 其中, g(·)为线性或非线性的分类器, θ为分类器 g(·)的参数, y.为分类器的输出。特别 地,如果分类器 g(·)为 Logistic回归分类器或 Softmax回归分类器,那么 g(·)可以看成 是网络的最后一层,即神经网络直接输出不同类别的条件概率 p(y|x)。 对于二分类问题 y ∈{0, 1},若采用 Logistic回归,那么 Logistic回归分类器可以看 成神经网络的最后一层。也就是说,网络的最后一层只用一个神经元,并且其激活函数为 Logistic函数。网络的输出可以直接作为类别 y =1的条件概率,即 p(y =1|x)= a(L) (3-29) 其中,a(L) ∈ R为第 L层神经元的活性值。 对于多分类问题 y ∈{1, 2, ··· ,C},如果使用 Softmax回归分类器,相当于网络最后 一层设置 C个神经元,其激活函数为 Softmax函数。网络最后一层(第 L层)的输出可 以作为每个类的条件概率,即 .. y.= softmaxz(L)(3-30) 其中, z(L) ∈ RC为第 L层神经元的净输入; y.∈ RC为第 L层神经元的活性值,每一维 分别表示不同类别标签的预测条件概率。 3.3.3参数学习 如果采用交叉熵损失函数,对于样本 (x,y),其损失函数为 L(y, y.) = .y T log y.(3-31) .. N给定训练集为 D =x(n),y(n) n=1,将每个样本 x(n)输入给前馈神经网络,得到网 络输出为 y.(n),其在数据集 D上的结构化风险函数为 X 1 N..1 (n)(n) R(W , b)= Ly,y.+ λ∥W ∥2 (3-32) N 2 F n=1 其中, W和 b分别表示网络中所有的权重矩阵和偏置向量; ∥W ∥2 是正则化项,用来防 F 止过拟合;λ> 0为超参数。λ越大,W越接近于 0。这里的 ∥W ∥2 一般使用 Frobenius F 范数: LMlMl.12 X. . ∥W ∥2 = w(l) (3-33) F ij l=1 i=1 j=1 62 有了学习准则和训练样本,网络参数可以通过梯度下降法来进行学习。在梯度下降法 的每次迭代中,第 l层的参数 W (l)和 b(l)参数更新方式为 .R(W , b) W (l) ← W (l) . α .W (l) !! N.. (n)(n) 1 X .Ly,y. = W (l) . α+ λW (l) N.W (l) n=1(3-34) .R(W , b) b(l) ← b(l) . α .b(l) N..! (n)(n) 1 X .Ly,y. = b(l) . α N.b(l) n=1 其中,α为学习率。 梯度下降法需要计算损失函数对参数的偏导数,通过链式法则逐一对每个参数进行求 偏导比较低效,在神经网络的训练中经常使用反向传播算法来高效地计算梯度。 3.4反向传播算法 假设采用随机梯度下降进行神经网络参数学习,给定一个样本 (x, y),将其输入神经 网络模型中,得到网络输出为 y.。假设损失函数为 L(y, y.),要进行参数学习就需要计算损 失函数关于每个参数的导数。 对第 l层中的参数 W (l)和 b(l)计算偏导数。因为 .L(y, y.) 的计算涉及向量对矩阵的 .W (l) 微分,十分烦琐,因此先计算 L(y, y.)关于参数矩阵中每个元素的偏导数 .L(y( , l) y.) 。根据 .w ij 链式法则: .L(y, y.) .z(l) .L(y, y.) = (3-35) (l)(l)(l) .z .w.w ij ij .L(y, y.) .z(l) .L(y, y.) = (3-36) .b(l) .b(l) .z(l) 式 (3-35)和式 (3-36)中的第二项都是目标函数关于第 l层的神经元 z(l)的偏导数, (l)(l) 称为误差项,可以一次计算得到。这样只需要计算 3个偏导数,分别为 .z(l) , . . zb(l) 和 .w ij .L. ( zy( , l) y.) 。 下面分别计算这 3个偏导数。 (l) (1)计算偏导数 .z(l) 。 .w ij 63 因为 z(l) = W (l)a(l.1) + b(l),偏导数 "#.z(l) .w(l) ij = .z(l) 1 .w(l) ij , · · · , .z(l) i .w(l) ij , · · · , .z(l) Ml .w(l) ij 23=40, · · · , .w(l) i: a(l.1) + b(l) i.w(l) ij , · · · , 05(3-37) hi=0, · · · , a(l.1) j , · · · , 0 . Lia(l.1) j∈ R1×Ml 其中,wi( : l) 为权重矩阵 W (l)的第 i行,Liaj(l.1) 表示第 i个元素为 aj(l.1),其余为 0的 行向量。 (l) (2)计算偏导数 . . zb(l) 。 因为 z(l)和 b(l)的函数关系为 z(l) = W (l)a(l.1) + b(l),因此偏导数 (l).z= IMl ∈ RMl×Ml (3-38) .b(l) 为 Ml × Ml的单位矩阵。 (3)计算偏导数 .L. ( zy( , l) y.) 。 偏导数 .L. ( zy( , l) y.) 表示第 l层神经元对最终损失的影响,也反映了最终损失对第 l层 神经元的敏感程度,因此一般称为第 l层神经元的误差项,用 δ(l)来表示。 .L(y, y.) δ(l) . (l) ∈ RMl (3-39) .z 误差项 δ(l)也间接反映了不同神经元对网络能力的贡献程度,从而较好地解决了贡献度分 配问题(Credit Assignment Problem,CAP)。 根据 z(l+1) = W (l+1)a(l) + b(l+1),有 (l+1) T W (l+1)∈ RMl×Ml+1 .z=(3-40) .a(l) 根据 a(l) = fl..z(l),其中 fl(·)为按位计算的函数,因此有 .. (l)(l) .a.flz = .z(l) .z(l) (3-41) .... ′ (l) = diagflz∈ RMl×Ml 64 因此,根据链式法则,第 l层的误差项为 .L(y, y.) δ(l) . (l) .z (l)(l+1) (l+1) .a.z.L(y, y.).z = ·· (l)(l)(l+1) .z.a.z . = diag..fl′ ..z(l)W (l+1)T · δ(l+1) (3-42) = fl′ ..z(l)叫 ⊙W (l+1)T δ(l+1)∈ RMl 其中,⊙是向量的点积运算符,表示每个元素相乘。 从式 (3-42)可以看出,第 l层的误差项可以通过第 l +1层的误差项计算得到,这就 是误差的反向传播。反向传播算法的含义:第 l层的一个神经元的误差项(或敏感性)是 所有与该神经元相连的第 l +1层的神经元的误差项的权重和。然后,再乘以该神经元激 活函数的梯度。 在计算出上面 3个偏导数之后,式 (3-35)可以写为 .L(y, y.) (l.1) = Liaδ(l) (l) j .w ij h(l.1) ih(l)(l)(l) iT (3-43) =0, ··· , a, ··· , 0δ, ··· , δ, ··· , δ j 1 iMl (l)(l.1) = δa ij 其中, δ( il)a( jl.1) 相当于向量 δ(l)和向量 a(l.1)的外积的第 i, j个元素。式 (3-43)可以进 一步写为 hi .L(y, y.) δ(l)(l.1) =..aT(3-44) .W (l) ij ij 因此,L(y, y.)关于第 l层权重 W (l)的梯度为 .L(y, y.) = δ(l)..a(l.1)T ∈ RMl×Ml.1 (3-45) .W (l) 同理,L(y, y.)关于第 l层偏置 b(l)的梯度为 .L(y, y.) = δ(l) ∈ RMl (3-46) .b(l) 在计算出每一层的误差项之后,就可以得到每一层参数的梯度。因此,使用误差反向 传播算法的前馈神经网络训练过程可以分为如下 3步。 (1)前馈计算每一层的净输入 z(l)和激活值 a(l),直到最后一层。 (2)反向传播计算每一层的误差项 δ(l)。 (3)计算每一层参数的偏导数,并更新参数。 图 3-8给出采用反向传播算法的随机梯度下降训练过程。 65 图 3-8采用反向传播算法的随机梯度下降训练过程 3.5自动梯度计算 神经网络的参数主要通过梯度下降来进行优化。当确定了风险函数以及网络结构后,就 可以手动用链式法则来计算风险函数对每个参数的梯度,并用代码进行实现。但是手动求 导并转换为计算机程序的过程非常琐碎并容易出错,导致实现神经网络变得十分低效。实 际上,参数的梯度可以让计算机自动计算。目前,主流的深度学习框架都包含了自动梯度 计算的功能,即可以只考虑网络结构并用代码实现,其梯度可以自动进行计算,无须人工 干预,这样可以大幅提高开发效率。 自动梯度计算的方法可以分为以下 3类:数值微分、符号微分和自动微分。 3.5.1数值微分 数值微分( numerical differentiation)是用数值方法来计算函数 f(x)的导数。函数 f(x)的点 x的导数定义为 f(x +Δx) . f(x) f ′ (x)= lim (3-47) Δx→0 Δx 要计算函数 f(x)在点 x的导数,可以对 x加上一个很小的非零的扰动 Δx,通过上 述定义来直接计算函数 f(x)的梯度。数值微分方法非常容易实现,但找到一个合适的扰动 Δx却十分困难。如果 Δx过小,会引起数值计算问题,如舍入误差;如果 Δx过大,会 增加截断误差,使得导数计算不准确。因此,数值微分的实用性比较差。 66 在实际应用中,经常使用式 (3-48)来计算梯度,可以减少截断误差。 f(x +Δx) . f(x . Δx) f ′ (x)= lim (3-48) Δx→0 2Δx 数值微分的另外一个问题是计算复杂度。假设参数数量为 N,则每个参数都需要单独 施加扰动,并计算梯度。假设每次正向传播的计算复杂度为 O(N),则计算数值微分的总 体时间复杂度为 O(N2)。 3.5.2符号微分 符号微分( symbolic differentiation)是一种基于符号计算的自动求导方法。符号计 算也叫作代数计算,是指用计算机来处理带有变量的数学表达式。这里的变量被看作符号 (symbols),一般不需要代入具体的值。符号计算的输入和输出都是数学表达式,一般包括 对数学表达式的化简、因式分解、微分、积分、解代数方程、求解常微分方程等运算。如 数学表达式的化简: 输入 :3x . x +2x +1 输出 :4x +1 (3-49) 符号计算一般来讲是对输入的表达式,通过迭代或递归使用一些事先定义的规则进行 转换。当转换结果不能再继续使用变换规则时,便停止计算。 符号微分可以在编译时就计算梯度的数学表示,并进一步利用符号计算方法进行优化。 此外,符号计算的一个优点是符号计算和平台无关,可以在 CPU或 GPU上运行。符号微 分的不足之处如下。 (1)编译时间较长,特别是对于循环,需要很长时间进行编译。 (2)为了进行符号微分,一般需要设计一种专门的语言来表示数学表达式,并且要对 变量(符号)进行预先声明。 (3)很难对程序进行调试。 3.5.3自动微分 自动微分( Automatic Differentiation,AD)是一种可以对一个(程序)函数进行计算 导数的方法。符号微分的处理对象是数学表达式,而自动微分的处理对象是一个函数或一 段程序。 自动微分的基本原理是所有的数值计算可以分解为一些基本操作,包含 +、.、×、/ 和一些初等函数 exp、log、sin、cos等,然后利用链式法则自动计算一个复合函数的梯度。 为简单起见,这里以一个神经网络中常见的复合函数的例子来说明自动微分的过程。 令复合函数 f(x; w, b)为 f(x; w, b)= 1 (3-50) exp(.(wx + b)) + 1 其中,x为输入标量,w和 b分别为权重和偏置参数。 67 首先,可以将复合函数 f(x; w, b)分解为一系列的基本操作,并构成一个计算图( computational graph)。计算图是数学运算的图形化表示。计算图中的每个非叶节点表示一个 基本操作,每个叶节点为一个输入变量或常量。图 3-9给出了当 x =1, w =0, b =0时复 合函数 f(x; w, b)的计算图,其中连边上的红色数字表示前向计算时复合函数中每个变量 的实际取值。 图 3-9复合函数 f(x; w, b)的计算图 从图 3-9上可以看出,复合函数 f(x; w, b)由 6个基本函数 hi(1 . i . 6)组成。如表 3-2 所示,每个基本函数的导数都十分简单,可以通过规则来实现。 表 3-2复合函数 f(x; w, b)的 6个基本函数及其导数 函数导数偏导数 h1 = x × w .h1 .w = x .h1 .x = w h2 = h1 + b .h2 .h1 = 1 .h2 .b = 1 h3 = h2 × (.1) .h3 .h2 = .1 h4 = exp (h3) .h4 .h3 = exp (h3) h5 = h4 + 1 .h5 .h4 = 1 h6 = 1/h5 .h6 .h5 = . 1 h2 5 整个复合函数 f(x; w, b)关于参数 w和 b的导数可以通过计算图上的节点 f(x; w, b) 与参数 w和 b之间路径上所有的导数连乘来得到,即 .f(x; w, b) .f(x; w, b) .h6 .h5 .h4 .h3 .h2 .h1 = (3-51) .w .h6 .h5 .h4 .h3 .h2 .h1 .w .f(x; w, b) .f(x; w, b) .h6 .h5 .h4 .h3 .h2 = (3-52) .b .h6 .h5 .h4 .h3 .h2 .b .f(x; w, b) 以 .w 为例,当 x =1, w =0, b =0时,可以得到 68 .f(x; w, b) .f(x; w, b) .h6 .h5 .h4 .h3 .h2 .h1 = .wx=1,w=0,b=0 .h6 .h5 .h4 .h3 .h2 .h1 .w (3-53) =1 × (.0.25) × 1 × 1 × (.1) × 1 × 1 =0.25 如果函数和参数之间有多条路径,可以将这多条路径上的导数再进行相加,得到最终 的梯度。 按照计算导数的顺序,自动微分可以分为两种模式:前向模式和反向模式。 1.前向模式 前向模式是按计算图中计算方向的相同方向来递归地计算梯度。以 当 x =1, w =0, b =0时,前向模式的累积计算顺序如下: .h1 = x =1 .w .h2 .h2 .h1 = .w .h1 .w .h3 .h3 .h2 = .w .h2 .w .h4 .h4 .h3 = .w .h3 .w .h5 .h5 .h4 = .w .h4 .w .h6 .h6 .h5 = .w .h5 .w =1 × 1=1 = .1 × 1 =1 × (.1) =1 × (.1) = .0.25 × (.1) = 0.25 .f(x; w, b) = .f(x; w, b) .h6 = 1 × 0.25 = 0.25 .w .h6 .w 2.反向模式 反向模式是按计算图中计算方向的相反方向来递归地计算梯度。以 当 x =1, w =0, b =0时,反向模式的累积计算顺序如下: .f(x; w, b) .h6 .f(x; w, b) .h5 .f(x; w, b) .h4 .f(x; w, b) .h3 .f(x; w, b) .h2 =1 .f(x; w, b) = .h6 .f(x; w, b) = .h5 .f(x; w, b) = .h4 .f(x; w, b) = .h3 .h6 .h5 .h5 .h4 .h4 .h3 .h3 .h2 =1 × (.0.25) = .0.25 = .0.25 × 1= .0.25 = .0.25 × 1= .0.25 = .0.25 × (.1) = 0.25 .f(x; w, b) 为例, .w (3-54) (3-55) (3-56) (3-57) (3-58) (3-59) (3-60) .f(x; w, b) 为例, .w (3-61) (3-62) (3-63) (3-64) (3-65) 69 .f(x; w, b) .f(x; w, b) .h2 = =0.25 × 1=0.25 (3-66) .h1 .h2 .h1 .f(x; w, b) .f(x; w, b) .h1 = =0.25 × 1=0.25 (3-67) .w .h1 .w 前向模式和反向模式可以看作应用链式法则的两种梯度累积方式。从反向模式的计算 顺序可以看出,反向模式和反向传播的计算梯度的方式相同。 对于一般的函数形式 f : RN → RM,前向模式需要对每一个输入变量都进行一次遍历, 共需要 N次。而反向模式需要对每一个输出都进行一次遍历,共需要 M次。当 N >M 时,反向模式更高效。在前馈神经网络的参数学习中,风险函数为 f : RN → RM,输出为 标量,因此采用反向模式为最有效的计算方式,只需要一次计算。 3.静态计算图和动态计算图 计算图按构建方式可以分为静态计算图( static computational graph)和动态计算图 (dynamic computational graph)。静态计算图是在编译时构建计算图,计算图构建好之后 在程序运行时不能改变,而动态计算图是在程序运行时动态构建。两种构建方式各有优缺 点。静态计算图在构建时可以进行优化,并行能力强,但灵活性比较差。动态计算图则不 容易优化,当不同输入的网络结构不一致时,难以并行计算,但是灵活性比较高。 4.符号微分和自动微分 符号微分和自动微分都利用计算图和链式法则自动求解导数。符号微分在编译阶段先 构造一个复合函数的计算图,通过符号计算得到导数的表达式,还可以对导数表达式进行 优化,在程序运行阶段才代入变量的具体数值来计算导数。而自动微分则无须事先编译,在 程序运行阶段边计算边记录计算图,计算图上的局部梯度都直接代入数值进行计算,然后 用前向或反向模式来计算最终的梯度。 图 3-10给出了符号微分与自动微分的对比。 图 3-10符号微分与自动微分的对比 3.6优化问题 神经网络的参数学习比线性模型更加困难,主要原因有两点:非凸优化问题和梯度消 失问题。 70