MP 模型
神经元是神经网络的基本单元,每个神经元都与其它神经元相连。当神经元兴奋时,就会向与之相连的神经元传递化学物质,从而改变其它神经元内的电位。当神经元内的点位超过阈值时,它就会兴奋起来,向其它神经元发送化学物质。
基于以上认识,1943年,生理学家麦卡洛克和数学家匹兹合作发表论文 《A Logical Calculus of the Ideas Immanent in Nervous Activity》,该论文提出了麦卡洛克—匹兹模型(McCulloch-Pitts model 简称MP模型),该模型的提出是人工神经网路研究的起点。在该模型中,神经元收到来自其它
n
n
n 个神经元的信号,将这些信号作带权加和,然后减去阈值并送入激活函数(activation function),最终将激活函数值作为输出。以下是该模型的示意图。
我们将
w
i
w_i
wi 作为某个输入的权重,
θ
\theta
θ 作为阈值,
A
A
A 作为激活函数,则 MP 模型的公式如下:
y
=
A
(
∑
i
=
1
n
w
i
⋅
x
i
−
θ
)
y=A\left(\sum_{i=1}^nw_i\cdot x_i-\theta\right)
y=A(i=1∑nwi⋅xi−θ)
A
(
x
)
=
{
1
,
x
⩾
0
0
,
x
<
0
A(x)= \left\{ \begin{matrix} 1,&x\geqslant0 \\ 0,&x<0 \end{matrix} \right.
A(x)={1,0,x⩾0x<0 通过公式我们可以看出,当输入的带权和大于或等于阈值时,模型输出
1
1
1,代表着神经元被激活,处于兴奋状态;当输入的带权和小于阈值时,模型输出
0
0
0,代表着神经元处于静默状态。
在后来的研究中,研究者们使用了很多其它函数来充当
A
A
A,为了加以规范,学术界将充当
A
A
A 的函数统称为激活函数(activation function)。对于各种激活函数的优劣,我们将在神经网络的激活函数一文中加以讨论。
y
=
A
(
∑
i
=
1
n
w
i
⋅
x
i
+
b
)
y = A \left( \sum_{i=1}^n{w_i \cdot x_i} + b \right)
y=A(i=1∑nwi⋅xi+b) 现在的神经元表达式多采用以上表达式,事实上与 MP 的表达式相差无几,只不过是换了个符号。我们也将采用以上表达式。此外,在上式中
b
b
b 被称为偏置(bias),输入激活函数的值被称为激活值(activation)。
多层前馈神经网络
多层前馈神经网络(multi-layer feedforward neural networks)的结构是一种全连接结构,将数个神经元组成一层,而后多个层叠加组成网络,其中某神经元将上一层所有神经元的输出作为该神经元的输入,即上一层神经元的个数就等于该神经元输入端的个数。如下图所示:
网络虚拟出了输入层来规范输入端的个数,并用最后一层网络层的输出来充当整个网络的输出。所以,网络的输入层没有神经元;其余层都有神经元。因此,在计算神经网络的层数时要除去输入层,如上图就是一个 4 层的神经网络。
前向传播
输入层输入特征(feature),隐藏层逐层计算,最后输出层输出预测(prediction)的过程被称为前向传播。我们不难得出,同一层的神经元是可以并行计算的,不同网络层是串行计算的。利用并行的特点,我们进一步发现某网络层所有神经元的计算可以合并成矩阵计算。设
A
A
A 为激活函数,数学公式如下:
[
y
1
y
2
⋮
y
m
]
=
A
(
[
w
1
,
1
w
1
,
2
⋯
w
1
,
n
w
2
,
1
w
2
,
2
⋯
w
2
,
n
⋮
⋮
⋱
⋮
w
m
,
1
w
m
,
2
⋯
w
m
,
n
]
⋅
[
x
1
x
2
⋮
x
n
]
+
[
b
1
b
2
⋮
b
m
]
)
\left[ \begin{array}{c} y_1\\ y_2\\ \vdots\\ y_m\\ \end{array} \right] = A\left( \left[ \begin{matrix} w_{1,1} & w_{1,2} & \cdots & w_{1,n} \\ w_{2,1} & w_{2,2} & \cdots & w_{2,n} \\ \vdots & \vdots & \ddots & \vdots \\ w_{m,1} & w_{m,2} & \cdots & w_{m,n} \\ \end{matrix} \right] \cdot \left[ \begin{array}{c} x_1\\ x_2\\ \vdots\\ x_n\\ \end{array} \right] + \left[ \begin{array}{c} b_1\\ b_2\\ \vdots\\ b_m\\ \end{array} \right] \right)
⎣
⎡y1y2⋮ym⎦
⎤=A⎝
⎛⎣
⎡w1,1w2,1⋮wm,1w1,2w2,2⋮wm,2⋯⋯⋱⋯w1,nw2,n⋮wm,n⎦
⎤⋅⎣
⎡x1x2⋮xn⎦
⎤+⎣
⎡b1b2⋮bm⎦
⎤⎠
⎞ 其中
m
m
m 为本层神经元的个数,
n
n
n 为上一层神经元的个数,
w
j
,
i
w_{j,i}
wj,i 表示本层第
j
j
j 个神经元中第
i
i
i 个输入端的权重值,
x
i
x_i
xi 是上一层第
i
i
i 个神经元的输出,同时也是本层各神经元的第
i
i
i 个输入,
b
j
b_j
bj 是本层第
j
j
j 个神经元的偏置。公式中由权重构成的矩阵被称为权重矩阵(weight matrix)。
通过上面的公式,我们得出,向网络中输入的特征数据实际是一个向量,网络输出的数据也是一个向量。再进一步,在训练神经网络时,向神经网络中输入的并不仅一个向量;而是将多个向量组成一个矩阵,对应的现实情况就是将多个样本打包成一个批次(batch)。设一个 batch 中包含的向量个数为
h
h
h。我们使用符号
{
k
}
\{k\}
{k} 来标识 batch 中第
k
k
k 个样本产生的结果。某网络层的计算公式如下:
[
y
1
{
1
}
y
1
{
2
}
⋯
y
1
{
h
}
y
2
{
1
}
y
2
{
2
}
⋯
y
2
{
h
}
⋮
⋮
⋯
⋮
y
m
{
1
}
y
m
{
2
}
⋯
y
m
{
h
}
]
=
A
(
[
w
1
,
1
w
1
,
2
⋯
w
1
,
n
w
2
,
1
w
2
,
2
⋯
w
2
,
n
⋮
⋮
⋱
⋮
w
m
,
1
w
m
,
2
⋯
w
m
,
n
]
⋅
[
x
1
{
1
}
x
1
{
2
}
⋯
x
1
{
h
}
x
2
{
1
}
x
2
{
2
}
⋯
x
2
{
h
}
⋮
⋮
⋯
⋮
x
n
{
1
}
x
n
{
2
}
⋯
x
n
{
h
}
]
+
[
b
1
b
1
⋯
b
1
b
2
b
2
⋯
b
2
⋮
⋮
⋯
⋮
b
m
b
m
⋯
b
m
]
)
\left[ \begin{matrix} y_1^{\{1\}}& y_1^{\{2\}}& \cdots& y_1^{\{h\}}\\ y_2^{\{1\}}& y_2^{\{2\}}& \cdots& y_2^{\{h\}}\\ \vdots& \vdots& \cdots& \vdots\\ y_m^{\{1\}}& y_m^{\{2\}}& \cdots& y_m^{\{h\}}\\ \end{matrix} \right] =A\left(\left[ \begin{matrix} w_{1,1}& w_{1,2}& \cdots& w_{1,n}\\ w_{2,1}& w_{2,2}& \cdots& w_{2,n}\\ \vdots& \vdots& \ddots& \vdots\\ w_{m,1}& w_{m,2}& \cdots& w_{m,n}\\ \end{matrix} \right] \cdot \left[ \begin{matrix} x_1^{\{1\}}& x_1^{\{2\}}& \cdots& x_1^{\{h\}}\\ x_2^{\{1\}}& x_2^{\{2\}}& \cdots& x_2^{\{h\}}\\ \vdots& \vdots& \cdots& \vdots\\ x_n^{\{1\}}& x_n^{\{2\}}& \cdots& x_n^{\{h\}}\\ \end{matrix} \right] + \left[ \begin{matrix} b_1&b_1&\cdots&b_1\\ b_2&b_2&\cdots&b_2\\ \vdots&\vdots&\cdots&\vdots\\ b_m&b_m&\cdots&b_m\\ \end{matrix} \right] \right)
⎣
⎡y1{1}y2{1}⋮ym{1}y1{2}y2{2}⋮ym{2}⋯⋯⋯⋯y1{h}y2{h}⋮ym{h}⎦
⎤=A⎝
⎛⎣
⎡w1,1w2,1⋮wm,1w1,2w2,2⋮wm,2⋯⋯⋱⋯w1,nw2,n⋮wm,n⎦
⎤⋅⎣
⎡x1{1}x2{1}⋮xn{1}x1{2}x2{2}⋮xn{2}⋯⋯⋯⋯x1{h}x2{h}⋮xn{h}⎦
⎤+⎣
⎡b1b2⋮bmb1b2⋮bm⋯⋯⋯⋯b1b2⋮bm⎦
⎤⎠
⎞ 通过以上,我们看出神经网络牵扯了大量的矩阵运算,这也就是神经网络依赖显卡的原因。
误差计算
1986 年鲁姆哈特等研究者重新独立地提出 BP(Error Back Propagation) 算法,之所以是“重新独立地提出”,是因为后来发现,类似的算法分别被 Paker 和 Werbos 在 1982 年和 1974 年独立地提出过,只不过当时没能被更多的人发现并受到应有的重视。对于技术类文章,这些背景内容完全可以不提,而笔者搜集这些背景资料地目的就是向研究者的致敬,在学习他们的技术的时候,应当提及他们的名字。BP 算法的巨大贡献在于它提供了一种有效的神经网络的训练方法。BP 算法训练网络得算法主要分为两个步骤——误差计算和反向传播。
误差计算就是计算出一个量,这个量是衡量网络得出的预测值(prediction)与目标值(target)之间差距,该量在学术上被称为损失值(loss)。我们可以直观的去推测出损失值的一个性质,现实中差距只有大和小之分,没有差距为负数的说法,因此损失值是一个非负实数。根据损失值的意义,我们也可知道神经网络训练的最终目标是使损失值在各种情况的值都为
0
0
0,即预测值完全符合目标值。
使用预测值与目标值来计算的函数被称为损失函数(loss function),即衡量预测值与目标值之间差距的方法。函数的大体形式如下:
ℓ
=
L
(
y
^
1
,
y
^
2
,
⋯
,
y
^
m
,
y
1
,
y
2
,
⋯
,
y
m
)
=
记作
L
(
Y
^
,
Y
)
\ell=L\left(\widehat y_1,\widehat y_2,\cdots,\widehat y_m,y_1,y_2,\cdots,y_m\right) \xlongequal{记作}L\left(\widehat Y, Y\right)
ℓ=L(y
1,y
2,⋯,y
m,y1,y2,⋯,ym)记作L(Y
,Y) 其中
y
^
j
\widehat y_j
y
j 为输出层第
j
j
j 个神经元的输出的预测值,
y
j
y_j
yj 为各预测值对应的目标值,
L
L
L 为损失函数,
ℓ
\ell
ℓ 为损失值。由损失值的非负性可知损失函数的值域是非负实数,此外,在反向传播过程中会有对损失函数求偏导的运算,因此损失函数必须可导。
上文中我们谈到在训练时数据是以 batch 为单位送入神经网络的,每个样本都会产生一个损失值,那么我们就会得到多个损失值。为了将其唯一化,常采用平均损失值作为最终的损失值。需要注意的是,在反向传播时,并不是用平均损失值来传播的,而是将多个损失值组成一个向量来传播,我们在下文中将讨论反向传播的矩阵计算形式。设一个 batch 中包含的特征个数为
h
h
h,batch 中第
k
k
k 个样本得出的损失值为
ℓ
{
k
}
\ell^{\{k\}}
ℓ{k},则平均损失值计算公式如下:
ℓ
=
1
h
⋅
∑
k
=
1
h
ℓ
{
k
}
\ell=\frac{1}{h} \cdot \sum_{k=1}^{h}{\ell^{\{k\}}}
ℓ=h1⋅k=1∑hℓ{k} 最原始的 BP 算法使用的损失函数是均方误差(Mean Square Error, MSE),对于 MSE 及其它各类损失函数的讨论,我们将在神经网络的损失函数中加以讨论。
可训练参数的更新
正如 BP 网络的名字来源于 Back Propagation,即反向传播。可以说反向传播算法是 BP 网络的精髓。反向传播算法的基本思想是梯度下降法(gradient descent)。我们知道在数学上某函数的梯度是它的最大方向导数,即函数值增长速度最快的方向。所以当我们沿着梯度的反方向前进时,函数值就会减小。再进一步说,我们沿着损失函数的梯度的反方向前进时,就会使损失值减小。
通过上文我们知道,一个神经元在数学上就是一个函数;进一步理解,一个网络层也可以看成一个向量函数,只不过是以向量作为自变量和因变量;再进一步理解,两层全连接的网络层在数学上就是一个复合的向量函数,网络层一层层的叠加就是函数一层层的复合;最终整个网络就是一个多层复合的向量函数。这个函数输出的向量又被损失函数最终转换为一个数——损失值,那么整个网络就可以看成一个以损失值为因变量的函数。
在反向传播中,只有可训练参数会发生改变,所以此时损失函数的自变量就是全体可训练参数。通过以上的推理,我们可以知道对损失函数应用梯度下降法的过程如下:首先,损失函数对所有可训练参数逐个求偏导;然后,每个偏导带入真值得到具体的偏导数(此时就得到了梯度);最后,让各个可训练参数减去这个偏导数(梯度的反方向就是给各个偏导数加个负号),我们就实现了向梯度的反方向前进。但此时还有一个问题,我们如果向着反方向前进的太多,可能会越过最低点走上另一个陡坡;如果前进的太少,可能会走很多次才能走到最低点。因此需要一个量,来规范我们每次前进的距离。于是,大名鼎鼎的学习率(常记作
λ
\lambda
λ )就诞生了。我们在更新可训练参数时,用可训练参数减去学习率与偏导数的积,这样就实现了对前进距离的规范。
我们可以总结更新某可训练参数的公式,记损失值为
ℓ
\ell
ℓ,某可训练参数为
w
w
w,该可训练参数未更新前的真值为
w
t
w_t
wt,更新后的真值为
w
t
+
1
w_{t+1}
wt+1,向偏导中带入的值的集合为
P
P
P,则公式如下:
w
t
+
1
=
w
t
−
λ
⋅
∂
ℓ
∂
w
∣
P
w_{t+1}=w_t-\lambda\cdot{\left.\frac{\partial \ell}{\partial w}\right|}_P
wt+1=wt−λ⋅∂w∂ℓ∣
∣P 以上基于梯度来更新可训练参数的方法被称为随机梯度下降法(stochastic gradient descent, SGD),也是原始 BP 算法提供的方法。这种基于梯度的用来更新可训练参数的方法被统称为优化器(optimizer),关于各种优化器的优劣,我们将在神经网络的优化器一文中加以讨论。
反向传播
接下来,我们将对损失函数对可训练参数求偏导的过程进行详细展开,以解释反向传播的传播过程。
如图是一个 3 层的网络,神经元输入端的权重用
w
w
w 表示,输出端用
y
y
y 表示。我们接下来只推导损失值
l
l
l 对
w
w
w 的偏导数。不妨将
y
1
y_1
y1、
y
2
y_2
y2、
y
3
y_3
y3、
y
4
y_4
y4、
y
5
y_5
y5、
y
6
y_6
y6作为推导过程中的中间变量。通过上文我们知道损失值是由预测值
y
5
y_5
y5、
y
6
y_6
y6 及其目标值
y
5
′
y_5'
y5′、
y
6
′
y_6'
y6′ 直接计算得来,所以已知:
L
(
y
5
,
y
6
,
y
5
′
,
y
6
′
)
L(y_5,y_6,y_5',y_6')
L(y5,y6,y5′,y6′)则已知:
{
∂
l
∂
y
6
∂
l
∂
y
5
\left\{ \begin{array}{l} \frac{\partial l}{\partial y_6}\\ \frac{\partial l}{\partial y_5} \end{array} \right.
{∂y6∂l∂y5∂l根据神经元表达式可得:
{
y
6
=
A
(
w
11
⋅
y
3
+
w
12
⋅
y
4
+
b
6
)
=
记作
A
(
s
6
)
y
5
=
A
(
w
9
⋅
y
3
+
w
10
⋅
y
4
+
b
5
)
=
记作
A
(
s
5
)
\left\{ \begin{array}{l} y_6=A(w_{11} \cdot y_3+w_{12} \cdot y_4 + b_6)\xlongequal{记作} A(s_6)\\ y_5=A(w_{9} \cdot y_3+w_{10} \cdot y_4 + b_5)\xlongequal{记作} A(s_5) \end{array} \right.
{y6=A(w11⋅y3+w12⋅y4+b6)记作A(s6)y5=A(w9⋅y3+w10⋅y4+b5)记作A(s5)则:
{
∂
ℓ
∂
w
12
=
∂
ℓ
∂
y
6
⋅
A
′
(
s
6
)
⋅
y
4
∂
ℓ
∂
w
11
=
∂
ℓ
∂
y
6
⋅
A
′
(
s
6
)
⋅
y
3
∂
ℓ
∂
w
10
=
∂
ℓ
∂
y
5
⋅
A
′
(
s
5
)
⋅
y
4
∂
ℓ
∂
w
9
=
∂
ℓ
∂
y
5
⋅
A
′
(
s
5
)
⋅
y
3
\left\{ \begin{array}{l} \frac{\partial \ell}{\partial w_{12}}=\frac{\partial \ell}{\partial y_6}\cdot A'(s_6) \cdot y_4 \\ \frac{\partial \ell}{\partial w_{11}}=\frac{\partial \ell}{\partial y_6}\cdot A'(s_6) \cdot y_3 \\ \frac{\partial \ell}{\partial w_{10}}=\frac{\partial \ell}{\partial y_5}\cdot A'(s_5) \cdot y_4 \\ \frac{\partial \ell}{\partial w_{9}}=\frac{\partial \ell}{\partial y_5}\cdot A'(s_5) \cdot y_3 \end{array} \right.
⎩
⎨
⎧∂w12∂ℓ=∂y6∂ℓ⋅A′(s6)⋅y4∂w11∂ℓ=∂y6∂ℓ⋅A′(s6)⋅y3∂w10∂ℓ=∂y5∂ℓ⋅A′(s5)⋅y4∂w9∂ℓ=∂y5∂ℓ⋅A′(s5)⋅y3根据复合函数求偏导法则可得:
{
∂
ℓ
∂
y
4
=
∂
ℓ
∂
y
6
⋅
∂
y
6
∂
y
4
+
∂
ℓ
∂
y
5
⋅
∂
y
5
∂
y
4
∂
ℓ
∂
y
3
=
∂
ℓ
∂
y
6
⋅
∂
y
6
∂
y
3
+
∂
ℓ
∂
y
5
⋅
∂
y
5
∂
y
3
\left\{ \begin{array}{l} \frac{\partial \ell}{\partial y_4}= \frac{\partial \ell}{\partial y_6} \cdot \frac{\partial y_6}{\partial y_4}+ \frac{\partial \ell}{\partial y_5} \cdot \frac{\partial y_5}{\partial y_4} \\ \frac{\partial \ell}{\partial y_3}= \frac{\partial \ell}{\partial y_6} \cdot \frac{\partial y_6}{\partial y_3}+ \frac{\partial \ell}{\partial y_5} \cdot \frac{\partial y_5}{\partial y_3} \end{array} \right.
{∂y4∂ℓ=∂y6∂ℓ⋅∂y4∂y6+∂y5∂ℓ⋅∂y4∂y5∂y3∂ℓ=∂y6∂ℓ⋅∂y3∂y6+∂y5∂ℓ⋅∂y3∂y5根据神经元表达式可得:
{
y
4
=
A
(
w
8
⋅
y
2
+
w
7
⋅
y
1
+
b
4
)
=
记作
A
(
s
4
)
y
3
=
A
(
w
6
⋅
y
2
+
w
5
⋅
y
1
+
b
3
)
=
记作
A
(
s
3
)
\left\{ \begin{array}{l} y_4=A(w_8 \cdot y_2+w_7 \cdot y_1 + b_4)\xlongequal{记作} A(s_4) \\ y_3=A(w_6 \cdot y_2+w_5 \cdot y_1 + b_3)\xlongequal{记作} A(s_3) \end{array} \right.
{y4=A(w8⋅y2+w7⋅y1+b4)记作A(s4)y3=A(w6⋅y2+w5⋅y1+b3)记作A(s3)则:
{
∂
ℓ
∂
w
8
=
∂
ℓ
∂
y
4
⋅
A
′
(
s
4
)
⋅
y
2
∂
ℓ
∂
w
7
=
∂
ℓ
∂
y
4
⋅
A
′
(
s
4
)
⋅
y
1
∂
ℓ
∂
w
6
=
∂
ℓ
∂
y
3
⋅
A
′
(
s
3
)
⋅
y
2
∂
ℓ
∂
w
5
=
∂
ℓ
∂
y
3
⋅
A
′
(
s
3
)
⋅
y
1
\left\{ \begin{array}{l} \frac{\partial \ell}{\partial w_8}=\frac{\partial \ell}{\partial y_4}\cdot A'(s_4) \cdot y_2 \\ \frac{\partial \ell}{\partial w_7}=\frac{\partial \ell}{\partial y_4}\cdot A'(s_4) \cdot y_1 \\ \frac{\partial \ell}{\partial w_6}=\frac{\partial \ell}{\partial y_3}\cdot A'(s_3) \cdot y_2 \\ \frac{\partial \ell}{\partial w_5}=\frac{\partial \ell}{\partial y_3}\cdot A'(s_3) \cdot y_1 \end{array} \right.
⎩
⎨
⎧∂w8∂ℓ=∂y4∂ℓ⋅A′(s4)⋅y2∂w7∂ℓ=∂y4∂ℓ⋅A′(s4)⋅y1∂w6∂ℓ=∂y3∂ℓ⋅A′(s3)⋅y2∂w5∂ℓ=∂y3∂ℓ⋅A′(s3)⋅y1根据复合函数求偏导法则可得:
{
∂
ℓ
∂
y
2
=
∂
ℓ
∂
y
4
⋅
∂
y
4
∂
y
2
+
∂
ℓ
∂
y
3
⋅
∂
y
3
∂
y
2
∂
ℓ
∂
y
1
=
∂
ℓ
∂
y
4
⋅
∂
y
4
∂
y
1
+
∂
ℓ
∂
y
3
⋅
∂
y
3
∂
y
1
\left\{ \begin{array}{l} \frac{\partial \ell}{\partial y_2}= \frac{\partial \ell}{\partial y_4} \cdot \frac{\partial y_4}{\partial y_2}+ \frac{\partial \ell}{\partial y_3} \cdot \frac{\partial y_3}{\partial y_2} \\ \frac{\partial \ell}{\partial y_1}= \frac{\partial \ell}{\partial y_4} \cdot \frac{\partial y_4}{\partial y_1}+ \frac{\partial \ell}{\partial y_3} \cdot \frac{\partial y_3}{\partial y_1} \end{array} \right.
{∂y2∂ℓ=∂y4∂ℓ⋅∂y2∂y4+∂y3∂ℓ⋅∂y2∂y3∂y1∂ℓ=∂y4∂ℓ⋅∂y1∂y4+∂y3∂ℓ⋅∂y1∂y3 从推导过程可以看出,求导过程是从后向前逐层进行的,并且每层的求导过程可以归纳为以下两个工作:
- 根据损失值对本层输出的偏导,求损失值对上一层输出的偏导。
- 根据损失值对本层输出的偏导,求损失值对本层各可训练参数的偏导。
其中 “第一个工作” 用来完成从后向前迭代求导;“第二个工作” 用来完成对各个具体可训练参数的求导。接下来,我们将推导出以上两个工作的矩阵计算形式。
“第一个工作”
通过以上,我们可以总结出 “第一个工作” 的矩阵计算公式如下:
[
∂
ℓ
∂
x
1
∂
ℓ
∂
x
2
⋮
∂
ℓ
∂
x
n
]
=
[
w
1
,
1
w
2
,
1
⋯
w
m
,
1
w
1
,
2
w
2
,
2
⋯
w
m
,
2
⋮
⋮
⋱
⋮
w
1
,
n
w
2
,
n
⋯
w
m
,
n
]
⋅
[
∂
ℓ
∂
y
1
⋅
A
′
(
s
1
)
∂
ℓ
∂
y
1
⋅
A
′
(
s
2
)
⋮
∂
ℓ
∂
y
m
⋅
A
′
(
s
m
)
]
\left[ \begin{matrix} \frac{\partial \ell}{\partial x_1} \\ \frac{\partial \ell}{\partial x_2} \\ \vdots \\ \frac{\partial \ell}{\partial x_n} \end{matrix} \right] = \left[ \begin{matrix} w_{1,1}& w_{2,1}& \cdots& w_{m,1}\\ w_{1,2}& w_{2,2}& \cdots& w_{m,2}\\ \vdots& \vdots& \ddots& \vdots\\ w_{1,n}& w_{2,n}& \cdots& w_{m,n}\\ \end{matrix} \right] \cdot \left[ \begin{matrix} \frac{\partial \ell}{\partial y_1} \cdot A'(s_1)\\ \frac{\partial \ell}{\partial y_1} \cdot A'(s_2) \\ \vdots \\ \frac{\partial \ell}{\partial y_m} \cdot A'(s_m) \end{matrix} \right]
⎣
⎡∂x1∂ℓ∂x2∂ℓ⋮∂xn∂ℓ⎦
⎤=⎣
⎡w1,1w1,2⋮w1,nw2,1w2,2⋮w2,n⋯⋯⋱⋯wm,1wm,2⋮wm,n⎦
⎤⋅⎣
⎡∂y1∂ℓ⋅A′(s1)∂y1∂ℓ⋅A′(s2)⋮∂ym∂ℓ⋅A′(sm)⎦
⎤ 其中
m
m
m 为本层神经元的个数,
n
n
n 为上一层神经元的个数,
w
j
,
i
w_{j,i}
wj,i 表示本层第
j
j
j 个神经元中第
i
i
i 个输入端的权重值,
x
i
x_i
xi 是上一层第
i
i
i 个神经元的输出,同时也是本层各神经元的第
i
i
i 个输入,
θ
j
\theta_j
θj 是本层第
j
j
j 个神经元的阈值,且
s
j
=
∑
i
=
0
n
w
j
,
i
⋅
x
i
−
θ
j
s_j = \sum_{i=0}^{n}{w_{j,i} \cdot x_i}-\theta_j
sj=∑i=0nwj,i⋅xi−θj,式中
A
′
A'
A′ 表示激活函数的导函数。
在正向传播中我们提到样本以 batch 为单位送入网络,那么反向传播时网络也将以 batch 的为单位传播,设一个 batch 中含有
h
h
h 个样本(特征向量),则公式如下:
[
(
∂
ℓ
∂
x
1
)
{
1
}
(
∂
ℓ
∂
x
1
)
{
2
}
⋯
(
∂
ℓ
∂
x
1
)
{
h
}
(
∂
ℓ
∂
x
2
)
{
1
}
(
∂
ℓ
∂
x
2
)
{
2
}
⋯
(
∂
ℓ
∂
x
2
)
{
h
}
⋮
⋮
⋯
⋮
(
∂
ℓ
∂
x
n
)
{
1
}
(
∂
ℓ
∂
x
n
)
{
2
}
⋯
(
∂
ℓ
∂
x
n
)
{
h
}
]
=
[
w
1
,
1
w
2
,
1
⋯
w
m
,
1
w
1
,
2
w
2
,
2
⋯
w
m
,
2
⋮
⋮
⋱
⋮
w
1
,
n
w
2
,
n
⋯
w
m
,
n
]
⋅
[
[
∂
ℓ
∂
y
1
⋅
A
′
(
s
1
)
]
{
1
}
[
∂
ℓ
∂
y
1
⋅
A
′
(
s
1
)
]
{
2
}
⋯
[
∂
ℓ
∂
y
1
⋅
A
′
(
s
1
)
]
{
h
}
[
∂
ℓ
∂
y
2
⋅
A
′
(
s
2
)
]
{
1
}
[
∂
ℓ
∂
y
2
⋅
A
′
(
s
2
)
]
{
2
}
⋯
[
∂
ℓ
∂
y
2
⋅
A
′
(
s
2
)
]
{
h
}
⋮
⋮
⋯
⋮
[
∂
ℓ
∂
y
m
⋅
A
′
(
s
m
)
]
{
1
}
[
∂
ℓ
∂
y
m
⋅
A
′
(
s
m
)
]
{
2
}
⋯
[
∂
ℓ
∂
y
m
⋅
A
′
(
s
m
)
]
{
h
}
]
\left[ \begin{matrix} \left(\frac{\partial \ell}{\partial x_1}\right)^{\{1\}} & \left(\frac{\partial \ell}{\partial x_1}\right)^{\{2\}} & \cdots & \left(\frac{\partial \ell}{\partial x_1}\right)^{\{h\}} \\ \left(\frac{\partial \ell}{\partial x_2}\right)^{\{1\}} & \left(\frac{\partial \ell}{\partial x_2}\right)^{\{2\}} & \cdots & \left(\frac{\partial \ell}{\partial x_2}\right)^{\{h\}} \\ \vdots & \vdots & \cdots & \vdots \\ \left(\frac{\partial \ell}{\partial x_n}\right)^{\{1\}} & \left(\frac{\partial \ell}{\partial x_n}\right)^{\{2\}} & \cdots & \left(\frac{\partial \ell}{\partial x_n}\right)^{\{h\}} \\ \end{matrix} \right] = \left[ \begin{matrix} w_{1,1} & w_{2,1} & \cdots & w_{m,1} \\ w_{1,2} & w_{2,2} & \cdots & w_{m,2} \\ \vdots & \vdots & \ddots & \vdots \\ w_{1,n} & w_{2,n} & \cdots & w_{m,n} \\ \end{matrix} \right] \cdot \left[ \begin{matrix} \left[\frac{\partial \ell}{\partial y_1} \cdot A'(s_1)\right]^{\{1\}} & \left[\frac{\partial \ell}{\partial y_1} \cdot A'(s_1)\right]^{\{2\}} & \cdots & \left[\frac{\partial \ell}{\partial y_1} \cdot A'(s_1)\right]^{\{h\}} \\ \left[\frac{\partial \ell}{\partial y_2} \cdot A'(s_2)\right]^{\{1\}} & \left[\frac{\partial \ell}{\partial y_2} \cdot A'(s_2)\right]^{\{2\}}& \cdots & \left[\frac{\partial \ell}{\partial y_2} \cdot A'(s_2)\right]^{\{h\}} \\ \vdots & \vdots & \cdots & \vdots \\ \left[\frac{\partial \ell}{\partial y_m} \cdot A'(s_m)\right]^{\{1\}} & \left[\frac{\partial \ell}{\partial y_m} \cdot A'(s_m)\right]^{\{2\}} & \cdots & \left[\frac{\partial \ell}{\partial y_m} \cdot A'(s_m)\right]^{\{h\}} \end{matrix} \right]
⎣
⎡(∂x1∂ℓ){1}(∂x2∂ℓ){1}⋮(∂xn∂ℓ){1}(∂x1∂ℓ){2}(∂x2∂ℓ){2}⋮(∂xn∂ℓ){2}⋯⋯⋯⋯(∂x1∂ℓ){h}(∂x2∂ℓ){h}⋮(∂xn∂ℓ){h}⎦
⎤=⎣
⎡w1,1w1,2⋮w1,nw2,1w2,2⋮w2,n⋯⋯⋱⋯wm,1wm,2⋮wm,n⎦
⎤⋅⎣
⎡[∂y1∂ℓ⋅A′(s1)]{1}[∂y2∂ℓ⋅A′(s2)]{1}⋮[∂ym∂ℓ⋅A′(sm)]{1}[∂y1∂ℓ⋅A′(s1)]{2}[∂y2∂ℓ⋅A′(s2)]{2}⋮[∂ym∂ℓ⋅A′(sm)]{2}⋯⋯⋯⋯[∂y1∂ℓ⋅A′(s1)]{h}[∂y2∂ℓ⋅A′(s2)]{h}⋮[∂ym∂ℓ⋅A′(sm)]{h}⎦
⎤
“第二个工作”
我们通过总结上文中的公式,可以得到以下矩阵公式:
[
∂
ℓ
∂
w
1
,
1
∂
ℓ
∂
w
1
,
2
⋯
∂
ℓ
∂
w
1
,
n
∂
ℓ
∂
w
2
,
1
∂
ℓ
∂
w
2
,
2
⋯
∂
ℓ
∂
w
2
,
n
⋮
⋮
⋱
⋮
∂
ℓ
∂
w
m
,
1
∂
ℓ
∂
w
m
,
2
⋯
∂
ℓ
∂
w
m
,
n
]
=
[
∂
ℓ
∂
y
1
⋅
A
′
(
s
1
)
∂
ℓ
∂
y
1
⋅
A
′
(
s
2
)
⋮
∂
ℓ
∂
y
m
⋅
A
′
(
s
m
)
]
⋅
[
x
1
x
2
⋯
x
n
]
\left[ \begin{matrix} \frac{\partial \ell}{\partial w_{1,1}} & \frac{\partial \ell}{\partial w_{1,2}} & \cdots & \frac{\partial \ell}{\partial w_{1,n}} \\ \frac{\partial \ell}{\partial w_{2,1}} & \frac{\partial \ell}{\partial w_{2,2}} & \cdots & \frac{\partial \ell}{\partial w_{2,n}} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{\partial \ell}{\partial w_{m,1}} & \frac{\partial \ell}{\partial w_{m,2}} & \cdots & \frac{\partial \ell}{\partial w_{m,n}} \end{matrix} \right] = \left[ \begin{matrix} \frac{\partial \ell}{\partial y_1} \cdot A'(s_1)\\ \frac{\partial \ell}{\partial y_1} \cdot A'(s_2) \\ \vdots \\ \frac{\partial \ell}{\partial y_m} \cdot A'(s_m) \end{matrix} \right] \cdot \left[ \begin{matrix} x_1 & x_2 & \cdots & x_n \end{matrix} \right]
⎣
⎡∂w1,1∂ℓ∂w2,1∂ℓ⋮∂wm,1∂ℓ∂w1,2∂ℓ∂w2,2∂ℓ⋮∂wm,2∂ℓ⋯⋯⋱⋯∂w1,n∂ℓ∂w2,n∂ℓ⋮∂wm,n∂ℓ⎦
⎤=⎣
⎡∂y1∂ℓ⋅A′(s1)∂y1∂ℓ⋅A′(s2)⋮∂ym∂ℓ⋅A′(sm)⎦
⎤⋅[x1x2⋯xn] 接下来,我们考虑以 batch 形式送入网络时公式的形式。此时我们会有疑问,使用 batch 时,每个样本都会让可训练参数产生一个偏导数值,多个样本就会使可训练参数会同时得到多个偏导数值,那么我们怎么选取最终的偏导数值呢?答案就是平均偏导数值。我们沿用上文中的符号,对于
w
j
,
i
w_{j,i}
wj,i 来说,其平均偏导数值的表达式为:
1
h
∑
k
=
1
h
(
∂
ℓ
∂
w
j
,
i
)
{
k
}
=
记作
g
j
,
i
\frac{1}{h}\sum_{k=1}^h{\left(\frac{\partial \ell}{\partial w_{j,i}}\right)^{\{k\}}} \xlongequal{记作} g_{j,i}
h1∑k=1h(∂wj,i∂ℓ){k}记作gj,i。我们可以得到以下矩阵公式:
[
g
1
,
1
g
1
,
2
⋯
g
1
,
n
g
2
,
1
g
2
,
2
⋯
g
2
,
n
⋮
⋮
⋱
⋮
g
m
,
1
g
m
,
2
⋯
g
m
,
n
]
=
1
h
[
[
∂
ℓ
∂
y
1
⋅
A
′
(
s
1
)
]
{
1
}
[
∂
ℓ
∂
y
1
⋅
A
′
(
s
1
)
]
{
2
}
⋯
[
∂
ℓ
∂
y
1
⋅
A
′
(
s
1
)
]
{
h
}
[
∂
ℓ
∂
y
2
⋅
A
′
(
s
2
)
]
{
1
}
[
∂
ℓ
∂
y
2
⋅
A
′
(
s
2
)
]
{
2
}
⋯
[
∂
ℓ
∂
y
2
⋅
A
′
(
s
2
)
]
{
h
}
⋮
⋮
⋯
⋮
[
∂
ℓ
∂
y
m
⋅
A
′
(
s
m
)
]
{
1
}
[
∂
ℓ
∂
y
m
⋅
A
′
(
s
m
)
]
{
2
}
⋯
[
∂
ℓ
∂
y
m
⋅
A
′
(
s
m
)
]
{
h
}
]
⋅
[
x
1
{
1
}
x
2
{
1
}
⋯
x
n
{
1
}
x
1
{
2
}
x
2
{
2
}
⋯
x
n
{
2
}
⋮
⋮
⋮
⋮
x
1
{
h
}
x
2
{
h
}
⋯
x
n
{
h
}
]
\left[ \begin{matrix} g_{1,1} & g_{1,2} & \cdots & g_{1,n} \\ g_{2,1} & g_{2,2} & \cdots & g_{2,n} \\ \vdots & \vdots & \ddots & \vdots \\ g_{m,1} & g_{m,2} & \cdots & g_{m,n} \\ \end{matrix} \right] = \frac{1}{h} \left[ \begin{matrix} \left[\frac{\partial \ell}{\partial y_1} \cdot A'(s_1)\right]^{\{1\}} & \left[\frac{\partial \ell}{\partial y_1} \cdot A'(s_1)\right]^{\{2\}} & \cdots & \left[\frac{\partial \ell}{\partial y_1} \cdot A'(s_1)\right]^{\{h\}} \\ \left[\frac{\partial \ell}{\partial y_2} \cdot A'(s_2)\right]^{\{1\}} & \left[\frac{\partial \ell}{\partial y_2} \cdot A'(s_2)\right]^{\{2\}}& \cdots & \left[\frac{\partial \ell}{\partial y_2} \cdot A'(s_2)\right]^{\{h\}} \\ \vdots & \vdots & \cdots & \vdots \\ \left[\frac{\partial \ell}{\partial y_m} \cdot A'(s_m)\right]^{\{1\}} & \left[\frac{\partial \ell}{\partial y_m} \cdot A'(s_m)\right]^{\{2\}} & \cdots & \left[\frac{\partial \ell}{\partial y_m} \cdot A'(s_m)\right]^{\{h\}} \end{matrix} \right] \cdot \left[ \begin{matrix} x_1^{\{1\}} & x_2^{\{1\}} & \cdots & x_n^{\{1\}} \\ x_1^{\{2\}} & x_2^{\{2\}} & \cdots & x_n^{\{2\}} \\ \vdots & \vdots & \vdots & \vdots \\ x_1^{\{h\}} & x_2^{\{h\}} & \cdots & x_n^{\{h\}} \end{matrix} \right]
⎣
⎡g1,1g2,1⋮gm,1g1,2g2,2⋮gm,2⋯⋯⋱⋯g1,ng2,n⋮gm,n⎦
⎤=h1⎣
⎡[∂y1∂ℓ⋅A′(s1)]{1}[∂y2∂ℓ⋅A′(s2)]{1}⋮[∂ym∂ℓ⋅A′(sm)]{1}[∂y1∂ℓ⋅A′(s1)]{2}[∂y2∂ℓ⋅A′(s2)]{2}⋮[∂ym∂ℓ⋅A′(sm)]{2}⋯⋯⋯⋯[∂y1∂ℓ⋅A′(s1)]{h}[∂y2∂ℓ⋅A′(s2)]{h}⋮[∂ym∂ℓ⋅A′(sm)]{h}⎦
⎤⋅⎣
⎡x1{1}x1{2}⋮x1{h}x2{1}x2{2}⋮x2{h}⋯⋯⋮⋯xn{1}xn{2}⋮xn{h}⎦
⎤
进阶内容目录
神经网络的激活函数
神经网络的损失函数
神经网络的优化器
神经网络的可训练参数初始化
修订记录
2022.10.31
- 将反向传播中各层的计算工作归纳为两个工作。
- 引入符号 { k } \{k\} {k} 用来标记 batch 中的样本序号。
2022.11.1
- 调整文章结构。
- 增加 “第二个工作” 章节。