花书笔记:第06章 深度前馈网络
-
深度前馈网络 也叫前馈神经网络、多层感知机
-
深度前馈网络的目标:
定义一个映射 y = f ( x ; θ ) \pmb y=f(\pmb x;\pmb \theta) yyy=f(xxx;θθθ) ,并学习参数 θ \pmb \theta θθθ ,使它能够得到最佳近似。例如分类任务,将输入 x \pmb x xxx 映射到一个类别 y y y 。
-
前馈神经网络组成结构:输入层 + 隐藏层 + 输出层
6.1 实例:学习 XOR 函数
-
问题描述
1) XOR 问题即,异或问题。给定两个输入 x 1 , x 2 x_1,x_2 x1,x2 取值为 0 或 1;当 x 1 = x 2 x_1=x_2 x1=x2时, y = 1 y=1 y=1 否则 y = 0 y=0 y=0 。
2) 数据集 X = { [ 0 , 0 ] T , [ 0 , 1 ] T , [ 1 , 0 ] T , [ 1 , 1 ] T } \mathbb{X}=\{[0,0]^T,[0,1]^T,[1,0]^T,[1,1]^T\} X={[0,0]T,[0,1]T,[1,0]T,[1,1]T}; Y = { 0 , 1 , 1 , 0 } \mathbb{Y}=\{0,1,1,0\} Y={0,1,1,0}。
-
定义模型
-
上图中左图是对数据集 X = { [ 0 , 0 ] T , [ 0 , 1 ] T , [ 1 , 0 ] T , [ 1 , 1 ] T } \mathbb{X}=\{[0,0]^T,[0,1]^T,[1,0]^T,[1,1]^T\} X={[0,0]T,[0,1]T,[1,0]T,[1,1]T}; Y = { 0 , 1 , 1 , 0 } \mathbb{Y}=\{0,1,1,0\} Y={0,1,1,0} 的图形描述。
-
对于左图原始空间,线性模型不能够学习到正确的分类模型 (不能用一条直线将两个类别的数据划分开)。
-
因此,我们想对原始输入数据做一个映射,转换为类似右图的空间,即 x → h \pmb x \rightarrow \pmb h xxx→hhh 的映射。此时就可以用线性模型完成划分了。
-
上图就是我们定义的用于该问题的前馈神经网络,左右两部分是模型的不同画法。
-
x 1 , x 2 → h 1 , h 2 x_1,x_2 \rightarrow h_1,h_2 x1,x2→h1,h2 之间就是 x → h \pmb x \rightarrow \pmb h xxx→hhh 的映射,箭头代表了映射权重(参数)。神经网络具有学习能力,所以我们希望网络能够学习参数 W \pmb W WWW 使得 f ( 1 ) : h = max { 0 , x W + c } f^{(1)}: \quad \pmb h = \max\{0,\pmb {x W} + \pmb c\} f(1):hhh=max{0,xWxWxW+ccc} 。
-
为什么要使用 f ( 1 ) f^{(1)} f(1) 这样的函数呢 ?
忽略截距;若 f ( 1 ) f^{(1)} f(1)仍为线性函数,则 y = h w \pmb y = \pmb {h w} yyy=hwhwhw 也为线性,则 y = x W w \pmb y = \pmb {xWw} yyy=xWwxWwxWw 。令 w ′ = W w \pmb {w' = Ww } w′=Www′=Www′=Ww,则 y = x w ′ \pmb y = \pmb {x w'} yyy=xw′xw′xw′ 仍为线性模型,肯定不能满足期望。
所以,我们在 x → h \pmb x \rightarrow \pmb h xxx→hhh 映射中加入了 激活函数 整流线性单元(ReLU): max { 0 , f ( x ) } \pmb {\max \{0,f(x)\}} max{0,f(x)}max{0,f(x)}max{0,f(x)} ,来使其变为非线性模型。
-
第 5 步可以学将 x \pmb x xxx 映射到 h \pmb h hhh 空间了,接下来我们也想学习线性模型 f ( 2 ) : y = h w + b f^{(2)}: \quad \pmb y = \pmb {h w} + \pmb b f(2):yyy=hwhwhw+bbb,使得能够正确划分映射到 h \pmb h hhh 空间的数据。
-
从上面的步骤可以看出,该模型的函数形式为:
f ( x , W , c , w , b ) = max { 0 , x W + c } w + b f(x,\pmb W,\pmb c,\pmb w,b)=\max\{0,\pmb {x W} + \pmb c\}\pmb w + b f(x,WWW,ccc,www,b)=max{0,xWxWxW+ccc}www+b
-
-
选择损失函数
注: 如 式 6.1 该问题选用了 均方误差(MSE) 作为损失函数,但是对于 二进制数据问题建模,在应用领域 MSE 通常不合适,加合适的方法在6.2.2.2节 。本文在此处使用 MSE 是为了简化数学问题。
-
求解
花书给出了该问题解的参数 (参数由网络学习得到):
验证一下这个解是否能够正确划分数据集;以及先来了解一下神经网络的正向传输过程。
X T = [ 0 0 0 1 1 0 1 1 ] \pmb {X^T}=\begin{bmatrix} 0&0 \\ 0&1 \\ 1&0 \\ 1&1 \end{bmatrix} XTXTXT=⎣⎢⎢⎡00110101⎦⎥⎥⎤
首先,输入层向隐藏层传输 ( x → h \pmb x \rightarrow \pmb h xxx→hhh) ,计算 h = max { 0 , X T W + c } \pmb h = \max\{0,\pmb {X^T W} + \pmb c\} hhh=max{0,XTWXTWXTW+ccc}:
h = [ 0 0 1 0 1 0 2 1 ] \pmb h=\begin{bmatrix} 0 & 0 \\ 1 & 0 \\ 1 & 0 \\ 2 & 1 \end{bmatrix} hhh=⎣⎢⎢⎡01120001⎦⎥⎥⎤
然后,隐藏层向输出层传输 ( h → y \pmb h \rightarrow \pmb y hhh→yyy),计算 y = h w + b \pmb y = \pmb {h w} + \pmb b yyy=hwhwhw+bbb
y = [ 0 1 1 0 ] \pmb y = \begin{bmatrix} 0 \\ 1 \\ 1 \\ 0 \end{bmatrix} yyy=⎣⎢⎢⎡0110⎦⎥⎥⎤
可看出网络的预测值与实际值相同。
6.2 基于梯度的学习
-
基于梯度学习的主要步骤:
定义代价函数;梯度计算;反向传播(更新参数)
6.2.1 代价函数
6.2.1.1 使用最大似然条件分布
-
大多数神经网络使用最大似然来训练,该方法会得到一个完整的概率分布。
-
使用最大似然的优势是,确定了模型 p ( y ∣ x ) p(y|x) p(y∣x) 后,代价函数 l o g ( p m o d e l ( y ∣ x ) ) log(p_{model}(\pmb y|\pmb x)) log(pmodel(yyy∣xxx)) 也就确定了。减少了设计代价函数的负担。
-
最大似然的代价函数
- 上式就是最大似然的代价函数 负对数似然
- 它与训练数据和模型分布间的交叉熵等价。
- E x , y ~ p ^ d a t a \mathbb{E}_{{x,y}~\hat p_{data}} Ex,y~p^data 表示求平均
- 代价函数的具体形式取决于 l o g ( p m o d e l ( y ∣ x ) ) log(p_{model}(\pmb y|\pmb x)) log(pmodel(yyy∣xxx))
-
例:求代价函数
若 p m o d e l ( y ∣ x ) = N ( y ; f ( x ; θ ) , I ) = 1 2 π e − ( y − f ( x ; θ ) ) 2 2 p_{model}(\pmb y|\pmb x)=N(\pmb y;f(\pmb x; \pmb \theta),\pmb I)=\frac{1}{\sqrt {2\pi}}e^{- \frac{(y-f( x;\theta))^2}{2}} pmodel(yyy∣xxx)=N(yyy;f(xxx;θθθ),III)=2π1e−2(y−f(x;θ))2 (高斯分布) ;
则 l o g ( p m o d e l ( y ∣ x ) ) = − 1 2 ∣ ∣ y − f ( x ; θ ) ∣ ∣ 2 + l o g ( 1 2 π ) log(p_{model}(\pmb y|\pmb x))= -\frac {1}{2} ||y-f(\pmb x;\pmb \theta)||^2 + log(\frac {1}{\sqrt {2 \pi}}) log(pmodel(yyy∣xxx))=−21∣∣y−f(xxx;θθθ)∣∣2+log(2π1) 。
所以带入 式 6.12,
J ( θ ) = 1 2 E x , y ~ p ^ d a t a ∣ ∣ y − f ( x ; θ ) ∣ ∣ 2 + c o n s t J(\theta)=\frac{1}{2}\mathbb{E}_{{x,y}~\hat p_{data}}||\pmb y - f(\pmb x; \pmb \theta)||^2 + const J(θ)=21Ex,y~p^data∣∣yyy−f(xxx;θθθ)∣∣2+const
6.2.1.2 学习条件统计量
-
该方法不是学习整个概率分布 ( p ( y ∣ x ) p(\pmb y | \pmb x) p(yyy∣xxx)),而是学习给定 x \pmb x xxx 时, y \pmb y yyy 的某个条件统计量 (如 学习 y \pmb y yyy 的均值,中位数)
-
泛函:
- 学习条件统计量的代价函数叫做 泛函。
- 泛函是函数到实数的映射,即泛函中包含的函数簇,都对应着一个实数。我们的目的就是找到我们需要的统计量所对应的函数。
- 设计代价泛函的时候要遵循代价泛函在所求函数处取得最小值。
- 从映射中找到的函数,就对应着我们想要的那个统计量。
- 对函数求解优化时要用到 变分法 。
-
两个常见统计量
最小化均方误差
最小化均方误差可以得到用来预测 对每个 x \pmb x xxx 预测 y \pmb y yyy 的均值的函数。平均绝对误差
最小化平均绝对误差可以用来预测 对每个 x \pmb x xxx 预测 y \pmb y yyy 的中位数的函数。
与交叉熵对比
均方误差 和 平均绝对误差 的代价函数在饱和输出单元 的梯度很小,所以使用梯度优化时往往效果不佳。因此,即使没必要估计整个概率分布 ( p ( y ∣ x ) p(\pmb y | \pmb x) p(yyy∣xxx)),交叉熵代价函数也更受欢迎。
6.2.2 输出单元
本节中讨论的所有问题都在隐藏层的输出特征 h = f ( x ; θ ) \pmb h=f(\pmb x;\pmb \theta) hhh=f(xxx;θθθ) 上进行,输出层将在隐层输出的基础上进行进一步的处理。
6.2.2.1 用于高斯输出分布的线性单元
-
该方法处理 h \pmb h hhh 是基于线性变换的,所以成为线性单元。输出层输出结果为:
y ^ = W T h + b \pmb {\hat y}=\pmb {W^Th} + \pmb b y^y^y^=WThWThWTh+bbb
因为示是线性,所以该种方法输出层没有使用激活函数 -
线性输出层常被用来产生条件高斯分布的均值:
p ( y ∣ x ) = N ( y ; y ^ , I ) p(\pmb{y|x}) = N(\pmb y;\pmb {\hat y},\pmb I) p(y∣xy∣xy∣x)=N(yyy;y^y^y^,III)
产生条件高斯分布的均值,即 p ( y ∣ x ) p(\pmb y| \pmb x) p(yyy∣xxx) 符合均值为 y ^ \hat y y^ 方差为 I I I 的高斯分布。 -
此时最大化似然等价于最小化均方误差,6.2.1.1 节 示例 中已证明。
-
线性单元不会饱和,所以易于采用基于梯度的优化算法,甚至更多方法。
6.2.2.2 用于 Bernoulli 输出分布的 sigmoid 单元
-
Bernoulli 输出分布主要用于预测二值型 y ∈ [ 0 , 1 ] y \in [0,1] y∈[0,1] 的值。一般用于二分类问题。该种类型的网络输出只有一个神经元 sigmoid 激活函数 作用于该神经元 。
-
网络只需要预测 P ( y = 1 ∣ x ) P(y=1|\pmb x) P(y=1∣xxx) 的概率即可。
-
Bernoulli 输出分布一般与 sigmoid 以及最大似然结合使用:
y ^ = σ ( z ) = 1 1 + e − z \hat y = \sigma(z)=\frac{1}{1+e^{-z}} y^=σ(z)=1+e−z1P ( y ∣ x ) = σ ( ( 2 y − 1 ) z ) P(y|\pmb x) = \sigma((2y-1)z) P(y∣xxx)=σ((2y−1)z)
z = w T h + b z = \pmb w^T \pmb h + b z=wwwThhh+b
-
损失函数
J ( θ ) = − l o g ( P ( y ∣ x ) ) = s o f t p l u s ( ( 1 − 2 y ) z ) \pmb {J(\theta)} = -log(P(y|\pmb x))=softplus((1-2y)z) J(θ)J(θ)J(θ)=−log(P(y∣xxx))=softplus((1−2y)z)s o f t p l u s ( x ) = l o g ( 1 + e x p ( x ) ) softplus(x) = log(1+exp(x)) softplus(x)=log(1+exp(x))
编程实现时,为了避免数值问题,最好将负的对数似然写作 z z z 的函数,而不是 y ^ = σ ( z ) \hat y= \sigma(z) y^=σ(z) 的函数。
6.2.2.3 用于 Multinoulli 输出分布的 softmax 单元
-
公式
z = W T h + b s o f t m a x ( z ) i = e x p ( z i ) ∑ j = 1 n e x p ( z j ) ∑ i = 1 n s o f t m a x ( x i ) = 1 \pmb z = \pmb W^T \pmb h + \pmb b \\ \quad\\ softmax(\pmb z)_i = \frac{exp(z_i)}{\sum_{j=1}^n exp(z_j)} \\ \quad\\ \sum _{i=1}^{n}softmax(x_i) =1 zzz=WWWThhh+bbbsoftmax(zzz)i=∑j=1nexp(zj)exp(zi)i=1∑nsoftmax(xi)=1 -
负对数似然(优化目标)
l o g [ s o f t m a x ( z ) i ] = − [ z i − l o g ∑ j e x p ( z i ) ] log[softmax(\pmb z)_i] = -\left[ z_i - log \sum_j exp(z_i) \right] log[softmax(zzz)i]=−[zi−logj∑exp(zi)] -
softmax 函数用于 n 分类,神经网络输出层也会有 n 个神经元 (n > 2)。
-
除对数似然之外的许多目标函数对 softmax 函数不起作用,所以一般情况下使用对数作为目标函数。
6.2.2.4 其他的输出类型
-
混合密度网络
高斯混合输出在 语音生成模型 和 物理运动 中特别有效。
6.3 隐藏单元
如何选择隐藏单元的类型
- 整流线性单元(ReLU),通常是隐藏单元极好的默认选择。
- 除非另有说明,否则隐藏单元一般由仿射变换 z = W T h + b \pmb z = \pmb W^T \pmb h + \pmb b zzz=WWWThhh+bbb 和 激活函数 g ( z ) g(\pmb z) g(zzz)。
6.3.1 整流线性单元及其扩展
-
ReLU 激活函数
g ( z ) = max { 0 , z } g(z)= \max \{0, z\} g(z)=max{0,z} -
初始化网络时,可以将偏置 b全都设置成一个小的正值 如 0.1,这可能会使 ReLu函数 在初始时对大多数数据集都处于激活状态,并且允许导数通过。
-
缺陷
不能通过基于梯度的方法学习到那些激活为 0 的样本,即 z < 0 z<0 z<0 时。
-
整流线性单元(ReLU)扩展
-
ReLU 3 个扩展都是基于 g ( z , α ) i = max ( 0 , z i ) − α i min ( 0 , z i ) g(\pmb z, \pmb \alpha)_i = \max(0,z_i) - \alpha_i\min(0,z_i) g(zzz,ααα)i=max(0,zi)−αimin(0,zi) 的形式。
-
绝对值整流
g ( z , α ) i = max ( 0 , z i ) − min ( 0 , z i ) g(\pmb z, \pmb \alpha)_i = \max(0,z_i) - \min(0,z_i) g(zzz,ααα)i=max(0,zi)−min(0,zi)
等价于 ∣ z i ∣ |z_i| ∣zi∣ 。它用于图像中的对象识别,其中寻找在输入照明极性反转下不变的特征是有意义的。
-
渗漏整流线性单元
是将 α i \alpha_i αi 固定成类似 0.01 的小值。 -
参数化整流线性单元(PReLU)
将 α i \alpha_i αi 作为学习的参数。 -
maxout单元
- maxout 将
z
\pmb z
zzz 划分为了 k 组,并输出每组的最大元素。
g ( z ) i = max j ∈ G ( i ) z j , j 表 示 组 别 g(\pmb z)_i = \max_{j\in\mathbb{G}^{(i)}}z_j,\quad j 表示组别 g(zzz)i=j∈G(i)maxzj,j表示组别
- maxout 将
z
\pmb z
zzz 划分为了 k 组,并输出每组的最大元素。
-
6.3.2 logistic sigmoid 与双曲正切函数
-
logistic sigmoid
g ( z ) = σ ( z ) = 1 1 + e − z g(z) = \sigma(z)=\frac{1}{1+e^{-z}} g(z)=σ(z)=1+e−z1
-
双曲正切 (tanh)
g ( z ) = t a n h ( z ) = 1 − e − 2 z 1 + e − 2 z = 2 σ ( 2 z ) − 1 g(z) = tanh(z) = \frac{1-e^{-2z}}{1 + e^{-2z}}=2\sigma(2z)-1 g(z)=tanh(z)=1+e−2z1−e−2z=2σ(2z)−1
-
由于 sigmoid 函数饱和性问题,当必须要使用 sigmoid 函数时,tanh 函数通常要比 sigmoid 表现更好,训练更加容易。
6.3.3 其他隐藏单元
-
softmax 单元也可以在隐藏层处使用。将在 10.2节 讲述。
-
径向基函数(RBF)
h i = e x p ( − 1 σ i 2 ∣ ∣ W : , i − x ∣ ∣ ) h_i = exp(-\frac{1}{\sigma_i^2}||\pmb W_{:,i}-\pmb x||) hi=exp(−σi21∣∣WWW:,i−xxx∣∣)
很难优化 -
softplus 函数
s o f t p l u s ( a ) = l o g ( 1 + e a ) softplus(a) = log(1+e^a) softplus(a)=log(1+ea)
ReLU 的平滑版本,但并不如 ReLU 效果好。 -
硬双曲正切函数
g ( a ) = max ( − 1 , m i n ( 1 , a ) ) g(a) = \max (-1,min(1,a)) g(a)=max(−1,min(1,a))
6.4 架构设计
架构指网络的整体结构,他应该具有多少单元,以及这些单元应该如何连接。
6.4.1 万能近似性质和深度
-
万能近似定理
一个前馈神经网络如果具有线性输出层和至少一层具有任何人“挤压”性质的激活函数的隐藏层,只要给予网络足够数量的隐藏单元它可以以任意的精度来近似任何从一个有限维空间到另一个有限维空间的 Borel 可测函数。前馈网络的导数也可以任意好地来近似函数地导数。(一个大的 MLP 一定能表示任何函数,但不一定被学习到。)
-
在很多情况下,使用更深地模型能够减少表示期望函数所需的单元的数量,并且可以减少泛化误差。
6.4.2 其他架构上的考虑
- 一般的神经网络都是层与层之间的链式结构。但在神经网络构建具有较大的灵活性,并不一定是层间依次连接,有时为了使网络更有利于处理某一领域的问题,也可以进行其他操作。如跳跃链接等。
6.5 反向传播和其他微分算法
-
前向传播
输入 x \pmb x xxx ,然后传播到每一层的隐藏单元,最终产生输出 y ^ \pmb {\hat y} y^y^y^ 。
-
反向传播
根据代价函数 J ( θ ) J(\theta) J(θ) 计算出的 误差 并从输出层依次反向求梯度更新参数。
6.5.1 计算图
-
作用:利用计算图表示的运算,更直观,也更容易手动求解梯度进行反向传播。
-
计算图
6.5.2 微积分的链式法则
- 设
y
=
g
(
x
)
\pmb y=g(\pmb x)
yyy=g(xxx) 并且
z
=
f
(
y
)
z = f(\pmb y)
z=f(yyy) 则
▽
x
z
\triangledown_{\pmb x}z
▽xxxz 求解公式如下:
6.5.3 递归的使用链式法则来实现反向传播
6.5.4 全连接 MLP 中的反向传播计算
-
多层MLP的正向传播
-
MLP 的反向传播
6.5.5 符号到符号的导数
-
采用了计算图以及添加一些额外的节点到计算图中,这些额外的节点提供了我们所需导数的符号描述。
-
计算图求导
该方法的优点是导数可以使用与原始表达式相同的语言来描述。因为导数只是另外一张计算图,我们可以再次运行反向传播。
6.5.6 一般化的反向传播
-
Jacobian矩阵
雅可比矩阵,是指函数的一阶偏导数以一定方式排列成的矩阵。如在神经网络中计算图中 z 的每个父节点的梯度组成的矩阵。
-
一般化的反向传播算法
整体流程:
build_grad 方法:
-
get_operation(V):返回用于计算 V 的的操作符,代表了在计算图中流入 V 的边。
-
get_consumers(V, G G G):返回一组变量,是计算图 G G G 中 V 的子节点。
-
get_inputs(V, G G G):返回一组变量,是计算图 G G G 的中 V 的父节点。
-
op.bprop(inputs, X, G)
∑ i ( ▽ X o p . f ( i n p u t s ) i ) G i \sum_i(\triangledown_{X}op.f(inputs)_i)G_i i∑(▽Xop.f(inputs)i)Gi
inputs 是提供给操作的一组输入; o p . f op.f op.f 是操作符对应的函数;输入 X 是指我们想要计算关于他的梯度;G 是操作对于输出的梯度。
-
6.5.7 实例:用于 MLP 训练的反向传播
-
架构说明
-
本例中 MLP 只具有一个隐层。
-
使用小批量梯度下算法(SGD)。
-
使用 ReLU 作为隐层激活函数。
-
输出层使用线性映射,不使用激活函数。
-
输出层代价函数使用 交叉熵 + 正则项:
J = J M L E + λ ( ∑ i , j ( W i , j ( 1 ) ) 2 + W i , j ( 2 ) ) 2 ) J=J_{MLE} + \lambda(\sum_{i,j}(W_{i,j}^{(1)})^2 + W_{i,j}^{(2)})^2) J=JMLE+λ(i,j∑(Wi,j(1))2+Wi,j(2))2)
-
-
MLP 的计算图
- 根据计算图我们可以去求 ▽ W ( 1 ) J \triangledown_{W^{(1)}}\pmb J ▽W(1)JJJ 和 ▽ W ( 2 ) J \triangledown_{ W^{(2)}}\pmb J ▽W(2)JJJ。
- 值得注意的是在求 ▽ W ( 1 ) J \triangledown_{ W^{(1)}}\pmb J ▽W(1)JJJ 和 ▽ W ( 2 ) J \triangledown_{W^{(2)}}\pmb J ▽W(2)JJJ 都有两条路径,我们需要求解每个路径的梯度,然后相加就是我们所求。
- 计算图的求梯度方法见 6.5.5 节。
6.6 历史小记
- 交叉熵损失函数 大大提高了具有 sigmoid 和 softmax 输出的模型性能。而均方误差损失时会 存在饱和 和 学习缓慢 的问题。
- 一般情况下使用整流非线性 比 使用sigmoid 网络性能更好。
- 神经网络非常小时,sigmoid表现比整流非线性更好。