剑指机器学习--前向神经网络

机器学习方法复习笔记-6

Posted by Leon Ling on November 8, 2020

深度前向神经网络(Deep Feedforward Network)是一种非常典型的深度学习模型。其目标就是为了拟合映射$y=f(x;\theta)$将输入的$x$转化为某种预测的输出$y$,并同时学习网络的参数$\theta$,使得模型能够达到最优的近似。

前向神经网络通常是多个函数复合表示,整体模型与一个有向无环图相关联,实际常用”链式法则“来表示函数的复合方式。常见的多层感知机,自编码器,以及卷积神经网络都是其中的一员。

[TOC]

1. 多层感知机和布尔函数

1.1 多层感知机表示异或逻辑时最少需要几个隐含层, 仅考虑二元输入?

首先,我们先来分析一下具有零个隐藏层的情况(等同于逻辑回归)能否表示异或运算。仅考虑二元输入的情况,设X取值为0或1,Y的取值也为0或1,Z为异或运算的输出。也就是,当X和Y相同时,异或输出为0,否则为1,具体的真值表如下

$X$ $Y$ $Z=X\oplus Y$
0 0 0
0 1 1
1 0 1
1 1 0

回顾逻辑回归的公式: $Z=sigmoid(AX+BY+C)$

其中Sigmoid激活函数是单调递增的:当$AX+BY+C$的取值增大时,$Z$的取值也增大;当$AX+BY+C$的取值减少时,$Z$的取值也减小。而$AX+BY+C$对于$X$和$Y$的变化也是单调的,当参数$A$为正数时,$AX+BY+C$以及$Z$的取值随$X$单调递增;当$A$取负数时,$AX+BY+C$和$Z$随$X$单调递减;当参数$A$为0时,$Z$的值与$X$无关。观察异或运算的真值表,当$Y=0$时,将$X$的取值从0变到1将使输出$Z$也从0变为1,说明此时$Z$的变化与$X$是正相关的,需要设置$A$为正数;而当$Y=1$时,将$X$的取值从0变为1将导致输出$Z$从1变为0,此时$Z$与$X$是负相关的,需要设置$A$为负数,与前面矛盾。因此,采用逻辑回归(即不带隐藏层的感知机)无法精确学习出一个输出为异或的模型表示。

然后,我们再考虑具有一个隐藏层的情况。事实上,通用近似定理告诉我们,一个前馈神经网络如果具有线性输出层和至少一层具有任何一种“挤压”性质的激活函数的隐藏层,当给予网络足够数量的隐藏单元时,可以以任意精度近似任何从一个有限维空间到另一个有限维空间的波莱尔可测函数。可以简单认为我们常用的激活函数和目标函数是通用近似定理适用的一个子集,因此多层感知机的表达能力是非常强的,关键在于我们是否能够学习到对应此表达的模型参数。

在这里,我们还并不涉及模型参数的学习,而是通过精心设计一个模型参数以说明包含一个隐含层的多层感知机就可以确切地计算异或函数,如下图所示。图中有$Z_1$和$Z_2$两个隐藏单元。在隐藏单元$Z_1$中,$X$和$Y$的输入权重均为1,且偏置为1,等同于计算$H_1=X+Y−1$,再应用ReLU激活函数$max(0,H_1)$,同理,隐藏单元$Z_2$的输入权重均为−1,偏置为−1,真值表如下所示。可以看到,第一个隐藏单元在$X$和¥Y¥均为1时激活,第二个隐藏单元在$X$和$Y$均为0时激活,最后再将两个隐藏单元的输出做一个线性变换即可实现异或操作。

$X$ $Y$ $H_1=X+Y-1$ $Z_1=max(0,H)$ $H_2=-X-Y+1$ $Z_2=max(0,H)$
0 0 -1 0 1 1
0 1 0 0 0 0
1 0 0 0 0 0
1 1 1 1 -1 0
$Z_1$ $Z_2$ $Z=-Z_1-Z_2+1$
0 1 0
0 0 1
0 0 1
1 0 0

1.2 如果只使用一个隐层,需要多少隐节点能够实现包含n元输入的任意布尔函数?

包含n元输入的任意布尔函数可以唯一表示为析取范式(Disjunctive Normal Form,DNF)(由有限个简单合取式构成的析取式)的形式。先看一个n=5的简单示例 $Y =\overline{X_1X_2}X_3X_4\overline{X_5}+\overline{X_1}X_2\overline{X_3}X_4X_5+\overline{X_1}X_2X_3\overline{X_4X_5}\\ \quad +X_1\overline{X_2X_3X_4}X_5+X_1\overline{X_2}X_3X_4X_5+X_1X_2\overline{X_3X_4}X_5$

其中,最终的输出Y可以表示成由6个合取范式所组成的析取范式。该函数可由包含6个隐节点的3层感知机实现,如图

首先证明单个隐结点可以表示任意合取范式。考虑任意布尔变量假设$X_i$,若它在合取范式中出现的形式为正$(X_i)$,则设权重为1;若出现的形式为非$\overline{X}_i$,则设权重为−1;若没有在合取范式中出现。设权重为0;并且偏置设为合区范式中变量的总数取负之后再加1。可以看出,当采用ReLU激活函数之后,当且仅当所有出现的布尔变量均满足条件时,该隐藏单元才会被激活(输出1),否则输出0,这与合取范式的定义的相符的。然后,令所有隐藏单元到输出层的参数为1,并设输出单元的偏置为0。这样,当且仅当所有的隐藏单元都未被激活时,才会输出0,否则都将输出一个正数,起到了析取的作用。

我们可以使用卡诺图表示析取式,即用网格表示真值表,当输入的合取式值为1时,则填充相应的网格。卡诺图中相邻的填色区域可以进行规约,以达到化简布尔函数的目的,由图可见,有$W、X、Y、Z$共4个布尔变量,$WX$的取值组合在纵轴显示,$YZ$的取值组合在横轴显示。7个填色网格最终可规约为3个合取式,故该函数可由包含3个隐节点的3层感知机实现:

回顾初始问题:在最差情况下,需要多少个隐藏结点来表示包含n元输入的布尔函数呢?

现在问题可以转化为:寻找“最大不可规约的”$n$元析取范式,也等价于最大不可规约的卡诺图。直观上,我们只需间隔填充网格即可实现,其表示的布尔函数恰为$n$元输入的异或操作,如图所示。容易看出,在间隔填充的网格上反转任意网格的取值都会引起一次规约,因此,$n$元布尔函数的析取范式最多包含$2^{(n−1)}$个不可规约的合取范式,对于单隐层的感知机,需要$2^{(n−1)}$个隐节点实现。

1.3 考虑多隐层的情况,实现包含n元输入的任意布尔函数最少需要多少个网络节点和网络层?

参考问题1的解答,考虑二元输入的情况,需要3个结点可以完成一次异或操作,其中隐藏层由两个节点构成,输出层需要一个结点,用来输出异或的结果并作为下一个结点的输入。对于四元输入,包含三次异或操作,需要$3×3=9$个节点即可完成。下图展示了一种可能的网络结构。输入$W、X、Y、Z $ 4个布尔变量;首先用3个结点计算$W⊕X$;然后再加入3个节点,将$W⊕X$的输出与Y进行异或,得到$W⊕X⊕Y$;最后与$Z$进行异或,整个网络总共需要9个结点。而六元输入包含五次异或操作,因此需要$3×5=15$个节点。依此类推,n元异或函数需要包括$3^{(n−1)}$个节点(包括最终输出节点)。可以发现,多隐层结构可以将隐节点的数目从指数级$O(2^{(n−1)})$直接减少至线性级$O(3^{(n−1)})$!

在上面所举的例子中,$n$元异或所需的$3^{(n−1)}$个结点可以对应$2^{(n−1)}$个网络层(包括隐含层和输出层),实际上,层数可以进一步减小。考虑到四元的输入$W、X、Y、Z$;如果我们在同一层中计算$W⊕X$和$Y⊕Z$,$Z$将二者的输出进行异或,就可以将层数从6降到4。根据二分思想,每层节点两两分组进行异或运算,需要的最少网络层数为$2log_2 N$(向上取整)。

2. 深度网络中的激活函数

2.1 常用的激活函数及其导数

  • Sigmoid激活函数:$f(z)=sigmoid(z)=\frac{1}{1+e^{-z}}$
  • Sigmoid函数倒数:$f^\prime(z)=f(z)(1-f(z))$
  • Tanh激活函数:$f(z)=tanh(z)=\frac{e^z-e^{-z}}{e^z-e^{-z}}$
  • Tanh函数导数:$f^\prime(z)=1-(f(z))^2$
  • ReLU激活函数:$f(z)=ReLU(z)=max(0,z)$
  • ReLU函数导数:$f^\prime(z)=\begin{cases}1, & z>0 \\ 0, & z\le0\end{cases}$

2.2 为什么Sigmoid和Tanh激活函数会导致梯度消失现象

如下左图,Sigmoid激活函数的曲线将输入z映射到区间$(0,1)$当 $z$ 很大时,$f(z)$趋近于1;当$z$很小时,$f(z)$趋近于0。其导数在$z$很大或很小时都会趋近于0,造成梯度消失的现象。

如下右图,Tanh激活函数的曲线当$z$很大时,$f(z)$趋近于1;当z很小时,$f(z)$趋近于−1。其导数在$z$很大或很小时都会趋近于0,同样会出现“梯度消失”。

实际上,Tanh激活函数相当于Sigmoid的平移放缩:$tanh(x)=2sigmoid(2x)-1$

2.3 ReLU系列的激活函数相对于Sigmoid和Tanh激活函数的优点是什么?它们有什么局限性以及如何改进?

优点:

  1. 从计算的角度上,SigmoidTanh激活函数均需要计算指数,复杂度高,而ReLU只需要一个阈值即可得到激活值。
  2. ReLU的非饱和性可以有效地解决梯度消失的问题,提供相对宽的激活 边界。
  3. ReLU的单侧抑制提供了网络的稀疏表达能力。

缺点:

ReLU的局限性在于其训练过程中会导致神经元死亡的问题。这是由于函数$f(z)=max(0,z)$导致负梯度在经过该ReLU单元时被置为0,且在之后也不被任何数据激活,即流经该神经元的梯度永远为0,不对任何数据产生响应。在实际训练中,如果学习率(Learning Rate)设置较大,会导致超过一定比例的神经元不可逆死亡,进而参数梯度无法更新,整个训练过程失败。

为解决这一问题,出现了ReLU的变种——Leaky ReLU(LReLU):$LReLU(z)=\begin{cases}z, & z>0 \\az, & z\le0\end{cases}$

ReLULReLU的函数曲线对比如下图,LReLUReLU的区别在于,当$z<0$时其值不为0,而是一个斜率为$a$的线性函数,一般$a$为一个很小的正常数,这样既实现了单侧抑制,又保留了部分负梯度信息以致不完全丢失。但另一方面,$a$值的选择增加了问题难度,需要较强的人工先验或多次重复训练以确定合适的参数值。

基于此,参数化的PReLU(Parametric ReLU)应运而生。它与LReLU的主要区别是将负轴部分斜率$a$作为网络中一个可学习的参数,进行反向传播训练,与其他含参数网络层联合优化。而另一个LReLU的变种增加了“随机化”机制,具体地,在训练过程中,斜率$a$作为一个满足某种分布的随机采样;测试时再固定下来。Random ReLU(RReLU)在一定程度上能起到正则化的作用。

此外,ReLU还有一个问题就是在$z=0$处不可导。所以后续又有人提出Exponential Linear Unit (ELU): $ELU(z)=\begin{cases}z, & z>0 \\ \alpha (e^z-1)z, & z\le0\end{cases}$

和用来解决ELU中$\alpha$不好确定的Scaled Exponential Linear Unit (SELU): $SELU(z)=\begin{cases}z, & z>0 \\ \lambda\alpha (e^z-1)z, & z\le0\end{cases}$, $\alpha = 1.67326324235, \lambda = 1.05070098736$ 。

这里的参数$\alpha$和$\lambda$有一套推导计算流程,可以详见作者的GitHub

3. 多层感知机的反向传播算法

下图定义了一个典型的多层感知机。

定义第$(l)$层的输入为$x^{(l)}$,输出为$a^{(l)}$;在每一层中,首先利用输入$x^{(l)}$和偏置$b^{(l)}$计算仿射变换$z^{(l)}=W^{(l)}x^{(l)}+b^{(l)}$;然后激活函数$f$作用于$z^{(l)}$,得到$a^{(l)}=f(z^{(l)})$;$a^{(l)}$直接作为下一层的输入,即$x^{(l+1)}$。设$x^{(l)}$为$m$维的向量,$z^{(l)}$和$a^{(l)}$为$n$维的向量,则$W^{(l)}$为$m×n$维的矩阵。我们分别用$z_i^{(l)}$,$a_i^{(l)}$和$W_{ij}^{(l)}$表示其中的一个元素。

在网络训练中,前向传播最终产生一个标量损失函数,反向传播算法(Back Propagation)则将损失函数的信息沿网络层向后传播用以计算梯度,达到优化网络参数的目的。

3.1 多层感知机的平方误差和交叉熵损失函数

给定包含$m$样本的集合${(x^{(l)},y^{(l)}),\cdot\cdot\cdot,(x^{(m)},y^{(m)})}$,其整体代价函数为 \(\begin{align} J(W,b)&=\bigg[\frac{1}{m}\Sigma^m_{i=1}J(W,b;x^{(i)},y^{(j)})\bigg]+ \frac{\lambda}{2}\Sigma^{N-1}_{l=1}\Sigma^{s_l}_{i=1}\Sigma^{s_l+1}_{j=1}(W^(l)_{ij})^2 \\ &=\bigg[\frac{1}{m}\Sigma^m_{i=1}\frac{1}{2}\big\Vert y^{(i)}-\cal{L}_{W,b}(x^{(i)})\big\Vert^2\bigg]+\frac{\lambda}{2}\Sigma^{N-1}_{l=1}\Sigma^{s_l}_{i=1}\Sigma^{s_l+1}_{j=1}(W^(l)_{ij})^2 \end{align},\) 其中第一项为平方误差项,第二项为L2正则化项,在功能上可称作权重衰减项,目的是减小权重的幅度,防止过拟合。该项之前的系数λ为权重衰减参数,用于控制损失函数中两项的相对权重。

以二分类场景为例,交叉熵损失函数定义为 \(\begin{align} J(W,b)&=\bigg[\frac{1}{m}\Sigma^m_{i=1}J(W,b;x^{(i)},y^{(j)})\bigg]+ \frac{\lambda}{2}\Sigma^{N-1}_{l=1}\Sigma^{s_l}_{i=1}\Sigma^{s_l+1}_{j=1}(W^(l)_{ij})^2 \\ &=\bigg[\frac{1}{m}\Sigma^m_{i=1}\{y^{(i)}ln\ o^{(i)}+(1-y^{(i)})ln(1-o^{(i)})\}\bigg]+\frac{\lambda}{2}\Sigma^{N-1}_{l=1}\Sigma^{s_l}_{i=1}\Sigma^{s_l+1}_{j=1}(W^(l)_{ij})^2 \end{align}\) 其中正则项与上式是相同的;第一项衡量了预测o(i)与真实类别y(i)之间的交叉熵,当y(i)与o(i)相等时,熵最大,也就是损失函数达到最小。在多分类的场景中,可以类似地写出相应的损失函数 \(\begin{align} J(W,b)&=\bigg[\frac{1}{m}\Sigma^m_{i=1}\Sigma^n_{k=1}y^{(i)}_kln\ o_k^{(i)}\bigg]+ \frac{\lambda}{2}\Sigma^{N-1}_{l=1}\Sigma^{s_l}_{i=1}\Sigma^{s_l+1}_{j=1}(W^(l)_{ij})^2\end{align}\) 其中$o_k^{(i)}$代表第$i$个样本的预测属于类别$k$的概率,$y_k^{(i)}$为实际的概率(如果第$i$个样本的真实类别为$k$,则$y_k^{(i)}=1$,否则为$0$)。

3.2 根据3.1中定义的损失函数,推导各层参数更新的梯度计算公式。

可以利用批量梯度下降法来优化网络参数。梯度下降法中每次迭代对参数$W$(网络连接权重)和$b$(偏置)进行更新: \(\begin{align} W_{ij}^{(l)}&=W_{ij}^{(l)}-\alpha\frac{\partial}{\partial W_{ij}^{(l)}}J(W,b)\\ b_i^{(l)}&=b_i^{(l)}-\alpha\frac{\partial}{\partial b_i^{(l)}}J(W,b) \end{align}\)

其中$\alpha$为学习速率,控制每次迭代中梯度变化的幅度。

问题的核心为求解$\frac{\partial}{\partial W_{ij}^{(l)}}J(W,b)$与$\frac{\partial}{\partial b_i^{(l)}}J(W,b)$。为得到递推公式,我们还需要计算损失函数对隐含层的偏导

$\begin{align} \frac{\partial}{\partial z_i^{(l)}}J(W,b)= \Sigma_{j=1}^{s_{l+1}}\bigg( \frac{\partial J(W,b)}{\partial z_j^{(l+1)}}\frac{\partial z_j^{(l+1)}}{\partial z_i^{(l)}}\bigg) \end{align}$

其中$s_{l+1}$为第$l+1$层的节点数,而

$\begin{align} \frac{\partial z_j^{(l+1)}}{\partial z_i^{(l)}}= \frac{\partial (W_{ij}^{(l)}x^{(l+1)}+b_j^{(l+1)})}{\partial z_i^{(l)}} \end{align}$

其中$b^{(l+1)}$与$z_i^{(l)}$无关可以省去,$x^{(l+1)}=a{(l)}=f(z^{(l)})$ ,因此

$\begin{align} \frac{\partial z_j^{(l+1)}}{\partial z_i^{(l)}}= W_{ij}^{(l)}f^\prime(z_i^{(l)}) \end{align}.$

而$\frac{\partial J(W,b)}{\partial z_j^{(l+1)}}$ 可以看作损失函数在第l层第i个节点产生的残差量,记为$δ_i^{(l)}$,从而递推公式可以表示为

$\begin{align} δ_i^{(l)}=\big(\Sigma_{j=1}^{s_{l+1}}W_{ij}^{(l)}\delta_j^{(l+1)}\big) f^\prime(z_i^{(l)}) \end{align}.$

损失对参数函数的梯度可以写为

$\begin{align} \frac{\partial}{\partial W_{ij}^{(l)}}J(W,b)= \frac{\partial J(W,b)}{\partial z_i^{(l+1)}}\frac{\partial z_j^{(l+1)}}{\partial W_{ij}^{(l)}}=\delta_i^{(l+1)}x_j^{(l+1)}
=\delta_i^{(l+1)}a_j^{(l)}\frac{\partial}{\partial b_i^{(l)}}J(W,b)=\delta_i^{(l+1)}. \end{align}$,

下面针对两种不同的损失函数计算最后一层的残差$δ^{(L)}$;得到$δ^{(L)}$之后,其他层的残差$δ^{(L−1)},…, δ^{(1)}$可以根据上面得到的递推公式计算。为了简化起见,这里暂时忽略Batch样本集合和正则化项的影响,重点关注这两种损失函数产生的梯度。

平方误差损失:

$\begin{align} J(W,b)&=\frac{1}{2}\left\Vert y-a^{(L)}\right\Vert^2=\frac{1}{2}\left\Vert y-f(z_j^{(L)})\right\Vert^2,\\ \delta^{(L)}&=-(y-a^{(L)})f^\prime(z^{(L)}).\end{align}$

交叉熵损失:

$\begin{align}J(W,b)=-\Sigma_{k=1}^ny_kln\ a_k^{(L)}=-\Sigma_{k=1}^ny_kln\ f^\prime(z^{(L)})\end{align}$.

在分类问题中,$y_k$仅在一个类别$k$时取值为1,其余为0。设实际的类别为$\tilde{k}$,则

$\begin{align} J(W,b)&=-ln\ a_{\tilde{k}}^{(L)},\\ \delta^{(L)}&=-\frac{f^\prime(z_{\tilde{k}}^{(L)})}{f(z_{\tilde{k}}^{(L)})}\end{align}.$

$f$取SoftMax激活函数时,$f^\prime(x)=f(x)(1-f(x))$ ,因此

$\begin{align}\delta^{(L)}&=f(z_{\tilde{k}}^{(L)})-1\\ &=a_{\tilde{k}}^{(L)}-1.\end{align}$

3.3 平方误差损失函数和交叉熵损失函数分别适合什么场景?

一般来说,平方损失函数更适合输出为连续,并且最后一层不含Sigmoid或Softmax激活函数的神经网络;交叉熵损失则更适合二分类或多分类的场景。

为何平方损失函数不适合最后一层含有Sigmoid或Softmax激活函数的神经网络呢?

可以回顾3.2推导出的平方误差损失函数相对于输出层的导数: $\delta^{(L)}=-(y-a^{(L)})f^\prime(z^{(L)})$,其中最后一项$f^\prime(z^{(L)})$为激活函数的导数。当激活函数为Sigmoid函数时,如果$z^{(L)}$的绝对值较大,函数的梯度会趋于饱和,即$f^\prime(z^{(L)})$的绝对值非常小,导致$δ^{(L)}$的取值也非常小,使得基于梯度的学习速度非常缓慢。

当使用交叉熵损失函数时,相对于输出层的导数(也可以被认为是残差)为 $\delta^{(L)}=a_{\tilde{k}}^{(L)}-1$,此时的导数是线性的,因此不会存在学习速度过慢的问题。

4. 神经网络训练技巧

在训练大规模神经网络的时候, 我们常常遇到过拟合的问题. 为了解决过拟合, 我们常常使用

  • 数据增强(Data Augmentation)
  • 正则化(Regularization)
  • 集成训练(Model Ensemble)
  • 批量归一化(Batch Normalization)
  • Dropout

4.1 网络训练的时候是否可以初始化全部参数为0?

不可以.

考虑fully connected的深度网络, 同一层的任意神经元都是同构的, 并且拥有相同的输入和输出. 如果再将参数都初始化为相同的值, 那么无论前向传播还是反向传播, 取值都是完全相同的. 学习的过程没有办法打破这种对称性, 最后导致训练完成同一层下的所有参数还是相同的.

所以, 要随机初始化神经网络的参数的值, 以打破对称性. 简单来说, 可以初始化参数范围 $(-\frac{1}{\sqrt{d}},\frac{1}{\sqrt{d}})$的均匀分布, 其中 $d$ 是神经元输入数据的维度. 而Bias可以被简单设置为0, 并不会造成参数不对称的问题.

4.2 为什么Dropout可以抑制过拟合?

Dropout是指在深度网络的训练中,以一定的概率随机地 “临时丢弃”一部分神经元节点。具体来讲,Dropout作用于每份小批量训练数据,由于其随机丢弃部分神经元的机制,相当于每次迭代都在训练不同结构的神经网络。类比于Bagging方法,Dropout可被认为是一种实用的大规模深度神经网络的模型集成算法。这是由于传统意义上的Bagging涉及多个模型的同时训练与测试评估,当网络与参数规模庞大时,这种集成方式需要消耗大量的运算时间与空间。Dropout在小批量级别上的操作,提供了一种轻量级的Bagging集成近似,能够实现指数级数量神经网络的训练与评测。

Dropout的具体实现中,要求某个神经元节点激活值以一定的概率p被“丢弃”,即该神经元暂时停止工作,如下图所示。因此,对于包含N个神经元节点的网络,在Dropout的作用下可看作为2N个模型的集成。这2N个模型可认为是原始网络的子网络,它们共享部分权值,并且具有相同的网络层数,而模型整体的参数数 目不变,这就大大简化了运算。对于任意神经元,每次训练中都与一组随机挑选的不同的神经元集合共同进行优化,这个过程会减弱全体神经元之间的联合适应性,减少过拟合的风险,增强泛化能力。

在神经网络中应用Dropout包括训练和预测两个阶段。在训练阶段中,每个神经元节点需要增加一个概率系数,如下图所示。

训练阶段又分为前向传播和反向传播两个步骤。原始网络对应的前向传播公式为:

$\begin{align}z_i^{(l+1)}&=w_i^{(l+1)}u^l+b^{(l+1)}_i,\\ y_i^{(l+1)}&=f(z^{(l+1)}_i).\end{align}$

应用Dropout之后,前向传播公式变为:

$\begin{align}r_i^{(l)}&\sim Bernoulli(p), \\ \tilde{y}^{(1)}&=r{(l)}\ast y{(l)},\\ z_i^{(l+1)}&=w_i^{(l+1)}\tilde{l}+b_i^{(l+1)},\\ y_i^{(l+1)}&=f(z^{(l+1)}_i).\end{align}$

上面的$Bernoulli$函数的作用是以概率系数$p$随机生成一个取值为0或1的向量,代表每个神经元是否需要被丢弃。如果取值为 0,则该神经元将不会计算梯度或参与后面的误差传播。

测试阶段是前向传播的过程。在前向传播的计算时,每个神经元的参数要预先乘以概率系数$p$,以恢复在训练中该神经元只有$p$的概率被用于整个神经网络的前向传播计算。

4.3 Batch Norm的基本原理是什么? 在卷积网络中如何使用?

神经网络训练过程的本质是学习数据分布,如果训练数据与测试数据的分布不同将大大降低网络的泛化能力,因此我们需要在训练开始前对所有输入数据进行归一化处理。

然而随着网络训练的进行,每个隐层的参数变化使得后一层的输入发生变化,从而每一批训练数据的分布也随之改变,致使网络在每次迭代中都需要拟合不同的数据分布,增大训练的复杂度以及过拟合的风险。

批量归一化方法是针对每一批数据,在网络的每一层输入之前增加归一化处理(均值为0,标准差为1),将所有批数据强制在统一的数据分布下,即对该层的任意一个神经元(假设为第$k$维)$\hat{x}^{(k)}$采用如下公式 $\hat{x}^{(k)}=\frac{x^{(k)}-E[x^{(k)}]}{\sqrt{Var[x^{(k)}]}}$,其中$x^{(k)}$为该层第k个神经元的原始输入数据,$E[x^{(k)}]$为这一批输入数据在第$k$个神经元的均值, $\sqrt{Var[x^{(k)}]}$为这一批数据在第$k$个神经元的标准差。

批量归一化可以看作在每一层输入和上一层输出之间加入了一个新的计算层,对数据的分布进行额外的约束,从而增强模型的泛化能力。但是批量归一化同时也降低了模型的拟合能力,归一化之后的输入分布被强制为0均值和1标准差。以Sigmoid激活函数为例,批量归一化之后数据整体处于函数的非饱和区域,只包含线性变换,破坏了之前学习到的特征分布。为了恢复原始数据分布,具体实现中引入了变换重构以及可学习参数 $\gamma$ 和 $\beta$:$y^{(k)}=\gamma^{(k)}\hat{x}^{(k)}+\beta^{(k)}$,其中$\gamma^{(k)}$和$\beta^{(k)}$分别为输入数据分布的方差和偏差。

对于一般的网络,不采用批量归一化操作时,这两个参数高度依赖前面网络学习到的连接权重(对应复杂的非线 性)。而在批量归一化操作中,$\gamma$和$\beta$变成了该层的学习参数,仅用两个参数就可以恢复最优的输入数据分布,与之前网络层的参数解耦,从而更加有利于优化的过程,提高模型的泛化能力。

完整的批量归一化网络层的前向传导过程公式如下: \(\begin{array} \mu_B&\leftarrow\frac{1}{m}\Sigma^m_{i=1}(x_{i}-\mu_B)^2,\\ \sigma^2_B&\leftarrow\frac{1}{m}\Sigma^m_{i=1}(x_i-\mu_B)^2,\\ \hat{x}_i&\leftarrow\frac{x_i-\mu_Beta}{\sqrt{\sigma^2_B+\epsilon}},\\ y_i&\leftarrow\gamma \hat{x}_i+\beta\equiv BN_{\gamma,\beta}(x_i) \end{array}\) 批量归一化在卷积神经网络中应用时,需要注意卷积神经网络的参数共享机制。每一个卷积核的参数在不同位置的神经元当中是共享的,因此也应该被一起归一化。具体实现中,假设网络训练中每一批包含$b$个样本,由一个卷积核生成的特征图的宽高分别为$w$和$h$,则每个特征图所对应的全部神经元个数为$b×w×h$;利用这些神经元对应的所有输入数据,我们根据一组待学习的参数γ和β对每个输入数据进行批量归一化操作。如果有f个卷积核,就对应f个特征图和f组不同的$γ$和$β$参数。

5. 卷积神经网络

卷积神经网络(Convolutional Neural Networks,CNN)也是一种前馈神经网络,其特点是每层的神经元节点只响应前一层局部区域范围内的神经元(全连接网络中每个神经元节点响应前一层的全部节点)。

一个深度卷积神经网络模型通常由若干卷积层叠加若干全连接层组成,中间也包含各种非线性操作以及池化操 作。卷积神经网络同样可以使用反向传播算法进行训练,相较于其他网络模型,卷积操作的参数共享特性使得需要优化的参数数目大大缩减,提高了模型的训练效率以及可扩展性。由于卷积运算主要用于处理类网格结构的数据,因此对于时间序列以及图像数据的分析与识别具有显著优势。

5.1 卷积的操作的本质特性是什么?

稀疏交互(Sparse Interaction)和参数共享(Parameter Sharing).

稀疏交互

在传统神经网络中,网络层之间输入与输出的连接关系可以由一个权值参数矩阵来表示,其中每个单独的参数值都表示了前后层某两个神经元节点之间的交互。对于全连接网络,任意一对输入与输出神经元之间都产生交互,形成稠密的连接结构,如图所示,神经元$s_i$与输入的所有神经元$x_j$均有连接。

而在卷积神经网络中,卷积核尺度远小于输入的维度,这样每个输出神经元仅与前一层特定局部区域内的神经元存在连接权重(即产生交互),我们称这种特性为稀疏交互,如下图所示。可以看到与稠密的连接结构不同,神经元$s_i$仅与前一层中的$x_{i−1}$、$x_i$和$x_{i+1}$相连。具体来讲,假设网络中相邻两层分别具有$m$个输入和$n$个输出,全连接网络中的权值参数矩阵将包含$m×n$个参数。对于稀疏交互的卷积网络,如果限定每个输出与前一层神经元的连接数为k,那么该层的参数总量为$k×n$。在实际应用中,一般$k$值远小于$m$就可以取得较为可观的效果;而此时优化过程的时间复杂度将会减小几个数量级,过拟合的情况也得到了较好的改善。

稀疏交互的物理意义是,通常图像、文本、语音等现实世界中的数据都具有局部的特征结构,我们可以先学习局部的特征,再将局部的特征组合起来形成更复杂和抽象的特征。

以人脸识别为例,最底层的神经元可以检测出各个角度的边缘特征(见图(a));位于中间层的神经元可以将边缘组合起来得到眼睛、鼻子、嘴巴等复杂特征(见图(b));最后,位于上层的神经元可以根据各器官的组合检测出人脸的特征(见图(c))。

参数共享

参数共享是指在同一个模型的不同模块中使用相同的参数,它是卷积运算的固有属性。全连接网络中,计算每层的输出时,权值参数矩阵中的每个元素只作用于某个输入元素一次;而在卷积神经网络中,卷积核中的每一个元素将作用于每一次局部输入的特定位置上。根据参数共享的思想,我们只需要学习一组参数集合,而不需要针对每个位置的每个参数都进行优化,从而大大降低了模型的存储需求。

参数共享的物理意义是使得卷积层具有平移等变性。

假如图像中有一只猫,那么无论它出现在图像中的任何位置,我们都应该将它识别为猫,也就是说神经网络的输出对于平移变换来说应当是等变的。特别地,当函数 $f (x)$ 与 $g(x)$ 满足 $f(g(x))=g( f (x))$ 时,我们称 $f (x)$ 关于变换 $g$ 具有等变性。将 $g$ 视为输入的任意平移函数,令 $I$ 表示输入图像(在整数坐标上的灰度值函数),平移变换后得到 $I’=g(I)$。例如,我们把猫的图像向右移动 $l$ 像素,满足 $I’(x,y)=I(x−l,y)$。我们令 $f$ 表示卷积函数,根据其性质,我们很容易得到 $g(f(I))=f(I’)=f (g(I))$。也就是说,在猫的图片上先进行卷积,再向右平移l像素的输出,与先将图片向右平移l像素再进行卷积操作的输出结果是相等的。

5.2 常用的池化操作有哪些? 池化的作用?

常用的池化操作主要针对非重叠区域,包括均值池化(mean pooling)、最大池化(max pooling)等。

均值池化通过对邻域内特征数值求平均来实现,能够抑制由于邻域大小受限造成估计值方差增大的现象,特点是对背景的保留效果更好。

最大池化则通过取邻域内特征的最大值来实现,能够抑制网络参数误差造成估计均值偏移的现象,特点是更好地提取纹理信息。

池化操作的本质是降采样。例如,我们可以利用最大池化将4×4的矩阵降采样为2×2的矩阵,如图所示。图中的池化操作窗口大小为2×2,步长为2。每次在2×2大小的窗口上进行计算,均值池化是求窗口中元素的均值,最大池化则求窗口中元素的最大值;然后将窗口向右或向下平移两格,继续操作。

此外,特殊的池化方式还包括对相邻重叠区域的池化以及空间金字塔池化。

相邻重叠区域的池化,顾名思义,是采用比窗口宽度更小的步长,使得窗口在每次滑动时存在重叠的区域。空间金字塔池化主要考虑了多尺度信息的描述,例如同时计算$1×1$、$2×2$、$4×4$的矩阵的池化并将结果拼接在一起作为下一网络层的输入。

池化操作除了能显著降低参数量外,还能够保持对平移、伸缩、旋转操作的不变性。

平移不变性是指输出结果对输入的小量平移基本保持不变。例如,输入为$(1,5,3)$,最大池化将会取5,如果将输入右移一位得到$(0,1,5)$,输出的结果仍将为5。

对伸缩的不变性(一般称为尺度不变性)可以这样理解,如果原先神经元在最大池化操作之后输出5,那么在经过伸缩(尺度变换)之后,最大池化操作在该神经元上很大概率的输出仍然是5。因为神经元感受的是邻域输入的最大值,而并非某一个确定的值。

旋转不变性可以参照下图。图中的神经网络由3个学得的过滤器和一个最大池化层组成。这3个过滤器分别学习到不同旋转方向的“5”。当输入中出现“5”时,无论进行何种方向的旋转,都会有一个对应的过滤器与之匹配并在对应的神经元中引起大的激活。最终,无论哪个神经元获得了激活,在经过最大池化操作之后输出都会具有大的激活。

5.3 卷积神经网络在文本分类任务中怎么使用?

对于文本来说,局部特征就是由若干单词组成的滑动窗口,类似于N-gram。卷积神经网络的优势在于能够自动地对Ngram特征进行组合和筛选,获得不同抽象层次的语义信息。由于在每次卷积中采用了共享权重的机制,因此它的训练速度相对较快,在实际的文本分类任务中取得了非常不错的效果。

下图是一个用卷积神经网络模型进行文本表示,并最终用于文本分类的网络结构。

  1. 输入层是一个$N×K$的矩阵,其中$N$为文章所对应的单词总数,$K$是每个词对应的表示向量的维度。每个词的$K$维向量可以是预先在其他语料库中训练好的,也可以作为未知的参数由网络训练得到。这两种方法各有优势,一方面,预先训练的词嵌入可以利用其他语料库得到更多的先验知识;另一方面,由当前网络训练的词向量能够更好地抓住与当前任务相关联的特征。因此,图中的输入层实际采用了两个通道的形式,即有两个$N×K$的输入矩阵,其中一个用预先训练好的词嵌入表达,并且在训练过程中不再发生变化;另外一个也由同样的方式初始化,但是会作为参数,随着网络的训练过程发生改变。
  2. 第二层为卷积层。在输入的$N×K$维矩阵上,我们定义不同大小的滑动窗口进行卷积操作: $c_i=f(w\cdot x_{i:i+h-1}+b)$,其中$x_{i:i+h−1}$代表由输入矩阵的第i行到第$i+h−1$行所组成的一个大小为$h×K$的滑动窗口,$w$为$K×h$维的权重矩阵,$b$为偏置参数。假设$h$为$3$,则每次在$2×K$的滑动窗口上进行卷积,并得到$N−2$个结果,再将这$N−2$个结果拼接起来得到$N−2$维的特征向量。每一次卷积操作相当于一次特征向量的提取,通过定义不同的滑动窗口,就可以提取出不同的特征向量,构成卷基层的输出。
  3. 第三层为池化层,比如图中所示的网络采用了1-Max池化,即为从每个滑动窗口产生的特征向量中筛选出一个最大的特征,然后将这些特征拼接起来构成向量表示。也可以选用K-Max池化(选出每个特征向量中最大的K个特征),或者平均池化(将特征向量中的每一维取平均)等,达到的效果都是将不同长度的句子通过池化得到一个定长的向量表示。
  4. 得到文本的向量表示之后,后面的网络结构就和具体的任务相关了。本例中展示的是一个文本分类的场景,因此最后接入了一个全连接层,并使用Softmax激活函数输出每个类别的概率。

6. 残差网络

随着大数据时代的到来,数据规模日益增加,这使得我们有可能训练更大容量的模型,不断地提升模型的表示能力和精度。深度神经网络的层数决定了模型的容量,然而随着神经网络层数的加深,优化函数越来越陷入局部最优解。同时,随着网络层数的增加,梯度消失的问题更加严重,这是因为梯度在反向传播时会逐渐衰减。特别是利用Sigmoid激活函数时,使得远离输出层(即接近输入层)的网络层不能够得到有效的学习,影响了模型泛化的效果。

深度残差网络(Deep Residual Network,ResNet)是一种非常有效的网络结构改进,极大地提高了可以有效训练的深度神经网络层数。

6.1 ResNet的提出背景和核心理论是什么?

ResNet的提出背景是解决或缓解深层的神经网络训练中的梯度消失问题。假设有一个L层的深度神经网络,如果我们在上面加入一层,直观来讲得到的L+1层深度神经网络的效果应该至少不会比L层的差。因为我们简单地设最后一层为前一层的拷贝(用一个恒等映射即可实现),并且其他层维持原来的参数即可。然而在进行反向传播时,我们很难找到这种形式的解。实际上,通过实验发现,层数更深的神经网络反而会具有更大的训练误差。这很大程度上归结于深度神经网络的梯度消失问题。

为了解释梯度消失问题是如何产生的。回顾第3节推导出的误差传播公式:\(\begin{equation}\delta^{(l)}=\bigg(\Sigma_{j=1}^{s_{l+1}}W_{ij}^{(l)}\delta_j^{(l+1)}\bigg)f^\prime(z_i^{(l)})\end{equation}\)

再展开一层,可以得到:\(\begin{equation} \delta^{(l)}= \bigg(\Sigma_{j=1}^{s_{l+1}}W_{ij}^{(l)} \left(\Sigma_{k=1}^{s_{l+2}}W_{jk}^{(l+1)}\delta_k^{(l+2)}f^\prime(z_j^{(l+1)})\right) \bigg)f^\prime(z_i^{(l)})\end{equation}\)

可以看到误差传播可以写成参数$W_{ij}^{(l)}$、$W_{jk}^{(l+1)}$以及导数$f^\prime(z_j^{(l+1)})$、$f^\prime(z_i^{(l)})$连乘的形式。当误差由第L层(记为$\delta^{(L)}$)传播到除输入以外的第一个隐含层(记为$\delta^{(l)}$)的时候,会涉及非常多的参数和导数的连乘,这时误差很容易产生消失或者膨胀,影响对该层参数的正确学习。因此深度神经网络的拟合和泛化能力较差,有时甚至不如浅层的神经网络模型精度更高。

ResNet通过调整网络结构来解决上述问题。首先考虑两层神经网络的简单叠加(见图(a))),这时输入$x$经过两个网络层的变换得到$H(x)$,激活函数采用ReLU。反向传播时,梯度将涉及两层参数的交叉相乘,可能会在离输入近的网络层中产生梯度消失的现象。ResNet把网络结构调整为,既然离输入近的神经网络层较难训练,那么我们可以将它短接到更靠近输出的层,如图(b)所示。输入$x$经过两个神经网络的变换得到$F(x)$,同时也短接到两层之后,最后这个包含两层的神经网络模块输出$H(x)=F(x)+x$。这样一来,$F(x)$被设计为只需要拟合输入$x$与目标输出的残差,残差网络的名称也因此而来。如果某一层的输出已经较好的拟合了期望结果,那么多加入一层不会使得模型变得更差,因为该层的输出将直接被短接到两层之后,相当于直接学习了一个恒等映射,而跳过的两层 只需要拟合上层输出和目标之间的残差即可。