本文是《深度学习》第六章的学习笔记.
本章是对前馈网络的整体内容进行详细地论述。
6.1 实例:学习XOR
采用一个简单的前馈神经网络,一个隐含层,隐含层包含两个单元。
整个网络为:
$$f(x;W,c,w,b) = w^T\text{max}(0,W^Tx+c)+b$$
隐含层激活函数采用的是ReLU
。
给出一个解:
$$W=
\begin{bmatrix}
1 & 1 \\
1 & 1 \\
\end{bmatrix}
$$
$$c=
\begin{bmatrix}
0 \\
-1 \\
\end{bmatrix}
$$
$$w=
\begin{bmatrix}
1 \\
-2 \\
\end{bmatrix}
$$
以及:$$ b = 0 $$
6.2 基于梯度的学习
对于前馈神经网络,将所有权重初始化为小的值是很重要的。偏置可以初始化为0或者小的正值(如0.1)。
第8章介绍迭代的基于梯度的优化算法,8.4节为参数初始化,
4.3节介绍了一些特别的算法,是对梯度下降思想的改进和提纯。
随机梯度下降将算法的改进在5.9节。
6.2.1 代价函数
大多数情况下,参数模型定义了一个分布$p(y|x;\theta)$,并且简单地使用最大似然原理。
使用训练数据和模型预测间的交叉熵作为代价函数。
完整的代价函数 = 基本代价函数 + 正则项。
最流行的正则化策略:权重衰减(weight decay)。
第7章介绍更高级的正则化策略。
6.2.1.1 使用最大似然学习条件分布
使用最大似然训练意味着代价函数就是负的对数似然。
负的对数似然 = 训练数据和模型分布间的交叉熵 。
代价函数为:
$$J(\theta) = E_{x,\; y \sim \hat P_{data}} logP_{model}(y|x) $$
代价函数的具体形式取决于模型$logP_{model}$的具体形式。展开后的代价函数,可以舍去其中不依赖于模型的参数。
如果有:$$P_{model}(y|x) = N(y;f(x;\theta),I) $$
就可以得到均方误差代价:
$$J(\theta) = \frac{1}{2} E_{x,\; y \sim \hat P_{data}} || y-f(x;\theta )||^2 +\text{const} $$
代价函数的梯度必须足够大和具有足够的预测性,来为学习算法提供一个好的指引。
饱和(变得非常平)的函数破坏了这一目标,梯度非常小。该情况很常见是因为隐藏单元或输出单元的激活函数会饱和。
6.2.1.2 学习条件统计量
预测器$f(x;\theta)$,预测y的均值。
代价泛函(可以表示一大类函数中的任何一个函数,仅仅被一些特征所限制,而不是具有特殊的参数形式)。 泛函是指函数到实数的映射。
对函数求解问题需要用到变分法(19.4.2节)。
变分法导出的第一个结果是解优化问题:
$$f^* =\underset{f}{\mathrm{argmin}} E_{x,\; y \sim P_{data}}|| y-f(x)||^2$$
得到:
$$f^*(x) = E_{ y \sim P_{data}(y|x)}[y]$$
最小化均方误差代价函数将得到一个函数,可以用来对每个x的值预测出y的均值。
第二个使用变分法得到的结果是:
$$f^* = \underset{f}{\mathrm{argmin}} E_{x,\; y \sim P_{data}}|| y-f(x)||_1$$
将得到一个函数可以对每个x预测y取值的中位数,只要这个函数在我们要优化的函数族里。这个函数通常被称为平均绝对误差(mean absolute error)。最小化平均绝对误差代价函数。
交叉熵代价函数 比均方误差或者平均绝对误差更受欢迎的原因也在此,饱和的输出单元当结合后两个代价函数时会产生非常小的梯度。
6.2.2 输出单元
代价函数的选择:大多数情况下,简单使用数据分布和模型分布间的交叉熵。
本节中,假设前馈网络提供了一组定义为$h=f(x;\theta )$的隐藏特征。输出层的作用则是随后对这些特征进行额外的变换完成整个网络必须完成的任务。
6.2.2.1 用于Bernoulli输出分布的sigmoid单元
两个类的分类问题,即预测二值型变量y。
最大似然定义$y\ $在$x\ $条件下的Bernoulli
分布。
6.2.2.2 用于Multinoulli输出分布的softmax单元
任何时候,当我们想要表示一个具有n个可能取值的离散型随机变量的分布时,都可以使用softmax函数。
softmax
函数最常用作分类器的输出,来表示$n\ $个不同类上的概率分布。
首先,线性层预测了未归一化的对数概率:
$$ z = W^Th+b$$
其中,$z_i = log \hat P (y=i|x)$,softmax
函数然后对$z\ $指数化和归一化来获得需要的$\hat y$。最终,softmax
函数的形式为:
$$ \text{softmax}(z)_i = \frac{\text{exp}(z_i)}{\sum_j \text{exp}(z_j)}$$
当使用最大化对数似然训练softmax
来输出目标值$y\ $时,这时,我们想要最大化$logP(y=i;z)=\log \text{softmax}(z)_i$。将softmax
定义为指数的形式是因为对数似然中的log
可以抵消softmax中
的exp
:
$$\log \text{softmax(z)}_i = z_i -\log \sum_j \text{exp}(z_j)$$
关于softmax
的解释:这个函数更接近argmax
函数而不是max函数。“soft”术语来源于softmax
函数是连续可微的。“argmax”函数的结果表示为一个one-hot向量(只有一个元素为1,其余元素都为0的向量),不是连续可微的。softmax
函数因此提供了argmax的“软化”版本,max函数相应的软化版本是$\text{softmax}(z)^Tz$。可能最好是把softmax函数称为“softargmax
”,但当前名字已经是一个根深蒂固的习惯了。
6.2.2.4 其他的输出类型
6.3 隐藏单元
整流线性单元是隐藏单元极好的默认选择。
大多数隐藏单元的区别仅仅在于激活函数$g(z)$的形式。
隐藏单元少数点不可微的解释。 可微的定义是:只有函数在$z\ $处的左导数与右导数都有定义并且相等时,函数在$z\ $处才是可微的。
$g(z) = \text{max}(0,z)$,在$z=0$处的左导数为0,右导数为1。软件中实现通常是返回左导数或者右导数的其中一个,而不是报告导数未定义或者产生一个错误。
6.3.1 整流线性单元及其扩展
整流线性单元的激活函数:$g(z) = \text{max}(0,z)$
整流线性单元通常作用于仿射变换之上: $$h = g(W^Tx+b)$$
6.3.2 logistic sigmoid与双曲正切函数
双曲正切函数通常要比logistic sigmoid函数表现更好。
6.3.3 其他隐藏单元
其中一种是完全没有隐藏单元$g(z)$。也可以说是用单位函数作为激活函数。
softmax单元是一种经常用作输出的单元,但有时候也可以用作隐藏单元。
softmax单元很自然地表示具有k个可能值的离散型随机变量的概率分布,所以它们可以作为一种开关。将在10.12节介绍。
其他的一些隐藏单元包括:
- 径向基函数(radial basis function, RBF)
- softplus函数
- 硬双曲正切函数(hard tanh)
6.4 架构设计
架构(architecture)一词指网络的整体结构:它应该具有多少单元,以及这些单元应该如何连接。
链式结构:每一层都是前一层的函数。主要的考虑因素是网络的深度和每层的宽度。
6.4.1 万能近似性质和深度
万能近似定理(universal approximation theorem):一个前馈神经网络如果具有线性输出层和至少一层具有任何一种“挤压”性质的激活函数(例如sigmoid函数)的隐含层,只要给予网络足够数量的隐藏单元,它可以以任意的精度近似任何从一个有限维空间到另一个有限维空间的Borel可测函数。
单层的前馈网络虽然足以表示任何函数,但是网络层可能大得不可实现。
所以需要深度网络。
Montufar et al(2014):一些用深度整流网络表示的函数可能需要浅层网络(一个隐含层)指数级的隐藏单元才能表示。
根据经验,更深的模型确实在广泛的任务中泛化得更好。
6.4.2 其他架构上的考虑
上述考虑的是简单的链式结构。在实践中,神经网络具有多样性。
用于计算机视觉的卷积神经网络的特殊架构在 第9章 中介绍。
前馈网络也可以推广到序列处理的循环神经网络,但有它们自己的架构考虑,将在第10章中介绍。
架构设计考虑的另一个关键点是如何将层与层之间连接起来。
6.5 反向传播和其他的微分算法
6.5.1 计算图
图中每个节点表示一个变量。
6.5.2 微积分中的链式法则
从标量扩展到向量的链式法则。
假设$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}$$
使用向量记法,可以等价地写成:
$$\triangledown_xz = (\frac {\partial y}{\partial x})^T \triangledown_yz$$
这里的$\frac {\partial y}{\partial x}$是$g\ $的$n\times m $的Jacobian
矩阵。
还可以从向量扩展到张量。
6.5.3 递归地使用链式法则来实现反向传播
6.5.4 全连接MLP中的反向传播计算
算法6.2反向传播时,偏导数的计算。
算法6.3是前向传播和代价函数的计算。
6.5.5 符号到符号的导数
符号表示
反向传播的方法。
1 符号到数值的微分:计算图和一组用于图的输入的数值
2 符号到符号的方法:采用计算图和添加额外的节点到计算图中,这些额外的节点提供了我们所需导数的符号描述。
6.5.6 一般化的反向传播
6.5.7 实例:用于MLP训练的反向传播
训练多层感知机
交叉熵代价函数
6.5.8 复杂化
操作返回多个张量。反向传播的内存消耗、现实实现。
6.5.9 深度学习界外的微分
自动微分领域关系如何以算法方式计算微分。
这里描述的反向传播算法只是自动微分算法的一种方法。
反向模式累加和前向模式累加。
Theano
和TensorFlow
的实现使用基于匹配已知简化模式的试探法,以便重复地尝试去简化图。
在机器学习以外的社区,更常见的 是使用传统的编程语言来直接实现微分软件。例如用Python
或者C
来编程
6.5.10 高阶微分
一些软件框架支持高阶导数。在深度学习软件框架中,这至少包括Theano
和TensorFlow
。
在深度学习的相关领域,很少会计算标量函数的单个二阶导数。相反,我们通常对Hessian
矩阵的性质比较感兴趣。如果有函数$f:\mathbb{R}^n \to R$,那么Hessian
矩阵的大小为$n\times n$。在典型的深度学习应用中,n将是模型的参数数量,可能很容易达到数十亿。因此,完整的Hessian
矩阵甚至不能表示。
典型的深度学习方法是使用Krylov
方法,而不是显式地计算Hessian
矩阵。
Hessian
矩阵上使用Krylov
方法,只需要计算Hessian
矩阵$H$和一个任意向量$v$间的乘积即可。
6.6 历史小记
线性 -> 非线性
反向传播
现代前馈网络的核心思想
交叉熵损失函数
分段线性隐藏单元(整流线性单元ReLU)