多层感知机(Multilayer Perceptron, MLP)是最简单的深度网络。本文回顾多层感知机的相关内容及一些基本概念术语。
多层感知机是对线性回归的拓展和修正,可以看做是多层线性回归。因为线性回归中一般采用类似Softmax回归的模型结构,Softmax操作将输入直接映射到输出,虽然其本身非线性,但其仿射变换后输入输出为线性对应关系,即隐藏一个假设:输入输出之间具有单调线性关系,即特征的增大一定会导致模型输出的单调增大或减小。然而实际情况中,输入输出显然不一定具有单调性,而且特征之间相互会有影响,因此线性回归具有一定局限性。因此,我们引入深度神经网络。
以输入、隐藏、输出三层感知机为例,由上节可知,多层感知机是为了克服线性回归的局限性而引入的。线性回归之所以会存在局限的原因是特征之间会有影响。因此我们可以在输入和输出之间虚拟一层作为”二次输入“(隐藏层)。隐藏层的值由输入层决定,通过线性回归的特性可知,隐藏层受输入层中的特征影响,而对于输出层,隐藏层又可以看做是新的输入层,是考虑了输入层特征之间影响而得到的输入层,因此,通过隐藏层的加入,三层感知机可以弥补单层线性回归的局限性。因为层与层间输入输出关系类似于人体交错纵横的神经元网络,所以称为神经网络。
需要注意的是,为了考虑所有特征之间的相互影响,最理想情况是每一层都考虑上一层之间所有特征之间相互影响的可能,即层与层之间为全连接结构。然而根据计算复杂度理论可知,全连接的神经网络的复杂度非常非常高,因此在实际使用中,存在实用性与有效性之间的权衡。
本节从数据角度推导如何建立多层感知机。用矩阵 X ∈ R n × d \mathbf{X} \in \mathbb{R}^{n \times d} X∈Rn×d表示 n n n个样本的小批量,其中每个样本都有 d d d个输入特征。为简单起见,此处推导单隐藏层的多层感知机,记其隐藏单元个数为 h h h, H ∈ R n × h \mathbf{H} \in \mathbb{R}^{n \times h} H∈Rn×h表示隐藏层的输出,称为隐藏表示(hidden representation)、隐藏层变量(hidden-layer variable)或者隐藏变量(hidden variable)。因为隐藏层和输出层都是全连接,所以有隐藏层权重 W ( 1 ) ∈ R n × h \mathbf{W^{(1)}} \in \mathbb{R^{n \times h}} W(1)∈Rn×h 和隐藏层偏置 b ( 1 ) ∈ R 1 × h \mathbf{b^{(1)}} \in \mathbb{R^{1 \times h}} b(1)∈R1×h以及输出层权重 W ( 2 ) ∈ R h × q \mathbf{W^{(2)}} \in \mathbb{R^{h \times q}} W(2)∈Rh×q和输出层偏置 b ( 2 ) ∈ R 1 × q \mathbf{b^{(2)}} \in \mathbb{R^{1\times q}} b(2)∈R1×q。
此时,可以计算出输出层的输出 O ∈ R n × q \mathbf{O} \in \mathbb{R^{n\times q}} O∈Rn×q为
H = X W ( 1 ) + b ( 1 ) O = H W ( 2 ) + b ( 2 ) \mathbf{H} = \mathbf{X}\mathbf{W^{(1)}} + \mathbf{b^{(1)}}\\ \mathbf{O} = \mathbf{H}\mathbf{W^{(2)}} + \mathbf{b^{(2)}} H=XW(1)+b(1)O=HW(2)+b(2)
接下来证明通过上式得到的输出与直接进行仿射变换得到的输出相等。联立以上两式,消掉隐藏层输出后可得
O = ( X W ( 1 ) + b ( 1 ) ) W ( 2 ) + b ( 2 ) = X W ( 1 ) W ( 2 ) + b ( 1 ) W ( 2 ) + b ( 2 ) = X W + b \begin{aligned} \mathbf{O} &= (\mathbf{X}\mathbf{W^{(1)}} + \mathbf{b^{(1)}})\mathbf{W^{(2)}} + \mathbf{b^{(2)}}\\ &= \mathbf{X}\mathbf{W^{(1)}}\mathbf{W^{(2)}}+\mathbf{b^{(1)}}\mathbf{W^{(2)}}+\mathbf{b^{(2)}} \\ &= \mathbf{X}\mathbf{W} + \mathbf{b} \end{aligned} O=(XW(1)+b(1))W(2)+b(2)=XW(1)W(2)+b(1)W(2)+b(2)=XW+b
通过以上证明可以,添加隐藏之后,模型的输入输出与线性回归相同,仍然遵循仿射变换关系!即添加的隐藏层没有任何作用!因此我们需要对隐藏层的输出进行处理,使其不再满足上式中的变换关系,我们采用的处理手段为激活函数(activation function),在隐藏层仿射变换后,对每个隐藏单元应用激活函数进行处理:
H = σ ( X W ( 1 ) + b ( 1 ) ) O = H W ( 2 ) + b ( 2 ) \mathbf{H} = \sigma( \mathbf{X}\mathbf{W^{(1)}} + \mathbf{b^{(1)}} )\\ \mathbf{O} = \mathbf{H}\mathbf{W^{(2)}} + \mathbf{b^{(2)}} H=σ(XW(1)+b(1))O=HW(2)+b(2)
处理后的输出称为活性值(activations)。经过激活函数处理后,因为激活函数一般不满足仿射变换,所以处理后的多层感知机模型整体不再满足仿射变换关系。因为 X \mathbf{X} X中的每一行对应一个样本,因此激活函数也按照行的方式作用于输入。
为了提升多层感知机的能力,可以继续堆叠这样的隐藏层,通过与上述过程类似的处理,可以产生效果更好的模型。
通过上节的证明可以发现,多层感知机区别于线性回归的仿射变换的关键在于激活函数,激活函数一般是非线性的,通过计算加权和加上偏置来确定该神经元是否被激活,他可以将上一层的输入转换为可微分的输出,下面介绍常见的激活函数。
ReLu是修正线性单元(Rectified linear unit,ReLu)的简称。对于任一给定元素 x x x,ReLU函数为该元素与0的最大值,即函数可表示为
R e L U = m a x ( x , 0 ) \mathbf{ReLU} = max(x,0) ReLU=max(x,0)
直观上看,ReLU函数将所有负元素的活性值设为0,从而将仿射变换变为非线性变换。而其导数对于负元素为0,正元素为1,即要么让特征保留,要么让特征消失,可以解决神经网络的梯度消失问题。
sigmoid函数的定义为对于任一定义域在 R \mathbb{R} R的输入,可以将其变换为区间 ( 0 , 1 ) (0,1) (0,1)之间的输出,因此sigmoid函数通常被称为挤压函数(squashing function)(将任意输入挤压到(0,1)之间)。
s i g m o i d ( x ) = 1 1 + exp ( − x ) sigmoid(x) = \frac{1}{1+\exp (-x)} sigmoid(x)=1+exp(−x)1
从上式可看出,sigmoid的优点是平滑可微,然而其复杂度较高,因此常被用作输出单元的激活(隐藏层的激活用ReLu函数)。sigmoid函数的导数为
d d x s i g m o i d ( x ) = e x p ( − x ) ( 1 + e x p ( − x ) ) 2 = s i g m o i d ( x ) ( 1 − s i g m o i d ( x ) ) \frac{d}{dx}sigmoid(x) = \frac{exp(-x)}{(1+exp(-x))^2}=sigmoid(x)(1-sigmoid(x)) dxdsigmoid(x)=(1+exp(−x))2exp(−x)=sigmoid(x)(1−sigmoid(x))
从导数可以看出,当 x → 0 − x\rightarrow0^- x→0−或 x → 0 + x\rightarrow0^+ x→0+时,导数值趋近于0.25, x → + ∞ x\rightarrow+\infty x→+∞或 x → − ∞ x\rightarrow-\infty x→−∞时,导数值趋向于0。通过画sigmoid函数的曲线图或者求二阶导数可以看出,函数在0附近接近线性0。
tanh(双曲正切)函数与sigmoid函数类似,也是将输入压缩到 ( − 1 , 1 ) (-1,1) (−1,1)之间,不同的是,sigmoid函数关于原点中心对称。
tanh ( x ) = 1 − exp ( − 2 x ) 1 + exp ( − 2 x ) \tanh (x)=\frac{1-\exp (-2 x)}{1+\exp (-2 x)} tanh(x)=1+exp(−2x)1−exp(−2x)
其导数为
d d x tanh ( x ) = 1 − tanh 2 ( x ) \frac{d}{d x} \tanh (x)=1-\tanh ^{2}(x) dxdtanh(x)=1−tanh2(x)
在训练过程中,过拟合是非常常见的现象,可以通过采用更多的训练数据来缓解过拟合,当数据数目难以增加时,可以采用正则化方法缓解过拟合,比如权重衰减。
权重衰减(weight decay)也被称为 L 2 L_2 L2正则化,通过函数与零的距离来衡量函数的复杂度。函数与零的距离可以采用范数来度量。对于线性函数 f ( x ) = w T x f(\mathbf{x}) = \mathbf{w}^T\mathbf{x} f(x)=wTx,可以采用其权重向量的范数来度量其与零的距离,即采用权重向量的范数可以度量函数复杂性,例如$\left | \mathbf{w} \right |^2 $。训练过程中,降低函数的复杂性,也就是要减小权重向量的范数,可以考虑将范数作为惩罚项加入到损失函数中,即原来的训练目标为最小化预测损失,现在改为最小化预测损失和惩罚项之和。
已有的线性函数的损失函数为:
L ( w , b ) = 1 n ∑ i = 1 n 1 2 ( w T x ( i ) + b − y ( i ) ) 2 L(\mathbf{w},b) = \frac{1}{n}\sum_{i=1}^{n}\frac{1}{2}(\mathbf{w}^T\mathbf{x}^{(i)}+b-y^{(i)})^2 L(w,b)=n1i=1∑n21(wTx(i)+b−y(i))2
式中, x ( i ) \mathbf{x}^{(i)} x(i)表示样本 i i i的特征, y ( i ) y^{(i)} y(i)表示样本 i i i的标签, ( w , b ) (\mathbf{w},b) (w,b)是权重和偏置参数。调整后,需要将权重向量的范数加入到损失函数中,具体如何添加来保持预测损失和权重向量范数的平衡未知,所以用常数 λ \lambda λ来描述添加后的范数。为了消去求导后的常数系数,所以常数采用 λ 2 \frac{\lambda}{2} 2λ的形式。同样地,为了便于计算,采用平方范数进行度量而不是标准范数。易知, λ 2 \frac{\lambda}{2} 2λ还是 λ \lambda λ,采用平方范数还是标准范数对损失函数没有影响。添加后的损失函数为
L ( w , b ) = 1 n ∑ i = 1 n 1 2 ( w T x ( i ) + b − y ( i ) ) 2 + λ 2 ∥ w ∥ 2 L(\mathbf{w},b) = \frac{1}{n}\sum_{i=1}^{n}\frac{1}{2}(\mathbf{w}^T\mathbf{x}^{(i)}+b-y^{(i)})^2+\frac{\lambda}{2}\left\|\mathbf{w}\right\|^2 L(w,b)=n1i=1∑n21(wTx(i)+b−y(i))2+2λ∥w∥2
当 λ \lambda λ等于0时,损失函数没有变化。当 λ > 0 \lambda > 0 λ>0时,可以对范数起到权衡作用。此外,选择 L 2 L_2 L2范数而不是 L 1 L_1 L1范数的原因是, L 2 L_2 L2范数对权重向量的大分量施加了巨大的惩罚,这使得训练过程中偏向于大量特征上均匀分布权重的模型,相比之下, L 1 L_1 L1范数会将权重集中于一小部分特征,将其他特征清除为0,因此适合于特征选择等场景。
训练模型的目的是为了让模型能在未知的数据上获得较好的表现,即良好的泛化性。统计学中的泛化理论认为,为了模型在训练集和测试集上的性能差距,应该使模型尽可能简单。通过上节的讨论可知,模型的简单性可以通过范数来衡量,它是模型简单性的一种度量,模型的简单性还可以从其他角度度量,比如模型的平滑性,即模型不应对输入的微小变化敏感,如果给训练数据中添加随机噪声,对模型效果的影响应该是有限的。因此,可以考虑在训练有多层的深层网络时,向每一层注入噪声以增强输入输出映射上的平滑性。这种方法被称为暂退法(drop out)。
顾名思义,暂退法是在训练过程中做舍弃(drop out),在整个训练过程的每一次迭代中,将当前层中的一些节点置0。问题的关键在于如何添加这种随机噪声,噪声应满足何种特性。目前常用的一种噪声注入方式是以一种无偏向(unbiased)的方式注入噪声,即噪声满足均值为0的正态分布。这样在固定其他层时,每一层的期望等于不添加噪声的值。对于输入 x \mathbf{x} x,在添加服从 ϵ ∼ N ( 0 , σ 2 ) \epsilon \sim \mathcal{N}\left(0, \sigma^{2}\right) ϵ∼N(0,σ2)的正态分布采样噪声后,产生扰动点 x ′ = x + ϵ \mathbf{x'}=\mathbf{x}+\epsilon x′=x+ϵ,扰动点的期望为 E [ x ′ ] = e [ x ] E[\mathbf{x'}] = e[\mathbf{x}] E[x′]=e[x]。
采用暂退法之后,如果要进行正则化,可以通过按照保留节点的分数进行规范化来进行。即,中间层的活性值 h h h以暂退概率 p p p替换为 h ′ h' h′。
h ′ = { 0 概率为 p h 1 − p 其他情况 h^{\prime}=\left\{\begin{array}{ll} 0 & \text { 概率为 } p \\ \frac{h}{1-p} & \text { 其他情况 } \end{array}\right. h′={01−ph 概率为 p 其他情况
易知,此时的期望值仍保持不变,仍有 E [ h ′ ] = h E[h']=h E[h′]=h成立。
需要注意的是,一般在测试时不用暂退法,也有特殊情况:在测试网络预测的不确定性时可以采用暂退法,如果不同的暂退法遮盖后得到的预测结构都一致,则网络较为稳定。
本节以带权重衰减的单隐藏层多层感知机为例推导前向传播和反向传播。前向传播指的是按照从输入层到输出层的顺序计算和存储每层的结果。为简单起见,假设输入样本为 x ∈ R d \mathbf{x} \in \mathbb{R}^d x∈Rd,且隐藏层不包含偏置项( b = 0 b=0 b=0)。中间变量为
z = W ( 1 ) x \mathbf{z}=\mathbf{W}^{(1)}\mathbf{x} z=W(1)x
其中, W ( 1 ) ∈ R h × d \mathbf{W}^{(1)} \in \mathbb{R}^{h \times d} W(1)∈Rh×d是隐藏层的权重向量,隐藏层的中间变量经过激活函数 ϕ \phi ϕ之后,得到隐藏层长度为 h h h的激活向量
h = ϕ ( z ) \mathbf{h}=\phi(\mathbf{z}) h=ϕ(z)
假设输出层的参数只有权重向量 W ( 2 ) ∈ R q × h \mathbf{W}^{(2)}\in\mathbb{R}^{q\times h} W(2)∈Rq×h,则可以得到输出层变量,易知其是长度为 q q q的向量
o = W ( 2 ) h \mathbf{o}=\mathbf{W}^{(2)}\mathbf{h} o=W(2)h
记损失函数为 l l l,样本标签为 y y y,则可以得到单个样本的预测损失为
L = l ( o , y ) L=l(\mathbf{o},y) L=l(o,y)
因为此过程中有权重衰减,所以根据 L 2 L_2 L2正则化的定义,可以得出正则化项为
s = λ 2 ( ∥ W ( 1 ) ∥ F 2 + ∥ W ( 2 ) ∥ F 2 ) s=\frac{\lambda}{2}(\left \| \mathbf{W}^{(1)} \right \|_F^2+\left \| \mathbf{W}^{(2)} \right \|_F^2) s=2λ(∥∥∥W(1)∥∥∥F2+∥∥∥W(2)∥∥∥F2)
则总的损失函数为
J = L + s \mathbf{J}=L+s J=L+s
因为训练目标是为了使损失最小,所以 J \mathbf{J} J也被称为目标函数(objective function)。下图为与上述推导过程对应的数据流图,其中正方形为变量,圆圈表示操作符。
反向传播(backward propagation)用于计算参数梯度。根据求导的连式法则,从输出层到输入层进行遍历,求取各参数的梯度。在上节的推导中,参数主要是隐藏层和输出层的权重向量 W ( 1 ) \mathbf{W}^{(1)} W(1)和 W ( 2 ) \mathbf{W}^{(2)} W(2),反向传播的目的是计算梯度 ∂ J ∂ W ( 1 ) \frac{\partial \mathbf{J}}{\partial \mathbf{W}^{(1)}} ∂W(1)∂J和 ∂ J ∂ W ( 2 ) \frac{\partial \mathbf{J}}{\partial \mathbf{W}^{(2)}} ∂W(2)∂J。因此,根据连式法则,需要一次计算每个中间变量的参数和梯度,即按照计算图中数据流的反向进行计算,最终目标是求得两个权重变量的梯度。
从数据流图可以看出,第一步是计算目标函数分别相对于两项的梯度。易知其均为1,即
∂ J ∂ L = 1 ∂ J ∂ s = 1 \frac{\partial{\mathbf{J}}}{\partial L} = 1\\ \frac{\partial{\mathbf{J}}}{\partial s} = 1 ∂L∂J=1∂s∂J=1
第二步,求目标函数关于输出层输出 o \mathbf{o} o的梯度
∂ J ∂ o = ∂ J ∂ L ⋅ ∂ L ∂ o = ∂ L ∂ o ∈ R q \frac{\partial{\mathbf{J}}}{\partial \mathbf{o}}=\frac{\partial{\mathbf{J}}}{\partial L} \cdot \frac{\partial{L}}{\partial \mathbf{o}} =\frac{\partial{L}}{\partial \mathbf{o}} \in \mathbb{R}^q ∂o∂J=∂L∂J⋅∂o∂L=∂o∂L∈Rq
第三步,计算正则化项相对于相对于两个权重参数的梯度
∂ s ∂ W ( 1 ) = λ W ( 1 ) ∂ s ∂ W ( 2 ) = λ W ( 2 ) 根 据 以 上 三 部 , 可 以 计 算 出 \frac{\partial{s}}{\partial \mathbf{W}^{(1)}}=\lambda \mathbf{W}^{(1)}\\ \frac{\partial{s}}{\partial \mathbf{W}^{(2)}}=\lambda \mathbf{W}^{(2)}根据以上三部,可以计算出 ∂W(1)∂s=λW(1)∂W(2)∂s=λW(2)根据以上三部,可以计算出
根据以上三步,可以计算出最接近输出层的参数的梯度 ∂ J / ∂ W ( 2 ) ∈ R q × h \partial J / \partial \mathbf{W}^{(2)} \in \mathbb{R}^{q \times h} ∂J/∂W(2)∈Rq×h
∂ J ∂ W ( 2 ) = ( ∂ J ∂ o ⋅ ∂ o ∂ W ( 2 ) ) + ( ∂ J ∂ s ⋅ ∂ s ∂ W ( 2 ) ) = ∂ J ∂ o h ⊤ + λ W ( 2 ) \frac{\partial J}{\partial \mathbf{W}^{(2)}}=\left(\frac{\partial J}{\partial \mathbf{o}} \cdot \frac{\partial \mathbf{o}}{\partial \mathbf{W}^{(2)}}\right)+\left(\frac{\partial J}{\partial s}\cdot \frac{\partial s}{\partial \mathbf{W}^{(2)}}\right)=\frac{\partial J}{\partial \mathbf{o}} \mathbf{h}^{\top}+\lambda \mathbf{W}^{(2)} ∂W(2)∂J=(∂o∂J⋅∂W(2)∂o)+(∂s∂J⋅∂W(2)∂s)=∂o∂Jh⊤+λW(2)
继续沿着数据流图求另一个参数,沿着输出层到隐藏层反向传播。关于隐藏层输出的梯度 ∂ J / ∂ h ∈ R h \partial \mathbf{J} / \partial \mathbf{h} \in \mathbb{R}^{h} ∂J/∂h∈Rh可以根据下式计算
∂ J ∂ h = ∂ J ∂ o ⋅ ∂ o ∂ h = W ( 2 ) ∂ J ∂ o \frac{\partial J}{\partial \mathbf{h}}=\frac{\partial J}{\partial \mathbf{o}} \cdot \frac{\partial \mathbf{o}}{\partial \mathbf{h}}=\mathbf{W}^{(2)} \frac{\partial J}{\partial \mathbf{o}} ∂h∂J=∂o∂J⋅∂h∂o=W(2)∂o∂J
因为激活函数 ϕ \phi ϕ的计算是以元素为单位的,所以计算中间变量 z \mathbf{z} z的梯度 ∂ J / ∂ z ∈ R h \partial \mathbf{J} / \partial \mathbf{z} \in \mathbb{R}^{h} ∂J/∂z∈Rh也需要艺元素为单位进行计算,我们用 ⊙ \odot ⊙表示按元素乘法
∂ J ∂ z = ∂ J ∂ h ⋅ ∂ h ∂ z = ∂ J ∂ h ⊙ ϕ ′ ( z ) \frac{\partial J}{\partial \mathbf{z}}=\frac{\partial J}{\partial \mathbf{h}} \cdot \frac{\partial \mathbf{h}}{\partial \mathbf{z}}=\frac{\partial J}{\partial \mathbf{h}} \odot \phi^{\prime}(\mathbf{z}) ∂z∂J=∂h∂J⋅∂z∂h=∂h∂J⊙ϕ′(z)
最后,可以得出最接近输入层的参数的梯度 ∂ J / ∂ W ( 1 ) ∈ R h × d \partial J / \partial \mathbf{W}^{(1)} \in \mathbb{R}^{h \times d} ∂J/∂W(1)∈Rh×d
∂ J ∂ W ( 1 ) = ∂ J ∂ z ⋅ ∂ z ∂ W ( 1 ) + ∂ J ∂ s ⋅ ∂ s ∂ W ( 1 ) = ∂ J ∂ z x ⊤ + λ W ( 1 ) \frac{\partial J}{\partial \mathbf{W}^{(1)}}=\frac{\partial J}{\partial \mathbf{z}}\cdot \frac{\partial \mathbf{z}}{\partial \mathbf{W}^{(1)}}+\frac{\partial J}{\partial s}\cdot \frac{\partial s}{\partial \mathbf{W}^{(1)}}=\frac{\partial J}{\partial \mathbf{z}} \mathbf{x}^{\top}+\lambda \mathbf{W}^{(1)} ∂W(1)∂J=∂z∂J⋅∂W(1)∂z+∂s∂J⋅∂W(1)∂s=∂z∂Jx⊤+λW(1)
训练时,前向传播和反向传播相互依赖。前向传播时,沿着计算图正向计算所有变量,反向传播时计算这些变量对应的梯度。因此,训练时初始化模型参数后,需要交替进行前向传播和反向传播,利用反向传播给出的梯度来更新模型参数。需要注意的是,反向传播需要重复利用中间值,为了避免重复计算,需要将中间值进行存储直至反向传播完成,因此训练比单纯的预测需要消耗更多的内存,而且中间值的大小与网络层的数量和批量大小成正相关,因此,使用更大批量训练更深层次的网络要注意是否存在内存不足的问题。
上文中主要关注的是在给定初始化模型参数的情况下,方案如何进行训练,对于如何给定初始化模型参数并未提及。然而,初始化模型参数及激活函数的选择对于方案的训练效果起到决定性作用。
此处讨论一个具有 L L L层、输入为 x \mathbf{x} x,输出 o \mathbf{o} o的深层网络。每一层 l l l由变换 f l f_l fl定义,权重参数为 W ( l ) \mathbf{W^{(l)}} W(l),隐藏变量为 h ( 1 ) ( h ( 0 ) = x ) \mathbf{h^{(1)}}(\mathbf{h^{(0)}}=\mathbf{x}) h(1)(h(0)=x)。根据上文推导易知,存在如下关系
h ( l ) = f l ( h ( l − 1 ) ) o = f L ⋅ . . . ⋅ f 1 ( x ) \mathbf{h}^{(l)}=f_l(\mathbf{h}^{(l-1)})\\ \mathbf{o}=f_L \cdot ... \cdot f_1(\mathbf{x}) h(l)=fl(h(l−1))o=fL⋅...⋅f1(x)
输出 o \mathbf{o} o关于任一组权重参数 W ( l ) \mathbf{W^{(l)}} W(l)的梯度可以写为下式
∂ W ( l ) 0 = ∂ h ( L − 1 h ( L ) ⏟ M ( L ) def ⋅ … ⋅ ∂ h ( l ) h ( l + 1 ) ⏟ M ( l + 1 ) def ∂ W ( l ) h ( l ) ⏟ v ( l ) def \partial_{\mathbf{W}^{(l)} \mathbf{0}}=\underbrace{\partial_{\mathbf{h}^{(L-1} \mathbf{h}^{(L)}}}_{\mathbf{M}^{(L) \text { def }}} \cdot \ldots \cdot \underbrace{\partial_{\mathbf{h}^{(l)} \mathbf{h}^{(l+1)}}}_{\mathbf{M}^{(l+1) \text { def }}} \underbrace{\partial_{\mathbf{W}}^{(l) \mathbf{h}^{(l)}}}_{\mathbf{v}^{(l) \text { def }}} ∂W(l)0=M(L) def ∂h(L−1h(L)⋅…⋅M(l+1) def ∂h(l)h(l+1)v(l) def ∂W(l)h(l)
可以看出,该梯度是 L − l L-l L−l个矩阵 M ( L ) ⋅ . . . ⋅ M ( l + 1 ) \mathbf{M}^{(L)} \cdot ... \cdot \mathbf{M}^{(l+1)} M(L)⋅...⋅M(l+1)与梯度向量 v ( l ) \mathbf{v}^{(l)} v(l)的乘积。容易产生数值溢出的问题。在处理概率时,一种常用手段是取对数,将其映射到对数空间,可以将数据溢出的压力从尾数转移至指数,从而达到缓解压力的目的。然而,如果对上式进行这种操作,并不能起到缓解压力的作用甚至可能会加重。因为矩阵中可能有各种特征值,他们可能很大可能很小,他们的乘积可能很大也可能很小,导致映射到对数空间后仍有溢出的可能。
提不稳定一方面容易导致数值表示不正确,另一方面也会破坏算法的稳定性。如果梯度过大,会产生梯度爆炸(gradient exploding)的问题,使模型无法稳定收敛,要么会有梯度消失(gradient vanishing)的问题,是模型无法更新参数,无法学习。
常用的激活函数中,易知sigmoid函数在输入较大或较小时梯度变化很小甚至消失,因此使用sigmoid函数会导致梯度消失的现象,所以,ReLU更常用。
除了梯度消失和梯度爆炸的问题外,神经网络设计的另一个问题是其参数固有的对称性。如果对隐藏层的权重向量进行冲排列,同时对输出层的权重向量进行重排列,两种情况得出的函数相同,也就是说,每层的隐藏单元之间具有排列对称性。
环节排列对称性的一种方法是进行参数初始化。一般情况,默认的初始化权重向量为服从正态分布的权重值,因为正态分布更为适合一般情况的参数分布,一般情况下,这种方法较为有效。特殊情况下,可以采用Xavier参数初始化方法。
上文讨论的是线性全连接层输出,如果对于没有非线性的情况,该层 n i n n_{in} nin的输入 x j x_j xj及相关权重可以由下式给出
o i = ∑ j = 1 n i n w i j x j o_i=\sum_{j=1}^{n_{in}}w_{ij}x_j oi=j=1∑ninwijxj
所有的权重为独立同分布,记该分布的均值为0,方差为 σ 2 \sigma^2 σ2(并不意味着是正态分布)。假设输入 x j x_j xj,输入之间相互独立且与权重独立同分布,记其方差为 γ 2 \gamma^2 γ2(均值为0)。则可通过下式计算输出 o i o_i oi的平均值和方差
E [ o i ] = ∑ j = 1 n in E [ w i j x j ] = ∑ j = 1 n in E [ w i j ] E [ x j ] = 0 \begin{aligned} E\left[o_{i}\right] &=\sum_{j=1}^{n_{\text {in }}} E\left[w_{i j} x_{j}\right] \\ &=\sum_{j=1}^{n_{\text {in }}} E\left[w_{i j}\right] E\left[x_{j}\right] \\ &=0 \end{aligned} E[oi]=j=1∑nin E[wijxj]=j=1∑nin E[wij]E[xj]=0 Var [ o i ] = E [ o i 2 ] − ( E [ o i ] ) 2 = ∑ j = 1 n in E [ w i j 2 x j 2 ] − 0 = ∑ j = 1 n in E [ w i j 2 ] E [ x j 2 ] = n in σ 2 γ 2 \begin{aligned} \operatorname{Var}\left[o_{i}\right] &=E\left[o_{i}^{2}\right]-\left(E\left[o_{i}\right]\right)^{2} \\ &=\sum_{j=1}^{n_{\text {in }}} E\left[w_{i j}^{2} x_{j}^{2}\right]-0 \\ &=\sum_{j=1}^{n_{\text {in }}} E\left[w_{i j}^{2}\right] E\left[x_{j}^{2}\right] \\ &=n_{\text {in }} \sigma^{2} \gamma^{2} \end{aligned} Var[oi]=E[oi2]−(E[oi])2=j=1∑nin E[wij2xj2]−0=j=1∑nin E[wij2]E[xj2]=nin σ2γ2
如果要保持方差不变,可以设置 n i n σ 2 = 1 n_{in}\sigma^2=1 ninσ2=1。在反向传播过程中,通过推导可知,梯度的方差 V a r [ ∂ w o ] = n o u t σ 2 γ 2 Var[\partial{w}o]=n_{out}\sigma^2\gamma^2 Var[∂wo]=noutσ2γ2。与输出的方差相似,除非有 n o u t σ 2 = 1 n_{out}\sigma^2=1 noutσ2=1,否则梯度的方差可能会增大导致平稳受到影响。易知以上两式无法同时满足,我们可以退而求其次,只需满足
1 2 ( n in + n out ) σ 2 = 1 或等价于 σ = 2 n in + n out . \frac{1}{2}\left(n_{\text {in }}+n_{\text {out }}\right) \sigma^{2}=1 \text { 或等价于 } \sigma=\sqrt{\frac{2}{n_{\text {in }}+n_{\text {out }}}} \text {. } 21(nin +nout )σ2=1 或等价于 σ=nin +nout 2.
这就是Xavier参数初始化方法,从均值为0,方差 σ 2 = 2 n i n + n o u t \sigma^2=\frac{2}{n_{in}+n_{out}} σ2=nin+nout2的正态分布中采样初始化参数。
实际应用中,一般将模型训练好之后部署到实际应用场景中,然而如果实际数据分布改变,可能会导致模型效果大副下降,本节讨论数据分布可能变化的方式以及如何挽救模型性能。数据分布改变常常表现为数据分布偏移。常见的数据偏移方式包括协变量偏移、标签偏移、概念偏移等。
协变量偏移指的是输入的分布随时间改变,标签函数(即条件分布 P ( y ∣ x ) P(y|x) P(y∣x))没有改变。
根据推导可知,如果不考虑正则化,可以用 minimize f 1 n ∑ i = 1 n l ( f ( x i ) , y i ) \underset{f}{\operatorname{minimize}} \frac{1}{n} \sum_{i=1}^{n} l\left(f\left(\mathbf{x}_{i}\right), y_{i}\right) fminimizen1∑i=1nl(f(xi),yi)表示训练损失,其中 l l l为损失函数,统计学中称此项为经验风险(empirical risk),用于近似真实风险(true risk),真实风险为从真实分布 p ( x , y ) p(x,y) p(x,y)中抽取的所有数据总体损失的期望
E p ( x , y ) [ l ( f ( x ) , y ) ] = ∬ l ( f ( x ) , y ) p ( x , y ) d x d y E_{p(\mathbf{x}, y)}[l(f(\mathbf{x}), y)]=\iint l(f(\mathbf{x}), y) p(\mathbf{x}, y) d \mathbf{x} d y Ep(x,y)[l(f(x),y)]=∬l(f(x),y)p(x,y)dxdy
然而,无法获得全部数据,因此,风险最小化指的是最小化经验风险。对于带标签的数据 ( x i , y i ) (x_i,y_i) (xi,yi),要评估 P ( y ∣ x ) P(y|x) P(y∣x)。然而协变量偏移的情况下,观测值 x i x_i xi是从源分布 q ( x ) q(x) q(x)得出的,目标分布为 p ( x ) p(x) p(x)。根据依赖性假设,即条件分布保持不变 p ( y ∣ x ) = q ( y ∣ x ) p(y|x)=q(y|x) p(y∣x)=q(y∣x)。协变量偏移情况下,源分布发生了偏移,可以采用如下恒等式进行纠正
∬ l ( f ( x ) , y ) p ( y ∣ x ) p ( x ) d x d y = ∬ l ( f ( x ) , y ) q ( y ∣ x ) q ( x ) p ( x ) q ( x ) d x d y \iint l(f(\mathbf{x}), y) p(y \mid \mathbf{x}) p(\mathbf{x}) d \mathbf{x} d y=\iint l(f(\mathbf{x}), y) q(y \mid \mathbf{x}) q(\mathbf{x}) \frac{p(\mathbf{x})}{q(\mathbf{x})} d \mathbf{x} d y ∬l(f(x),y)p(y∣x)p(x)dxdy=∬l(f(x),y)q(y∣x)q(x)q(x)p(x)dxdy
即需要知道,数据来自正确分布与错误分布的概率之比,以此重新衡量每个样本的权重
β i = def p ( x i ) q ( x i ) \beta_{i} \stackrel{\text { def }}{=} \frac{p\left(\mathbf{x}_{i}\right)}{q\left(\mathbf{x}_{i}\right)} βi= def q(xi)p(xi)
将权重 β i \beta_i βi带入数据样本中,则此时可以使用”加权经验风险最小化“来训练模型
minimize f 1 n ∑ i = 1 n β i l ( f ( x ∗ i ) , y ∗ i ) \underset{f}{\operatorname{minimize}} \frac{1}{n} \sum_{i=1}^{n} \beta_i l\left(f\left(\mathbf{x}*{i}\right), y*{i}\right) fminimizen1i=1∑nβil(f(x∗i),y∗i)
但是,因为权重未知,因此需要对权重进行估计。可以采用的方法有很多,不过任意一种方法都需要从两个分布中抽取样本:从测试数据中获取”真实“分布 p p p,从训练集中获取 q q q。从恒等式可以知道,我们只需要 x ∼ p ( x ) x\sim p(x) x∼p(x)和 x ∼ q ( x ) x \sim q(x) x∼q(x),因此只需要访问特征而不需要访问标签。
综上所述,需要对从两种分布中抽取的数据进行区分。可以很好区分的样本,其权重应该相应地显著增加或减少。如果两个分布无法区分,表明相关的样本可能来自两个分布的任意一个。
假设从 p ( x ) p(x) p(x)和 q ( x ) q(x) q(x)中抽取相同数量的样本,均用标签 z z z表示,从 p p p中抽取的标签为1,从 q q q中抽取的标签为-1。则混合数据集的概率分布可以由下式给出
P ( z = 1 ∣ x ) = p ( x ) p ( x ) + q ( x ) and hence P ( z = 1 ∣ x ) P ( z = − 1 ∣ x ) = p ( x ) q ( x ) P(z=1 \mid \mathbf{x})=\frac{p(\mathbf{x})}{p(\mathbf{x})+q(\mathbf{x})} \text { and hence } \frac{P(z=1 \mid \mathbf{x})}{P(z=-1 \mid \mathbf{x})}=\frac{p(\mathbf{x})}{q(\mathbf{x})} P(z=1∣x)=p(x)+q(x)p(x) and hence P(z=−1∣x)P(z=1∣x)=q(x)p(x)
此时,可以采用对数几率回归(logistic regression,用于二元分类的softmax回归的特例),即对权重取对数,将其结果记为 h h h。
l o g β i = def l o g p ( x i ) q ( x i ) = h log\beta_{i} \stackrel{\text { def }}{=} log\frac{p\left(\mathbf{x}_{i}\right)}{q\left(\mathbf{x}_{i}\right)}=h logβi= def logq(xi)p(xi)=h
则可推出
p ( x ) q ( x ) = e x p ( − h ) \frac{p(x)}{q(x)}=exp(-h) q(x)p(x)=exp(−h)
带入混合数据集的概率分布可得
P ( z = 1 ∣ x ) = 1 1 + exp ( − h ( x ) ) P(z=1 \mid \mathbf{x})=\frac{1}{1+\exp (-h(\mathbf{x}))} P(z=1∣x)=1+exp(−h(x))1
至此,可以得出纠正协变量偏移的算法。假设训练集为 ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x n , y n ) {(x_1,y_1),(x_2,y_2),...,(x_n,y_n)} (x1,y1),(x2,y2),...,(xn,yn)和一个未标记的测试集 u 1 , u 2 , . . . , u n {u_1,u_2,...,u_n} u1,u2,...,un。 x i , 1 ≤ i ≤ n x_i,1 \le i \le n xi,1≤i≤n来自源分布, u i u_i ui来自目标分布。
生成一个二元分类训练集 ( x 1 , − 1 ) , . . . , ( x n , − 1 ) , ( u 1 , 1 ) , . . . , ( u n , 1 ) {(x_1,-1),...,(x_n,-1),(u_1,1),...,(u_n,1)} (x1,−1),...,(xn,−1),(u1,1),...,(un,1)
用对数几率回归训练二元分类器得到函数 h h h
用 β i = e x p ( h ( x i ) ) \beta_i = exp(h(x_i)) βi=exp(h(xi))或者 β i = m i n ( e x p ( h ( x i ) ) , c ) ( c 为 常 量 ) \beta_i = min(exp(h(x_i)),c) (c为常量) βi=min(exp(h(xi)),c)(c为常量)对训练数据进行加权
使用权重 β i \beta_i βi进行训练
需要注意的是目标分布(测试分布)中不能存在训练时出现概率为0的样本,否则,会出现 p ( x ) > 0 p(x)>0 p(x)>0但 q ( x ) = 0 q(x)=0 q(x)=0的情况,其对应的权重为 ∞ \infin ∞。
标签偏移描述的问题与协变量偏移相反, P ( y ) P(y) P(y)改变但 P ( x ∣ y ) P(x|y) P(x∣y)保持不变。
为了讨论方便,此处基本假设与协变量偏移的情况相同,所不同的是此时处理的是 k k k个类别的分类问题,且标签的分布随时间变化,即 q ( y ) ≠ p ( y ) q(y) \ne p(y) q(y)=p(y),但类别条件分布保持不变,即 p ( x ∣ y ) = q ( x ∣ y ) p(x|y)=q(x|y) p(x∣y)=q(x∣y)。如果源分布出错,可以通过以下恒等式进行纠正
∬ l ( f ( x ) , y ) p ( x ∣ y ) p ( y ) d x d y = ∬ l ( f ( x ) , y ) q ( x ∣ y ) q ( y ) p ( y ) q ( y ) d x d y \iint l(f(\mathbf{x}), y) p(\mathbf{x} \mid y) p(y) d \mathbf{x} d y=\iint l(f(\mathbf{x}), y) q(\mathbf{x} \mid y) q(y) \frac{p(y)}{q(y)} d \mathbf{x} d y ∬l(f(x),y)p(x∣y)p(y)dxdy=∬l(f(x),y)q(x∣y)q(y)q(y)p(y)dxdy
类似地,权重应为
β i = def p ( y i ) q ( y i ) \beta_{i} \stackrel{\text { def }}{=} \frac{p\left(\mathbf{y}_{i}\right)}{q\left(\mathbf{y}_{i}\right)} βi= def q(yi)p(yi)
标签偏移时不改变 p ( x ) p(x) p(x),所以如果在源分布上得到一个模型,可以从中得出对权重的一致估计,而不需要处理其他维度。因此我们在训练集训练分类器,使用验证集计算其混淆矩阵。如果我们的分类器一开始就相当准确, 并且目标数据只包含我们以前见过的类别, 以及如果标签偏移假设成立(这里最强的假设), 我们就可以通过求解一个简单的线性系统来估计测试集的标签分布 p ( y ) p(y) p(y)。观测源数据上的标签,很容易估计分布 q ( y ) q(y) q(y),可以进一步求得权重,带入加权经验风险最小化。
概念偏移是指标签的定义发生变化,例如不同语境下对于同一个单词take的翻译不同、不同地区对于毒品的种类定义不同等。
概念偏移很难用原则性的方式解决,除了从零开始收集标签和训练目前别无他法。不过因为通常情况下,概念的变化总是相对缓慢的,因此,可以使用新数据更新现有的权重,而不是从头开始训练