交叉熵的一般形式是:
−
Σ
p
∗
l
o
g
(
q
)
-Σ{p*log(q)}
−Σp∗log(q)
其中p一般指的是真实情况概率(标签),q指的是神经网络计算出的概率(结果)
为了一般化,这里特别规定好:
输
入
的
训
练
样
本
标
签
为
Y
:
[
Y
0
,
Y
1
,
.
.
.
,
Y
n
]
神
经
网
络
计
算
的
结
果
为
A
:
[
A
0
,
A
1
,
.
.
.
,
A
n
]
交
叉
熵
公
式
中
对
数
的
底
数
为
e
,
此
时
l
o
g
是
l
n
输入的训练样本标签为Y:[Y_0,Y_1,...,Y_n]\\ 神经网络计算的结果为A:[A_0,A_1,...,A_n]\\ 交叉熵公式中对数的底数为e,此时log是ln
输入的训练样本标签为Y:[Y0,Y1,...,Yn]神经网络计算的结果为A:[A0,A1,...,An]交叉熵公式中对数的底数为e,此时log是ln
令交叉熵(CrossEntropyLoss)=CELoss,其表达式为:
C
E
L
o
s
s
(
A
,
Y
)
=
−
∑
i
=
0
n
Y
i
∗
l
n
A
i
CELoss(A,Y)=-\sum_{i=0}^{n}{Y_i*lnA_i}
CELoss(A,Y)=−i=0∑nYi∗lnAi
对交叉熵来说,样本标签Y并不是"变量",可以看做常数,而神经网络的结果A才是输入的变量。和之前softmax的函数又不一样了,softmax是输入一个序列输出一个序列,这里是输入两个序列输出一个数字!
(
[
A
0
A
1
A
2
.
.
.
A
n
]
&
[
Y
0
Y
1
Y
2
.
.
.
Y
n
]
)
=
>
C
E
L
o
s
s
(
A
,
Y
)
=
>
[
−
Y
0
∗
l
n
A
0
−
Y
1
∗
l
n
A
1
−
Y
2
∗
l
n
A
2
.
.
.
−
Y
n
∗
l
n
A
n
]
}
∑
=
结
果
(
某
个
确
定
的
数
值
)
\Bigg (\left[ \begin{matrix} A_0\\A_1\\A_2\\.\\.\\.\\A_n \end{matrix} \right]\& \left[ \begin{matrix} Y_0\\Y_1\\Y_2\\.\\.\\.\\Y_n \end{matrix} \right]\Bigg ) =>CELoss(A,Y)=> \left[ \begin{matrix} -Y_0*lnA_0\\-Y_1*lnA_1\\-Y_2*lnA_2\\.\\.\\.\\-Y_n*lnA_n \end{matrix} \right]\Bigg\} \sum=结果(某个确定的数值)
(⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡A0A1A2...An⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤&⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡Y0Y1Y2...Yn⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤)=>CELoss(A,Y)=>⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡−Y0∗lnA0−Y1∗lnA1−Y2∗lnA2...−Yn∗lnAn⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤}∑=结果(某个确定的数值)
所以交叉熵的导数就是对这个"结果"所贡献的每个表达式的导数,如下:
∂
C
E
L
o
s
s
(
A
,
Y
)
∂
A
=
[
∂
L
(
A
0
,
Y
0
)
∂
A
0
∂
L
(
A
1
,
Y
1
)
∂
A
1
∂
L
(
A
2
,
Y
2
)
∂
A
2
.
.
.
∂
L
(
A
n
,
Y
n
)
∂
A
n
]
=
[
−
Y
0
∗
l
n
A
0
−
Y
1
∗
l
n
A
1
−
Y
2
∗
l
n
A
2
.
.
.
−
Y
n
∗
l
n
A
n
]
′
=
[
−
Y
0
A
0
−
Y
1
A
1
−
Y
2
A
2
.
.
.
−
Y
n
A
n
]
}
=
−
Y
i
A
i
∣
i
=
0
n
\frac{∂CELoss(A,Y)}{∂A}= \left[ \begin{matrix} \frac{∂L(A_0,Y_0)}{∂A_0}\\ \frac{∂L(A_1,Y_1)}{∂A_1}\\ \frac{∂L(A_2,Y_2)}{∂A_2}\\.\\.\\.\\ \frac{∂L(A_n,Y_n)}{∂A_n} \end{matrix} \right]= \left[ \begin{matrix} -Y_0*lnA_0\\-Y_1*lnA_1\\-Y_2*lnA_2\\.\\.\\.\\-Y_n*lnA_n \end{matrix} \right]'= \left[ \begin{matrix} -\frac{Y_0}{A_0}\\-\frac{Y_1}{A_1}\\-\frac{Y_2}{A_2}\\.\\.\\.\\-\frac{Y_n}{A_n} \end{matrix} \right]\Bigg \}=-\frac{Y_i}{A_i}\Bigg|_{i=0}^{n}
∂A∂CELoss(A,Y)=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡∂A0∂L(A0,Y0)∂A1∂L(A1,Y1)∂A2∂L(A2,Y2)...∂An∂L(An,Yn)⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡−Y0∗lnA0−Y1∗lnA1−Y2∗lnA2...−Yn∗lnAn⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤′=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡−A0Y0−A1Y1−A2Y2...−AnYn⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤}=−AiYi∣∣∣∣∣i=0n
在深度学习中,如果是希望程序基于输入数据,给出一个置信度,比如MNIST的0-9,我希望给出十个概率,这十个概率加起来等于1,其中最大的概率对应的数字自然就是程序识别的结果了。这种情况我们就可以在神经网络最后一层使用softmax作为激活函数输出A,搭配CELoss作为损失函数了。
根据之前的文章,我们可以知道softmax函数及其导数是:
A
(
z
i
)
=
e
z
i
e
z
0
+
e
z
1
+
.
.
.
+
e
z
n
=
e
z
i
∑
j
=
0
n
e
z
j
∂
A
∂
z
i
=
{
A
i
(
1
−
A
i
)
∣
i
=
j
∑
j
=
0
→
n
j
≠
i
−
A
i
A
j
=
A
i
(
1
−
A
i
)
+
∑
j
=
0
→
n
j
≠
i
−
A
i
A
j
A(z_i)=\frac{e^{z_i}}{e^{z_0}+e^{z_1}+...+e^{z_n}} =\frac{e^{z_i}}{\sum_{j=0}^{n}e^{z_j}}\\ \frac{∂A}{∂z_i}=\begin{cases} A_i(1-A_i)\big|_{i=j}\\\\ \sum_{j=0→n}^{j≠i}-A_iA_j \end{cases} =A_i(1-A_i)+\sum_{j=0→n}^{j≠i}-A_iA_j
A(zi)=ez0+ez1+...+eznezi=∑j=0nezjezi∂zi∂A=⎩⎪⎨⎪⎧Ai(1−Ai)∣∣i=j∑j=0→nj=i−AiAj=Ai(1−Ai)+j=0→n∑j=i−AiAj
结合链式法则,有:
∂
C
E
L
o
s
s
∂
z
i
=
∂
C
E
L
o
s
s
∂
A
∗
∂
A
∂
z
i
=
∂
C
E
L
o
s
s
∂
A
i
∗
∂
A
i
∂
z
i
+
∂
C
E
L
o
s
s
∂
∑
A
j
∗
∂
∑
A
j
∂
z
i
=
[
−
Y
i
A
i
∗
A
i
(
1
−
A
i
)
]
∣
i
=
j
+
[
−
Y
i
A
i
∗
∑
j
=
0
→
n
j
≠
i
−
A
i
A
j
]
∣
i
≠
j
=
Y
i
∗
(
A
i
−
1
)
+
∑
j
=
0
→
n
j
≠
i
Y
i
A
j
=
Y
i
A
i
+
∑
j
=
0
→
n
j
≠
i
Y
i
A
j
−
Y
i
\frac{∂CELoss}{∂z_i}=\frac{∂CELoss}{∂A}*\frac{∂A}{∂z_i}= \frac{∂CELoss}{∂A_i}*\frac{∂A_i}{∂z_i} +\frac{∂CELoss}{∂\sum A_j}*\frac{∂\sum A_j}{∂z_i}\\ =[-\frac{Y_i}{A_i}*A_i(1-A_i)]\bigg|_{i=j} +[-\frac{Y_i}{A_i}*\sum_{j=0→n}^{j≠i}-A_iA_j]\bigg|_{i≠j}\\ =Y_i*(A_i-1)+\sum_{j=0→n}^{j≠i}Y_iA_j\\ =Y_iA_i+\sum_{j=0→n}^{j≠i}Y_iA_j-Y_i
∂zi∂CELoss=∂A∂CELoss∗∂zi∂A=∂Ai∂CELoss∗∂zi∂Ai+∂∑Aj∂CELoss∗∂zi∂∑Aj=[−AiYi∗Ai(1−Ai)]∣∣∣∣i=j+[−AiYi∗j=0→n∑j=i−AiAj]∣∣∣∣i=j=Yi∗(Ai−1)+j=0→n∑j=iYiAj=YiAi+j=0→n∑j=iYiAj−Yi
计算当i=j时:
−
Y
i
A
i
∗
A
i
(
1
−
A
i
)
=
−
Y
i
+
A
i
Y
i
(1)
-\frac{Y_i}{A_i}*A_i(1-A_i)=-Y_i+A_iY_i\tag{1}
−AiYi∗Ai(1−Ai)=−Yi+AiYi(1)
当i≠j时:
−
Y
i
A
i
∗
∑
j
=
0
→
n
j
≠
i
−
A
i
A
j
=
∑
j
=
0
→
n
j
≠
i
Y
i
A
i
∗
A
i
A
j
=
∑
j
=
0
→
n
j
≠
i
Y
i
A
j
(2)
-\frac{Y_i}{A_i}*\sum_{j=0→n}^{j≠i}-A_iA_j=\sum_{j=0→n}^{j≠i}\frac{Y_i}{A_i}*A_iA_j =\sum_{j=0→n}^{j≠i}Y_iA_j\tag{2}
−AiYi∗j=0→n∑j=i−AiAj=j=0→n∑j=iAiYi∗AiAj=j=0→n∑j=iYiAj(2)
仔细比较(1)和(2),可以发现(1)的后半段正好就是(2)中缺失的i=j,(1)+(2)的结果如下:
−
Y
i
+
A
i
Y
i
+
∑
j
=
0
→
n
j
≠
i
Y
i
A
j
=
−
Y
i
+
∑
i
=
0
n
Y
i
A
i
由
于
Y
是
样
本
标
签
,
每
一
批
只
有
一
个
是
真
实
值
,
其
值
为
1
,
其
它
都
是
0
。
所
以
特
别
地
:
∑
i
=
0
n
Y
i
A
i
=
Y
0
A
0
+
Y
1
A
1
+
.
.
.
+
Y
i
A
i
+
.
.
.
+
Y
n
A
n
=
0
+
0
+
.
.
.
+
Y
i
A
i
+
.
.
.
+
0
=
A
i
这
样
整
个
导
数
的
结
果
就
全
部
求
出
来
了
:
∂
C
E
L
o
s
s
∂
z
i
=
A
i
−
Y
i
-Y_i+A_iY_i+\sum_{j=0→n}^{j≠i}Y_iA_j=-Y_i+\sum_{i=0}^{n}Y_iA_i\\ 由于Y是样本标签,每一批只有一个是真实值,其值为1,其它都是0。所以特别地:\\ \sum_{i=0}^{n}Y_iA_i=Y_0A_0+Y_1A_1+...+Y_iA_i+...+Y_nA_n=0+0+...+Y_iA_i+...+0=A_i\\ 这样整个导数的结果就全部求出来了:\frac{∂CELoss}{∂z_i}=A_i-Y_i
−Yi+AiYi+j=0→n∑j=iYiAj=−Yi+i=0∑nYiAi由于Y是样本标签,每一批只有一个是真实值,其值为1,其它都是0。所以特别地:i=0∑nYiAi=Y0A0+Y1A1+...+YiAi+...+YnAn=0+0+...+YiAi+...+0=Ai这样整个导数的结果就全部求出来了:∂zi∂CELoss=Ai−Yi
在神经网络中,损失函数和激活函数的选择是很重要的。从上面的结果可以很明显看出softmax和交叉熵的配合是非常好的,它的结果只和A和Y有关,也可以很好地避免梯度弥散,最重要的是其计算只有减法,非常方便和高效,所以一般处理多分类问题都可以使用这两个函数。
此外,二分类问题可以使用交叉熵的特殊情况:二分类交叉熵函数(BCE)和sigmoid函数的配合(它和softmax是一脉相承的),结果是一样的,这里就不细说了。