《Deep Learning》笔记 —— 深度前馈网络

深度前馈网络也叫作前馈神经网络或者多层感知机,一种理解前馈网络的方式是从线性模型开始的,并考虑克服其局限性。线性模型,如逻辑回归和线性回归,无论是通过闭解形式还是使用凸优化,它们都能高效且可靠的拟合。但是也存在明显缺陷,线性模型被局限在线性函数里,所以无法理解两个输入变量的相互作用。

为了扩展线性模型来表示\(x\)的非线性函数,引入非线性变换\(\phi(x)\),关于如何选择\(\phi\),有如下方法:

1)使用一个通用\(\phi\),例如无限维的\(\phi\),它隐含地用在基于RBF核的核机器上。非常通用的特征映射通常只基于局部光滑原则,并且没有足够先验信息解决高级问题。

2)手动设计\(\phi\),缺点是不同的领域难以迁移。

3)深度学习的策略是自主学习\(\phi\),这种方法的优点是我们只需要寻找正确的函数族就可以了,不需要去寻找精确函数。

1. 基于梯度的学习

线性模型和神经网络最大的区别在于神经网络的非线性导致大多数我们感兴趣的代价函数都变得非凸。这意味着神经网络的训练通常使用迭代的、基于梯度的优化,仅仅使得代价函数达到一个非常小的值,而不是想训练线性回归模型、SVM的凸优化那样保证全局收敛。

1.1 代价函数

大多数现代神经网络使用最大似然来训练,这意味着代价函数是负对数似然,它与训练数据和模型分布间的交叉熵等价,这个代价函数表示为: \[J(\theta)=-\mathbb{E}_{x,y \sim \hat{p}_{data}}log\,p_{model}(y|x)\]

使用最大似然来导出代价函数的方法的一个优势是,它减轻了为每个模型设计代价函数的负担。明确一个模型的\(p(y|x)\)则自动地确定了一个代价函数\(log\,p(y|x)\)

特别的,代价函数的梯度必须足够的大和具有足够的预测性,而饱和的函数把梯度变得非常小破坏了这个目标。值得注意的是这种情况在神经网络中经常发生,因为隐藏层或输出层的激活函数会饱和。负对数似然能够避免这个问题,因为负对数代价函数中的对数函数消除了某些输出单元的指数效果。

1.2 输出单元

高斯输出分布的线性单元

给定特征\(h\),线性输出单元产生一个向量\(\hat{y}=W^Th+b\)。线性输出层经常用来产生条件高斯分布的均值: \[p(y|x)=\mathcal{N}(y;\hat{y},I)\] 最大化其对数似然等价于最小化均方误差。

因为线性单元不会饱和,所以易于采用基于梯度的优化算法。

伯努利输出分布的sigmoid单元

sigmoid输出单元定义为\(\hat{y}=\sigma(w^Th+b)\),可将其分为两个部分,使用线性层来计算\(z=w^Th+b\),接着使用sigmoid激活函数将\(z\)转化为概率。

当我们使用其他损失函数,损失函数将在\(\sigma(z)\)饱和时饱和,sigmoid在\(z\)取非常小的负值时会饱和到0,取非常大的正值时会饱和到1,这种情况一旦发生,梯度会变得非常小以至于不能用来学习,因此最大似然几乎总是训练sigmoid输出单元的优选方案。

多项式输出分布的softmax单元

任何时候,当需要表示一个具有n个可能取值的离散随机变量的分布时,都可以使用softmax函数,softmax函数最常用作分类器的输出,来表示n个不同类上的概率分布。用于伯努利分布的方法可以推广到多项式分布。首先线性层预测未归一化的对数概率: \[z=W^Th+b\] 其中\(z_i=log\,\hat{P}(y=i|x)\),softmax函数对z指数化和归一化来获得需要的\(\hat{y}\),其函数形式为: \[softmax(z)_i=\frac{e^{z_i}}{\sum_je^{z_j}}\] 使用最大似然训练softmax输出目标y,对数似然中的log将抵消softmax中的\(e\)\[log\,softmax(z_i)=z_i-log\,\sum_{j}e^{z_j}\] 该式中的第一项\(z_i\)不会饱和,所以即使\(z_i\)对第二项贡献很小,学习依然可以进行。此外第二项\(log\,\sum_je^{z_j}\)可以近似为\(\max\limits_j\,z_j\),如果正确答案已经具有softmax的最大输入则\(-z_i\)\(log\,\sum_j \approx \max\limits_j\,z_j=z_j\)将大致抵消。这样整个样本对整体训练代价贡献很小,所以这个代价将主要由为被正确分类的样本产生。

对数似然之外的许多目标函数对softmax函数不起作用,因为指数函数的变量取非常小的负值时将造成梯度消失,特别是平方误差,对softmax单元来说它是很差的损失函数。

其他的输出类型

最大似然原则给如何为任何种类的输出层设计一个好的代价函数提供了指导。

2. 隐藏单元

ReLU单元是隐藏单元极好的默认选择,一些隐藏层单元可能并不是在所有的输入点上都是可微的,例如ReLU单元\(g(z)=max{0,z}\)\(z=0\)处不可微,在实践中,梯度下降对这些机器学习模型仍然表现良好,部分原因是因为神经网络算法通常不会达到代价函数的局部最小值,而是仅仅显著减小它的值。

2.1 ReLU单元的扩展

ReLU单元易于优化,因为其与线性单元非常类似,ReLU单元在其一半的定义域上输出为零,这使得ReLU单元只要处于激活状态,其导数都比较大和一致,而且二阶导数几乎处处为0,处于激活状态时候,它的一阶导数处处为1,所以它的梯度方向对学习来说更有用。

ReLU的一个缺陷是不能通过基于梯度的方法学习那些使他它们激活为0的样本,而ReLU的各自扩展则保证了能在各个位置都接受到梯度。

ReLU的三个扩展基于当\(z_i<0\)时使用一个非零的斜率\(\alpha_i\):\(h_i=g(z,\alpha)_i=max(0,z_i)+\alpha_imin(0,z_i)\)

1)绝对值ReLU,固定\(\alpha_i=-1\)来得到\(g(z)=|z|\),它用于图像中的对象识别,在寻找输入照明极性反转下不变的特征。

2)渗漏ReLU(Leaky ReLU),将\(\alpha_i\)固定为一个类似0.01的小值。

3)参数化ReLU(PReLU),将\(\alpha_i\)作为一个可学习的参数。

maxout单元,进一步扩展了ReLU,其将\(z\)划分为每组具有k个值得组: \[ g(z)_i=\max_{j\in\mathbb(G^i)}z_j \] 每个maxout单元输出每组中的最大元素。这提供了一种方法来学习对输入x空间中的多个方向的响应的分段线性函数。maxout单元可以学习多大k段的分段线性凸函数,因此可视为学习激活函数本身。使用足够大的k,maxout单元可以以任意的精确度来近似任何凸函数。(此部分详见paper)

2.2 logistic sigmoid与双曲正切函数

sigmoid单元的广泛饱和性会使基于梯度的学习变得非常困难,所以现在不鼓励使用sigmoid作为前馈网络的隐藏层单元。如果必须要使用sigmoid作为激活函数,则双曲正切函数通常要比logistic sigmoid函数表现的更好,在\(tanh(0)=0\)\(\sigma(0)=\frac{1}{2}\)的意义上,tanh更像单位函数(在0附近),所以只要网络的激活保持地很小,训练深层网络类似于训练一个线性模型。

sigmoid激活函数在除前馈神经网络以外的情景中更为常见,循环神经网络、许多概率模型以及一些自编码器有一些额外的要求使得其不能使用分段激活函数。

2.3 其他隐藏层单元

1)线性隐藏单元,即完全没有使用激活函数,线性隐藏层单元提供了一种减速网络中参数数量的有效方法。

2)softmax单元,softmax单元表示具有k个可能值得离散型变量的概率分布,所以它们可以作为一种开关。

3)RBF函数,\(h_i = e^{-\frac{1}{\sigma_i^2}||W_{:,i}-x||^2}\)因对大多数x饱和到0,所以很难优化。

4)softplus函数,\(g(a)=\zeta(a)=log(1+e^a)\),ReLU的平滑版本,通常不鼓励使用softplus,通常ReLU表现更好。

5)硬双曲正切函数,\(g(a)=\max(-1,min(1,a))\),形状与tanh类似,但相比于双曲正切,hard tanh是有界的。

3. 架构设计

架构指网络的整体结构,具有多少个单元以及这些单元如何连接。

3.1 万能近似

具有隐藏层的前馈网络提供了一种万能近似框架,具体的来说,万能定理表明,一个前馈近似神经网络如果具有线性输出层和至少一层具有任何一种“挤压”性质的激活函数的隐藏层,只要给予网络足够数量的隐藏单元,则它可以以任意精度来近似任何从一个有限维空间到另一个有限维空间的Borel可测函数(在\(\mathbb(R)^n\)的有界闭集上的任意连续函数时Borel可测的)。神经网络也可以近似从任何有限维离散空间映射到另一个任意函数。

万能近似定理意味着无论试图学习什么样的函数,都能通过一个足够大MLP来表示这个函数,但是不能保证训练算法一定能够学到这个函数。存在两个原因可能导致学习失败,首先,用于训练的优化算法可能找不到用于期望函数的参数值。其次,训练算法可能由于过拟合而选择了错误的函数。

总之,具有单层前馈网络足以表示任何函数,但是网络层可能大得不可实现,并且可能无法正确地学习和泛化。在很多情况下使用更深的模型能够减少表示期望函数所需的单元数量,并且减少泛化误差。

3.2 其他架构上的考虑

许多神经网络架构被开发用于特定的任务,用于计算机视觉的卷积神经网络,用于序列处理的循环神经网络等。一般来说,层不需要连接在链中,但许多架构构建了一个主链,随后又添加了额外的架构特性,例如从层i到i+2或者更高层的跳跃连接,这些跳跃连接使得梯度更容易从输出层流向更接近输入的层。

4. 反向传播

微积分中的链式法则

\(x\)是实数,\(f\text{和}g\)是从实数映射到实数的函数,假设\(y=g(x)\)并且\(z=f(g(x))=f(y)\),那么链式法则是: \[ \frac{dz}{dx}=\frac{dz}{dy}\frac{dy}{dx} \] 扩展到向量形式,\(x\in \mathbb{R}^m\)\(y\in \mathbb{R}^n\)\(g\)是从\(\mathbb{R}^m\)\(\mathbb{R}^n\)的映射,\(f\)是从\(\mathbb{R}^n\)\(\mathbb{R}\)的映射,如果\(y=g(x)\),且\(z=f(y)\),则 \[ \frac{\partial z}{\partial x_i}=\sum_j \frac{\partial z}{\partial y_j}\frac{\partial y_j}{\partial x_i} \] 向量记法: \[ \nabla_xz = (\frac{\partial z}{\partial x})^T\nabla_yz \] 其中\(\frac{\partial y}{\partial x}\)\(g\)\(n\times m\)Jacobian矩阵。

扩展到张量,使用\(\nabla_\mathbf{X}z\)表示值\(z\)关于张量\(\mathbf{X}\)的梯度,使用单个变量\(i\)来表示张量完整的索引组,令\(\mathbf{Y}=g(\mathbf{X})\)\(z=f(\mathbf{Y})\),则 \[ \nabla_\mathbf{X}z=\sum_j(\nabla_\mathbf{X}Y_j)\frac{\partial z}{\partial \mathbf{Y}_j} \]

递归的使用链式法则实现反向传播

在迭代的计算工程中存在两种策略,存储子表达式还是重新进行计算。例如,令\(w\in \mathbb{R}\)为计算图的的输入,每一步使用相同的操作函数\(f:\mathbb{R} \rightarrow \mathbb{R}\),即\(x=f(w)\)\(y=f(x)\)\(z=f(y)\),为了计算\(\frac{\partial z}{\partial w}\)得到: \[ \begin{array}{} & \quad \frac{\partial z}{\partial w} \\ & = \frac{\partial z}{\partial y} \frac{\partial y}{\partial x} \frac{\partial x}{\partial w} \\ & = f'(y)f'(x)f'(w) \end{array} \] 此实现方法,仅计算\(f(w)\)的值一次并将它存储在变量\(x\)中。另一种策略则使用\(f'(f(f(w)))f'(f(w))f'(w)\),通常在存储受限时会使用。

MLP中的的反向传播计算

前向传播: forward.png

反向传播: backward.png