这个,在tenorflow 2.0 学习softmax多分类问题时遇到的几个问题,在这里和大家分享,包括损失函数的推导,还有数字编码和独热编码使用 不同 loss function 的区别和联系。
修仙炼丹时遇到的几个问题
一 . 为什么用交叉熵loss function 而不用MSE(包含推导)?
原因之一:
因为我们必须知道,softmax函数在神经网络输出层的最后将所有的结果都变成概率分布的形式,比如我们对一个物品归类,它属于鞋子的概率是30%,属于上衣的概率是50%,而属于裤子的概率是20%(当然所用标签的概率之和肯定为1),我们最后只需返回最大概率的结果对应的标签就完成了归类!
而我们熟知的MSE似乎无法完成这个任务,无法以概率的形式输出结果!
原因之二:
先看看MSE长啥样:
L
(
a
,
y
)
=
1
2
(
a
−
y
)
2
L(a,y) = \frac{1}{2} (a-y)^{2}
L(a,y)=21(a−y)2 ,其中,这个 a 为神经元实际输出的值,y是真实值!激活函数我们用的都是:
s
i
g
m
o
i
d
sigmoid
sigmoid函数,假设有以下反向传播途径:
z
1
=
w
1
x
+
b
1
;
a
1
=
s
i
g
m
o
i
d
(
z
1
)
z
2
=
w
2
a
1
+
b
2
;
a
2
=
s
i
g
m
o
i
d
(
z
2
)
z_{1} = w_{1}x +b_{1} ; \\ a_{1} =sigmoid(z_{1})\\ z_{2} = w_{2}a_{1} +b_{2} ; \\ a_{2} =sigmoid(z_{2})
z1=w1x+b1;a1=sigmoid(z1)z2=w2a1+b2;a2=sigmoid(z2)
我们知道深度学习的训练过程是通过梯度下降法反向传播更新参数值,具体来说,每一次前向传播结束后,通过对损失函数+激活函数反向在每一层对每个w和b参数进行求导,得到,得到
d
L
d
w
\frac{dL}{dw}
dwdL和
d
L
d
b
\frac{dL}{db}
dbdL的值,最后更新w和b,f反复该操作,最终是y与a无线接近!
使用MSE:
L函数求导为:
L
′
(
a
,
y
)
=
a
−
y
L'(a, y) = a - y
L′(a,y)=a−y
sigmoid函数求导为:
a
′
(
z
)
=
a
(
1
−
a
)
a' (z) = a (1 - a)
a′(z)=a(1−a)
我们对
w
2
w_{2}
w2进行求导,由链式法则可知:
d
L
d
w
2
=
d
L
d
a
2
⋅
d
a
2
d
z
2
⋅
d
z
2
d
w
2
\frac{dL}{dw_{2}} = \frac{dL}{da_{2}} \cdot \frac{da_{2}}{dz_{2}}\cdot \frac{dz_{2}}{dw_{2}}
dw2dL=da2dL⋅dz2da2⋅dw2dz2
最后得到:
d
L
d
w
2
=
(
a
2
−
y
)
⋅
a
2
(
1
−
a
2
)
⋅
a
1
\frac{dL}{dw_{2}} = (a_{2}-y) \cdot a_{2}(1-a_{2}) \cdot a_{1}
dw2dL=(a2−y)⋅a2(1−a2)⋅a1
使用sparse_categorical_crossentropy:
首先我们要知道交叉熵的函数是这样的:
L
=
−
∑
i
y
i
ln
a
i
L=-\sum_{i} y_{i} \ln a_{i}
L=−i∑yilnai
这里给出简单的推导(可看可不看,会用就行!):
∂
L
∂
z
i
=
∑
j
(
∂
L
j
∂
a
j
∂
a
j
∂
z
i
)
\frac{\partial L}{\partial z_{i}}=\sum_{j}\left(\frac{\partial L_{j}}{\partial a_{j}} \frac{\partial a_{j}}{\partial z_{i}}\right)
∂zi∂L=j∑(∂aj∂Lj∂zi∂aj)
好,接下来推括号中的第一项:
∂
L
j
∂
a
j
=
∂
(
−
y
j
ln
a
j
)
∂
a
j
=
−
y
j
1
a
j
\frac{\partial L_{j}}{\partial a_{j}}=\frac{\partial\left(-y_{j} \ln a_{j}\right)}{\partial a_{j}}=-y_{j} \frac{1}{a_{j}}
∂aj∂Lj=∂aj∂(−yjlnaj)=−yjaj1
第二项分为
i
=
j
i=j
i=j 与
i
≠
j
i\neq j
i=j:
-
i
=
j
i=j
i=j 时:
∂ a i ∂ z i = ∂ ( e i i ∑ k e i k ) ∂ z i = ∑ k e z k e z i − ( e z i ) 2 ( ∑ k e z k ) 2 = ( e z i ∑ k e z k ) ( 1 − e z i ∑ k e z k ) = a i ( 1 − a i ) \frac{\partial a_{i}}{\partial z_{i}}=\frac{\partial\left(\frac{e^{i_{i}}}{\sum_{k} e^{i k}}\right)}{\partial z_{i}}=\frac{\sum_{k} e^{z_{k}} e^{z_{i}}-\left(e^{z_{i}}\right)^{2}}{\left(\sum_{k} e^{z_{k}}\right)^{2}}=\left(\frac{e^{z_{i}}}{\sum_{k} e^{z_{k}}}\right)\left(1-\frac{e^{z_{i}}}{\sum_{k} e^{z_{k}}}\right)=a_{i}\left(1-a_{i}\right) ∂zi∂ai=∂zi∂(∑keikeii)=(∑kezk)2∑kezkezi−(ezi)2=(∑kezkezi)(1−∑kezkezi)=ai(1−ai) - i ≠ j i\neq j i=j时: ∂ a j ∂ z i = ∂ ( e i j ∑ k e x ) ∂ z i = − e z j ( 1 ∑ k e z k ) 2 e z i = − a i a j \frac{\partial a_{j}}{\partial z_{i}}=\frac{\partial\left(\frac{e^{i j}}{\sum_{k} e^{x}}\right)}{\partial z_{i}}=-e^{z_{j}}\left(\frac{1}{\sum_{k} e^{z_{k}}}\right)^{2} e^{z_{i}}=-a_{i} a_{j} ∂zi∂aj=∂zi∂(∑kexeij)=−ezj(∑kezk1)2ezi=−aiaj
最后得到: ∂ C ∂ z i = ∑ j ( ∂ C j ∂ a j ∂ a j ∂ z i ) = ∑ j = j i ( ∂ C j ∂ a j ∂ a j ∂ z i ) + ∑ i = j ( ∂ C j ∂ a j ∂ a j ∂ z i ) = ∑ j = j i − y j 1 a j ( − a i a j ) + ( − y i 1 a i ) ( a i ( 1 − a i ) ) = ∑ j = j i a i y j + ( − y i ( 1 − a i ) ) = ∑ j = i a i y j + a i y i − y i = a i ∑ j y j − y i \begin{aligned} \frac{\partial C}{\partial z_{i}} &=\sum_{j}\left(\frac{\partial C_{j}}{\partial a_{j}} \frac{\partial a_{j}}{\partial z_{i}}\right)=\sum_{j=j i}\left(\frac{\partial C_{j}}{\partial a_{j}} \frac{\partial a_{j}}{\partial z_{i}}\right)+\sum_{i=j}\left(\frac{\partial C_{j}}{\partial a_{j}} \frac{\partial a_{j}}{\partial z_{i}}\right) \\ &=\sum_{j=j i}-y_{j} \frac{1}{a_{j}}\left(-a_{i} a_{j}\right)+\left(-y_{i} \frac{1}{a_{i}}\right)\left(a_{i}\left(1-a_{i}\right)\right) \\ &=\sum_{j=j i} a_{i} y_{j}+\left(-y_{i}\left(1-a_{i}\right)\right) \\ &=\sum_{j=i} a_{i} y_{j}+a_{i} y_{i}-y_{i} \\ &=a_{i} \sum_{j} y_{j}-y_{i} \end{aligned} ∂zi∂C=j∑(∂aj∂Cj∂zi∂aj)=j=ji∑(∂aj∂Cj∂zi∂aj)+i=j∑(∂aj∂Cj∂zi∂aj)=j=ji∑−yjaj1(−aiaj)+(−yiai1)(ai(1−ai))=j=ji∑aiyj+(−yi(1−ai))=j=i∑aiyj+aiyi−yi=aij∑yj−yi
即: ∂ C ∂ z i = a i − y i \frac{\partial C}{\partial z_{i}}=a_{i}-y_{i} ∂zi∂C=ai−yi
注意,这里的损失函数是多分类的,有人会说交叉熵损失函数是: C = − 1 n ∑ x [ y ln a + ( 1 − y ) ln ( 1 − a ) ] C=-\frac{1}{n} \sum_{x}[y \ln a+(1-y) \ln (1-a)] C=−n1∑x[ylna+(1−y)ln(1−a)] 那是二分类情况下的,本质一样。
此时, 我们可知激活函数 s i g m o i d sigmoid sigmoid的自身斜率在趋近两端时变得很平滑,这也意味着反向求导时迭代值dL/dw会比较小,从而使得训练速度变慢,这即是交叉熵函数优于均方差函数的第二个原因。
二 . categorical_crossentropy和sparse_categorical_crossentropy的区别
在tensorflow.keras 中,如果我们对目标图片进行识别,对其所有对应的标签值采用数字编码就用 s p a r s e c a t e g o r i c a l c r o s s e n t r o p y sparse_categorical_crossentropy sparsecategoricalcrossentropy 的损失函数,比如标签是1,2,3…,1返回鞋子,2返回上衣,3返回裤子,想这种非常单纯的用数字编码,就用这个函数!
如果我们采用独热编码,像鞋子编码为[1,0,0] ,裤子编码为[0,1,0] ,那么上衣就是 [0,0,1]
用二维数组中数字的位置来进行标签化,这个时候,我们采用的损失函数就是
c
a
t
e
g
o
r
i
c
a
l
c
r
o
s
s
e
n
t
r
o
p
y
categorical_crossentropy
categoricalcrossentropy,其实原理基本一样,只是算法在运行的时候对编码预处理了!
这一期博客就到这里,还不是所有的问题,发现行的问题后 本篇博客会添加更新!