0. 前言
经朋友推荐,近日阅读斋藤康毅先生编写的《深度学习入门 · 基于Python的理论与实现》,书本十分通俗易懂,在Chapter 5 —— 反向传播部分,作者以计算图方式给出了Sigmoid函数,全连接层的反向传播过程,但是在给出Softxmax层的反向传播推导过程的时候,将Softmax函数与交叉熵计算函数直接相连,视为同一个层次,并且给出这个层次的反向传播计算图推导,这篇文章主要关注于两点:
- 将Softmax函数单独视为一层,该层的反向传播导数的输出是什么?
- 验证作者在文中所提出的观点 :
对于Sotfmax-with-loss层,当损失函数为交叉熵时,反向传播输出为 : ∂ L ∂ A = Y i − T i \frac {\partial L}{\partial A} = Y_{i} - T_{i} ∂A∂L=Yi−Ti ( 其中 : A为Softmax函数输入 , Y为Softmax函数输出 , T为样本的真实标签 )
PS :
- 本文为本人阅读笔记,可作为对该书的补充理解,具体知识点请参阅书本
- 本文所列出的公式可为代码编写时,softmax函数的反向传播输出提供参考借鉴
1. Softmax层计算图结构
如《深度学习入门 · 基于Python的理论与实现》一书所示,Softmax-with-Loss层计算图和反向传播过程如下图所示 :
此处,我使用相同的样例——假设softmax函数输出为一个1X3的向量,分析softmax函数本身的反向传播过程(层次画的略乱,各位见谅) :
此处,进行参数补全与名词解释 :
- L1, L2, L3 : 上层函数对softmax各维的输出的求导的结果,若使用书中的交叉熵,则 : L i = − t i y i … … ① Li = -{\frac {t_{i}}{y_{i}}} ……① Li=−yiti……①
- 图中没有给出的参数
- L 1 ∗ e a 1 L1 * e^{a1} L1∗ea1
- L 2 ∗ e a 2 L2 * e^{a2} L2∗ea2
- L 3 ∗ e a 3 L3 * e^{a3} L3∗ea3
- − L 1 e a 1 + L 2 e a 2 + L 3 e a 3 ( ∑ e a i ) 2 - \frac{L_{1}e^{a1} + L_{2}e^{a2} + L3e^{a3}}{(\sum e^{ai})^{2}} −(∑eai)2L1ea1+L2ea2+L3ea3
- 根据计算图加法原则,同4
- 同上
- 同上
- ( L 1 − L 2 ) e a 2 + ( L 1 − L 3 ) e a 3 ( ∑ e a i ) 2 ∗ e a 1 \frac{(L_{1}-L_{2})e^{a2}+(L_{1}-L_{3})e^{a3}}{(\sum e^{ai})^{2}} * e^{a1} (∑eai)2(L1−L2)ea2+(L1−L3)ea3∗ea1
- ( L 2 − L 1 ) e a 1 + ( L 2 − L 3 ) e a 3 ( ∑ e a i ) 2 ∗ e a 2 \frac{(L_{2}-L_{1})e^{a1}+(L_{2}-L_{3})e^{a3}}{(\sum e^{ai})^{2}} * e^{a2} (∑eai)2(L2−L1)ea1+(L2−L3)ea3∗ea2
- ( L 3 − L 1 ) e a 1 + ( L 3 − L 2 ) e a 2 ( ∑ e a i ) 2 ∗ e a 3 \frac{(L_{3}-L_{1})e^{a1}+(L_{3}-L_{2})e^{a2}}{(\sum e^{ai})^{2}} * e^{a3} (∑eai)2(L3−L1)ea1+(L3−L2)ea2∗ea3
2. 作者的推导合理性的验证
此处,我们以(8)式为例进行推导——使用交叉熵函数作为损失函数,softmax输入端每个维度的导数是否与作者原文一样,等于yi-ti:
Step 1 . 在(8)式中代入①式,由Softmax的输出,可知 :
y
i
=
e
a
i
∑
e
a
j
y_{i} = \frac {e^{ai}}{\sum{e^{aj}}}
yi=∑eajeai
Step 2 . 所以可得 :
(
L
1
−
L
2
)
∗
e
a
1
∗
e
a
2
=
t
2
∗
S
∗
e
a
1
−
t
1
∗
S
∗
e
a
2
(L_{1} - L_{2}) * e^{a1} * e^{a2} = t_{2} * S * e^{a1} - t_{1} * S * e^{a2}
(L1−L2)∗ea1∗ea2=t2∗S∗ea1−t1∗S∗ea2
(
L
1
−
L
3
)
∗
e
a
1
∗
e
a
3
=
t
3
∗
S
∗
e
a
1
−
t
1
∗
S
∗
e
a
3
(L_{1} - L_{3}) * e^{a1} * e^{a3} = t_{3} * S * e^{a1} - t_{1} * S * e^{a3}
(L1−L3)∗ea1∗ea3=t3∗S∗ea1−t1∗S∗ea3
其中 :
S
=
∑
e
a
j
S = {\sum{e^{aj}}}
S=∑eaj
Step 3 . 原式等价于 :
t
2
e
a
1
+
t
3
e
a
3
−
t
1
e
a
2
−
t
1
e
a
3
∑
e
a
i
\frac{t_{2}e^{a1} +t_{3}e^{a3} - t_{1}e^{a2} - t_{1}e^{a3}}{\sum e^{ai}}
∑eait2ea1+t3ea3−t1ea2−t1ea3
Step 4 . 等价变换,原式等于 :
(
t
1
e
a
1
+
t
2
e
a
1
+
t
3
e
a
1
)
−
(
t
1
e
a
1
+
t
1
e
a
2
+
t
1
e
a
3
)
∑
e
a
i
\frac{(t_{1}e^{a1}+t_{2}e^{a1}+t_{3}e^{a1}) - (t_{1}e^{a1}+t_{1}e^{a2} + t_{1}e^{a3})}{\sum e^{ai}}
∑eai(t1ea1+t2ea1+t3ea1)−(t1ea1+t1ea2+t1ea3)
等于 :
(
t
1
e
a
1
+
t
2
e
a
1
+
t
3
e
a
1
)
∑
e
a
i
−
t
1
\frac{(t_{1}e^{a1}+t_{2}e^{a1}+t_{3}e^{a1})}{\sum e^{ai}} - t_{1}
∑eai(t1ea1+t2ea1+t3ea1)−t1
Step 5 . 由于t1,t2,t3为样本的真实标签,且采用one-hot形式表示,即t1,t2,t3中只有一个为1,其余为0,所以,原式等于 :
e
a
1
∑
e
a
i
−
t
1
=
y
1
−
t
1
\frac{e^{a1}}{\sum e^{ai}} - t_{1} = y_{1} - t_{1}
∑eaiea1−t1=y1−t1
Step 6. 比较上述结果,发现与作者所求结果一致,所以可知——softmax作为最后一层,且损失函数为交叉熵时,将二者视为同层,该层次反向传播的导数输出为y-t
3. 某些补充
-
Problem : 为何"在正向传播时有分支流出,则反向传播时它们的反向传播值会相加"?
Answer : 在链式求导中,对函数 f(u,y,φ) 求f关于x的偏导数(假设x是u,y,φ中的自变量),则 : ∂ f ∂ x = ∂ f ∂ u ∂ u ∂ x + ∂ f ∂ y ∂ y ∂ x + ∂ f ∂ φ ∂ φ ∂ x \frac{\partial f}{\partial x} = \frac{\partial f}{\partial u} \frac{\partial u}{\partial x} + \frac{\partial f}{\partial y} \frac{\partial y}{\partial x} + \frac{\partial f}{\partial φ} \frac{\partial φ}{\partial x} ∂x∂f=∂u∂f∂x∂u+∂y∂f∂x∂y+∂φ∂f∂x∂φ
以softmax图中(1),(2),(3)合并到(4)为例,(1),(2),(3)其实分别就是f对u,y,φ的偏导数,之所以三者可以合并,是因为 u(x) = φ(x) = y(x) = 1/S 所以三个偏导数值可以相加乘以下一层的偏导 -
Problem : 为什么我把(1,1,1)作为输入,得到的Softmax函数导数值为0
Answer : 这只能说明对(1,1,1)向量,softmax函数无任何误差,达到最低点。但是这在交叉熵中不可能出现,因为 (ti/yi) 只有唯一一个不为0的值
4. Reference
《深度学习入门 · 基于Python的理论与实现》 —— 斋藤康毅