深度学习笔记损失函数反向传播公式过程理解记录
深度学习的第三周课程损失函数的反向传播卡了一点时间,发现卡顿的根本原因是对前边的一些细节符号没有准确记忆,同时过程中一些同一含义的符号发生变化。联系上前文一条一条过终于顺利理解,留些记录免得遗忘。
1.逻辑回归
逻辑回归的公式都比较好理解,深度学习和机器学习笔记都反复提及:
2.神经网络中的损失函数计算
以双层神经网络为例,有一个输入层,一个隐藏层和一个输出层。
反向传播就是将偏导一层一层写出来,
d
z
[
2
]
=
d
L
d
a
2
⋅
d
a
2
d
z
2
dz^{[2]}=\frac{dL}{da^{2}}\cdot \frac{da^{2}}{dz^{2}}
dz[2]=da2dL⋅dz2da2
其中:
L
为
损
失
函
数
定
义
:
L
=
L
(
y
∧
(
i
)
,
y
(
i
)
)
=
−
y
(
i
)
log
y
∧
(
i
)
−
(
1
−
y
(
i
)
)
log
(
1
−
y
∧
(
i
)
)
,
此
处
y
∧
(
i
)
为
a
[
2
]
a
[
2
]
=
σ
(
z
[
2
]
)
=
1
1
+
e
−
z
[
2
]
;
其
中
σ
(
)
为
激
活
函
数
,
教
材
用
的
依
然
是
s
i
g
m
o
d
函
数
L\mathrm{为损失函数定义}:\;L=L(\overset\wedge y^{(i)},y^{(i)})=-y^{(i)}\log\;\overset\wedge y^{(i)}-(1-y^{(i)})\log(1-\;\overset\wedge y^{(i)})\;,\mathrm{此处}\overset\wedge y^{(i)}为a^{\lbrack2\rbrack}\\a^{\lbrack2\rbrack}=\sigma(z^{\lbrack2\rbrack})=\frac1{1+e^{-z^{\lbrack2\rbrack}}}\;;\;\mathrm{其中}\sigma()\mathrm{为激活函数},\mathrm{教材用的依然是}sigmod\mathrm{函数}
L为损失函数定义:L=L(y∧(i),y(i))=−y(i)logy∧(i)−(1−y(i))log(1−y∧(i)),此处y∧(i)为a[2]a[2]=σ(z[2])=1+e−z[2]1;其中σ()为激活函数,教材用的依然是sigmod函数
所以可以得到:
d
a
[
2
]
d
z
[
2
]
=
a
[
2
]
(
1
−
a
[
2
]
)
;
d
a
[
2
]
=
d
L
d
a
[
2
]
=
−
y
/
a
[
2
]
+
(
1
−
y
)
/
(
1
−
a
[
2
]
)
\frac{da^{\lbrack2\rbrack}}{dz^{\lbrack2\rbrack}}=a^{\lbrack2\rbrack}(1-a^{\lbrack2\rbrack})\;;\;da^{\lbrack2\rbrack}=\frac{dL}{da^{\lbrack2\rbrack}}=-y/a^{\lbrack2\rbrack}+(1-y)/(1-a^{\lbrack2\rbrack})\;\;
dz[2]da[2]=a[2](1−a[2]);da[2]=da[2]dL=−y/a[2]+(1−y)/(1−a[2])
所以:
d
z
[
2
]
=
d
L
d
a
2
⋅
d
a
2
d
z
2
=
a
[
2
]
−
y
dz^{[2]}=\frac{dL}{da^{2}}\cdot \frac{da^{2}}{dz^{2}}=a^{[2]}-y
dz[2]=da2dL⋅dz2da2=a[2]−y
按两层写一下逻辑回归方程:
第
一
层
:
z
[
1
]
=
w
[
1
]
a
[
0
]
+
b
[
1
]
;
\mathrm{第一层}:z^{\lbrack1\rbrack}=w^{\lbrack1\rbrack}a^{\lbrack0\rbrack}+b^{\lbrack1\rbrack}\;;\;
第一层:z[1]=w[1]a[0]+b[1];
其
中
a
[
0
]
=
x
;
\mathrm{其中}\;a^{\lbrack0\rbrack}=x\;;
其中a[0]=x;
第
一
层
激
活
:
a
[
1
]
=
σ
(
z
[
1
]
)
;
\mathrm{第一层激活}:a^{\lbrack1\rbrack}=\sigma(z^{\lbrack1\rbrack})\;;
第一层激活:a[1]=σ(z[1]);
第
二
层
:
z
[
2
]
=
w
[
2
]
a
[
1
]
+
b
[
2
]
;
\mathrm{第二层}:z^{\lbrack2\rbrack}=w^{\lbrack2\rbrack}a^{\lbrack1\rbrack}+b^{\lbrack2\rbrack}\;;
第二层:z[2]=w[2]a[1]+b[2];
第
二
层
激
活
:
a
[
2
]
=
σ
(
z
[
2
]
)
;
\mathrm{第二层激活}:a^{\lbrack2\rbrack}=\sigma(z^{\lbrack2\rbrack})\;;
第二层激活:a[2]=σ(z[2]);
输
出
:
y
^
=
a
[
2
]
;
\mathrm{输出}:\widehat y=a^{\lbrack2\rbrack}\;;
输出:y
=a[2];
w在z表达式中,所以对w的求导需要先解L再解z。
d w = d L d z ⋅ d z d w = d L d z ⋅ x = d z ⋅ x ; dw=\frac{dL}{dz}\cdot\frac{dz}{dw}=\frac{dL}{dz}\cdot x=dz\cdot x; dw=dzdL⋅dwdz=dzdL⋅x=dz⋅x;
所以由两层逻辑回归方程可以得到:
d w [ 2 ] = d z [ 2 ] ⋅ a [ 1 ] ; d w [ 1 ] = d z [ 1 ] ⋅ a [ 0 ] , 其 中 a [ 0 ] = x ; dw^{\lbrack2\rbrack}=dz^{\lbrack2\rbrack}\cdot a^{\lbrack1\rbrack}\;;\;dw^{\lbrack1\rbrack}=dz^{\lbrack1\rbrack}\cdot a^{\lbrack0\rbrack}\;,\;\mathrm{其中}a^{\lbrack0\rbrack}=x; dw[2]=dz[2]⋅a[1];dw[1]=dz[1]⋅a[0],其中a[0]=x;
综上所述,过程1,解第二层需要从输出层往前挨个求偏导。过程2.求第一层也是从输出层挨个往前求偏导,无非就是挨个往前的中间变量可以用过程1的结果做替换,也就是这里面容易跟不上了,一层一层写出来看一遍就会了。
d z [ 1 ] = ( d L d a [ 2 ] ⋅ d a [ 2 ] d z [ 2 ] ) ⋅ d z [ 2 ] d a [ 1 ] ⋅ d a [ 1 ] d z [ 1 ] ; dz^{\lbrack1\rbrack}=(\frac{dL}{da^{\lbrack2\rbrack}}\cdot\frac{da^{\lbrack2\rbrack}}{dz^{\lbrack2\rbrack}})\cdot\frac{dz^{\lbrack2\rbrack}}{da^{\lbrack1\rbrack}}\cdot\frac{da^{\lbrack1\rbrack}}{dz^{\lbrack1\rbrack}}\;; dz[1]=(da[2]dL⋅dz[2]da[2])⋅da[1]dz[2]⋅dz[1]da[1];
对应的是深度学习笔记中的公式3.4.2:
d
z
[
1
]
=
d
z
[
2
]
⋅
w
[
2
]
T
⋅
σ
[
1
]
′
(
z
[
1
]
)
;
dz^{\lbrack1\rbrack}=dz^{\lbrack2\rbrack}\cdot w^{\lbrack2\rbrack T}\cdot\sigma^{\lbrack1\rbrack'}(z^{\lbrack1\rbrack})\;;
dz[1]=dz[2]⋅w[2]T⋅σ[1]′(z[1]);
此处在课程笔记中将激活函数用了g()代替了前面部分的函数,含义及表达式一样,或许是为了打字方便,本文中延续机器学习笔记从始至终都用一种符号sigma,便于快速阅读公式。
笔记中公式3.4.1同样的方式展开:
d b [ 2 ] = d L d z [ 2 ] ⋅ d z [ 2 ] d b [ 2 ] = d z [ 2 ] ⋅ 1 ; db^{\lbrack2\rbrack}=\frac{dL}{dz^{\lbrack2\rbrack}}\cdot\frac{dz^{\lbrack2\rbrack}}{db^{\lbrack2\rbrack}}=dz^{\lbrack2\rbrack}\cdot1\;; db[2]=dz[2]dL⋅db[2]dz[2]=dz[2]⋅1;
笔记中公式3.44及以后的推导无非是吧代价函数换成了损失函数而已,矩阵的角标及其含义发生变化,过程及形式均一样。