前言
推荐系统中,我们通常用深度神经网络(DNN)来学习高阶(非线性)特征。这篇博客中,我们将详细介绍DNN的BP算法。
如果觉得此文过长或者写得不容易懂的,可以看看B站上的一个视频讲解(链接),内容较为简单。
DNN
我们可以将DNN分成三个部分,
- 输入层
- 隐藏层
- 输出层
接下来,我们以三层DNN为例。
1. 输入层
对于输入层,我们假设输入数据
x
x
x有
n
n
n个特征,即
x
=
(
x
(
1
)
,
x
(
2
)
,
.
.
.
,
x
(
n
)
)
x=(x^{(1)}, x^{(2)}, ..., x^{(n)})
x=(x(1),x(2),...,x(n))
2. 第一层隐藏层
第一层隐藏层的输出为 m m m维向量,这样,从输入层到第一层隐藏层,可以看做是从 n n n维到 m m m维的转化。我们需要
- 权重矩阵 W n × m W_{n\times m} Wn×m,将 n n n维列向量转化为隐藏层 m m m维列向量
- 激活函数 σ \sigma σ,对 m m m维列向量的每一个元素做激活处理(常用的激活函数有sigmoid,Relu等)
我们将权重矩阵
W
n
×
m
W_{n\times m}
Wn×m重写为
W
n
×
m
=
(
w
1
,
w
2
,
.
.
.
,
w
m
)
W_{n\times m}=(w_1, w_2, ..., w_m)
Wn×m=(w1,w2,...,wm)
其中,
w
i
w_i
wi为
n
n
n维列向量。这样,第一层隐藏层的输出为
m
m
m维向量
o
u
t
p
u
t
1
=
(
σ
(
x
w
1
)
,
σ
(
x
w
2
)
,
.
.
.
,
σ
(
x
w
m
)
)
output_1=\left(\sigma(xw_1), \sigma(xw_2), ..., \sigma(xw_m)\right)
output1=(σ(xw1),σ(xw2),...,σ(xwm))
3. 第二层隐藏层
对于第二层隐藏层,以第一层隐藏层输出 o u t p u t 1 output_1 output1为输入,我们假设输出同样是 m m m维向量,权重矩阵为 N m × m = ( n 1 , n 2 , . . . , n m ) N_{m\times m}=(n_1, n_2, ..., n_m) Nm×m=(n1,n2,...,nm)
其中,
n
i
n_i
ni为
m
m
m维列向量。这样,第二层隐藏层的输出为
m
m
m为向量
o
u
t
p
u
t
2
=
(
σ
(
o
u
t
p
u
t
1
⋅
n
1
)
,
σ
(
o
u
t
p
u
t
1
⋅
n
2
)
,
.
.
.
,
σ
(
o
u
t
p
u
t
1
⋅
n
m
)
)
output_2=\left(\sigma(output_1\cdot n_1), \sigma(output_1\cdot n_2), ..., \sigma(output_1\cdot n_m)\right)
output2=(σ(output1⋅n1),σ(output1⋅n2),...,σ(output1⋅nm))
4. 输出层
输出层以第二层隐藏层的输出 o u t p u t 2 output_2 output2为输入,输出的是一个数,我们假设权重矩阵为 P m × 1 = ( p 1 , p 2 , . . . , p m ) P_{m\times 1}=(p_1, p_2, ..., p_m) Pm×1=(p1,p2,...,pm)
其中,
p
i
p_i
pi为数字。这样,输出层的输出为数字
O
u
t
p
u
t
=
o
u
t
p
u
t
2
⋅
P
=
σ
(
o
u
t
p
u
t
1
⋅
n
1
)
⋅
p
1
+
σ
(
o
u
t
p
u
t
1
⋅
n
2
)
⋅
p
2
+
.
.
.
+
σ
(
o
u
t
p
u
t
1
⋅
n
m
)
⋅
p
m
\begin{array}{lll} Output&=&output_2\cdot P\\ &=&\sigma(output_1\cdot n_1)\cdot p_1 + \sigma(output_1\cdot n_2)\cdot p_2+\\ && ... + \sigma(output_1\cdot n_m)\cdot p_m \end{array}
Output==output2⋅Pσ(output1⋅n1)⋅p1+σ(output1⋅n2)⋅p2+...+σ(output1⋅nm)⋅pm
BP算法
BP算法是将误差从后向前传播,最后确定权重矩阵的更新策略。
1. 误差
给定一个数据
(
x
,
y
)
(x, y)
(x,y),我们有误差
L
o
s
s
=
1
2
(
y
−
O
u
t
p
u
t
)
2
Loss=\frac{1}{2}\left(y-Output\right)^2
Loss=21(y−Output)2
2. 链式法则
假设 F ( x ) = f ( g ( x ) ) F(x)=f(g(x)) F(x)=f(g(x)),则有链式法则 ∂ F ( x ) ∂ x = ∂ F ∂ g ⋅ ∂ g ∂ x \frac{\partial F(x)}{\partial x}=\frac{\partial F}{\partial g}\cdot\frac{\partial g}{\partial x} ∂x∂F(x)=∂g∂F⋅∂x∂g
3. 反向传播
我们将依次从后往前确定权重矩阵的更新策略,也就是
- 先确定权重矩阵 P P P的更新策略
- 再确定权重矩阵 N N N的更新策略
- 最后确定权重矩阵 W W W的更新策略
3.1 P P P的更新
对
L
o
s
s
Loss
Loss关于
p
i
p_i
pi求导,我们有
∂
L
o
s
s
∂
p
i
=
(
O
u
t
p
u
t
−
y
)
⋅
∂
O
u
t
p
u
t
∂
p
i
=
(
O
u
t
p
u
t
−
y
)
⋅
σ
(
o
u
t
p
u
t
1
⋅
n
i
)
\begin{array}{lll} \frac{\partial Loss}{\partial p_i}&=&(Output-y)\cdot \frac{\partial Output}{\partial p_i}\\ &=&(Output-y)\cdot \sigma(output_1\cdot n_i) \end{array}
∂pi∂Loss==(Output−y)⋅∂pi∂Output(Output−y)⋅σ(output1⋅ni)
这样,更新策略为
p
i
←
p
i
−
α
∂
L
o
s
s
∂
p
i
p_i\leftarrow p_i-\alpha \frac{\partial Loss}{\partial p_i}
pi←pi−α∂pi∂Loss
3.2 N N N的更新
对
L
o
s
s
Loss
Loss关于
n
i
,
j
n_{i, j}
ni,j求导,我们有
∂
L
o
s
s
∂
n
i
,
j
=
(
O
u
t
p
u
t
−
y
)
⋅
∂
O
u
t
p
u
t
∂
n
i
,
j
=
(
O
u
t
p
u
t
−
y
)
⋅
p
i
∂
σ
(
o
u
t
p
u
t
1
⋅
n
i
)
∂
n
i
,
j
=
(
O
u
t
p
u
t
−
y
)
⋅
σ
˙
(
o
u
t
p
u
t
1
⋅
n
i
)
p
i
σ
(
x
w
j
)
\begin{array}{lll} \frac{\partial Loss}{\partial n_{i, j}}&=&(Output-y)\cdot \frac{\partial Output}{\partial n_{i, j}}\\ &=&(Output-y)\cdot p_i \frac{\partial \sigma(output_1\cdot n_i) }{\partial n_{i,j}}\\ &=&(Output-y)\cdot \dot \sigma(output_1\cdot n_i)p_i\sigma(xw_j) \end{array}
∂ni,j∂Loss===(Output−y)⋅∂ni,j∂Output(Output−y)⋅pi∂ni,j∂σ(output1⋅ni)(Output−y)⋅σ˙(output1⋅ni)piσ(xwj)
其中, σ ˙ ( x ) = ∂ σ ( x ) ∂ x \dot \sigma(x)=\frac{\partial \sigma(x)}{\partial x} σ˙(x)=∂x∂σ(x)。
这样,更新策略为
n
i
,
j
←
n
i
,
j
−
α
∂
L
o
s
s
∂
n
i
,
j
n_{i,j}\leftarrow n_{i,j}-\alpha \frac{\partial Loss}{\partial n_{i,j}}
ni,j←ni,j−α∂ni,j∂Loss
3.3 W W W的更新
对
L
o
s
s
Loss
Loss关于
n
i
,
j
n_{i, j}
ni,j求导,我们有
∂
L
o
s
s
∂
w
i
,
j
=
(
O
u
t
p
u
t
−
y
)
⋅
∂
O
u
t
p
u
t
∂
w
i
,
j
=
(
O
u
t
p
u
t
−
y
)
⋅
p
i
∂
σ
(
o
u
t
p
u
t
1
⋅
n
i
)
∂
w
i
,
j
=
(
O
u
t
p
u
t
−
y
)
⋅
σ
˙
(
o
u
t
p
u
t
1
⋅
n
i
)
p
i
∂
σ
(
x
w
j
)
∂
w
i
,
j
=
(
O
u
t
p
u
t
−
y
)
⋅
σ
˙
(
o
u
t
p
u
t
1
⋅
n
i
)
p
i
σ
˙
(
x
w
j
)
x
j
\begin{array}{lll} \frac{\partial Loss}{\partial w_{i, j}}&=&(Output-y)\cdot \frac{\partial Output}{\partial w_{i, j}}\\ &=&(Output-y)\cdot p_i \frac{\partial \sigma(output_1\cdot n_i) }{\partial w_{i,j}}\\ &=&(Output-y)\cdot \dot \sigma(output_1\cdot n_i)p_i\frac{\partial \sigma(xw_j)}{\partial w_{i,j}}\\ &=&(Output-y)\cdot \dot \sigma(output_1\cdot n_i)p_i\dot\sigma(xw_j)x_j \end{array}
∂wi,j∂Loss====(Output−y)⋅∂wi,j∂Output(Output−y)⋅pi∂wi,j∂σ(output1⋅ni)(Output−y)⋅σ˙(output1⋅ni)pi∂wi,j∂σ(xwj)(Output−y)⋅σ˙(output1⋅ni)piσ˙(xwj)xj
这样,更新策略为
w
i
,
j
←
w
i
,
j
−
α
∂
L
o
s
s
∂
w
i
,
j
w_{i,j}\leftarrow w_{i,j}-\alpha \frac{\partial Loss}{\partial w_{i,j}}
wi,j←wi,j−α∂wi,j∂Loss
其实,上面就是不断用链式法则计算导数的过程。