反向传播算法
约定
首先我们对数学符号做一些约定。
- 粗体的小写字母表示列向量,如 x,xi,δ 等;
- 粗体的大写字母表示矩阵,如 A,W,Δ 等;
- 常规字体表示标量或函数,如 α,i,xjp,f 等;
- 当 x 表示神经网络的某一层的激活前的值时,我们用 x¯¯¯ 表示激活后的值;
- 上标指示神经网络的层数。例如 xi 表示神经网络的第 i 层的激活前的值;
- 下标作为向量或矩阵的索引,例如
xi 表示向量 x 的第 i 个元素,Wij 表示矩阵 W 的 (i,j) 元; W⋅,i 表示矩阵 W 的第 i 列,Wi,⋅ 表示矩阵 W 的第 i 行;为简单起见,Wi,⋅ 可简记为 Wi ; - 左上标指示样本实例,例如 ix 表示第 i 个实例。
- 以上表示是可以组合的,如果组合后有意义的话。例如
jxi¯¯¯¯¯ 表示输入第 j 个实例时,神经网路的第i 层的输出。
标准前馈神经网络
我们首先考虑简单的情况:前馈神经网络,如图
???
所示。我们先假设任意两层之间没有权值共享。方向传播算法本质上就是梯度下降算法,所以我们要对损失函数关于每个参数求导。设单个输入实例
x
损失函数为
J(x)
, 那么我们要求解
∂J∂Wi
和
∂J∂bi
,
i=1,2,…,n
. 对
J
关于
∂J∂bi=∂xi∂bi⋅∂J∂xi=I∂J∂xi=∂J∂xi(1)
我们可以证明
∂J∂Wi=∂J∂xix(i−1)¯¯¯¯¯¯¯¯T(2)
这是因为
==∂J∂Wipq=∂xi∂Wipq∂J∂xi∑j∂xij∂Wipq∂J∂xijxi−1q¯¯¯¯¯¯∂J∂xip
所以关键是求解 ∂J∂xi . 由链式法则(注意这里是使用的标量函数对矩阵或向量求到的链式法则,求导顺序不可交换),有
∂J∂xi=∂xn∂xi====∂xn∂xi∂J∂xn∂xn−1∂xi∂xn∂xn−1∂xn−2∂xi∂xn−1∂xn−2∂xn∂xn−1 ⋯∂xi+1∂xi∂xi+2∂xi+1⋯∂xn∂xn−1(3)(4)
所以,由公式 (1), (3) 和 (4) 得
∂J∂bi=∂J∂xi=∂xi+1∂xi∂xi+2∂xi+1⋯∂xn∂xn−1⋅∂J∂xn(5)
由公式 (2)–(4) 得
∂J∂Wi=∂xi+1∂xi∂xi+2∂xi+1⋯∂xn∂xn−1Ai⋅∂J∂xnδn⋅x(i−1)¯¯¯¯¯¯¯¯T(6)
其中
∂xj+1∂xj=diag(f˙j(xj))W(j+1)T
公式 (6) 中 δn 的计算是容易的,因为 xn 靠近网络的输出端,一般而言 J 是
公式 (6) 中 Ai 是一系列的Jaccobian矩阵的乘积。结合图1,我们可以从网络的输出端到输入端的方向依次计算这些Jaccobian矩阵,并累乘之得到 Aj,j=n−1,n−2,…,1 . 但是这样做的计算量太大,因为它涉及一列的矩阵与矩阵的乘积,我们不会显示的计算矩阵 Ai , 而是依次计算 δj,j=n−1,n−2,…,1
δj=∂xj+1∂xjδj+1=diag(f˙j(xj))W(j+1)Tδj+1
最后得到
∂J∂Wi=∂J∂bi=δix(i−1)¯¯¯¯¯¯¯¯Tδi
另一点值得注意是,通常我们不会每观察到一个实例就更新权值,而是对每 m>1 个实例计算一次梯度,更新一次权值。例如,我们从训练集中每抽取 m 个样本
∂L∂bi=∂L∂Wi=1m∑j=1mAi∂J(jx)∂xn1m∑j=1mAi∂J(jx)∂xn⋅jx(i−1)¯¯¯¯¯¯¯¯¯¯T(7)(8)
在实践中,我们一般都是按照 (7) 和 (8) 上面两式求参数的梯度,进而更新网络的权值。注意矩阵按不同的顺序求值,时间复杂度是不同的,千万不要显示的计算 Ai .
如果定义
Xi=Δi=(1xi,2xi,…,mxi)(1δi,2δi,…,mδi)
那么
∂J∂Wi=∂J∂bi=ΔiX(i−1)TΔi
非标准前馈神经网络
权值共享情况
下面我们考虑有权值共享的情况。我们可以证明,当有权值共享的时候,网络可以如同没有权值共享一样地更新。如图 2 所示,不失一般性,不妨假设除了图 2 所示的
z
层和
y
层共享权值矩阵
W
之外,没有其他权值共享;设所有的激活函数都是
f
.
所以
∂J∂W=∂J∂zh¯¯¯T+∂J∂yx¯¯¯T
同理,如果偏置共享的话,对偏置的导数也有类似的性质。
因为 ∂J∂W 可以写为没有权值共享时,损失函数关于对应位置的权值矩阵的导数之和,所以对该网络更新权值,可以如同没有权值共享一样地更新。
图结构的前馈神经网络
未完待续……