定义
交叉熵是信息论中的一个概念,开始是用来估算平均编码长度的。假设给定两个概率分布p和q,通过q来表示p的交叉熵为:
H
(
p
,
q
)
=
−
∑
p
(
x
)
log
q
(
x
)
H(p,q) = -\sum p(x)\operatorname { log }q(x)
H(p,q)=−∑p(x)logq(x)
交叉熵刻画的是两个概率分布之间的距离,或者可以说是使用概率分q去表达概率分布p的困难程度,通常p代表标记值,q表示预测值。交叉熵越小,表示两个概率分布越接近。
而在神经网络中,可以通过softmax回归将前向传播的结果转为概率分布,然后就可以使用交叉熵作为损失函数。
假设softmax层的前一层网络输出结果为
y
1
,
y
2
,
.
.
.
,
y
n
y_1,y_2,...,y_n
y1,y2,...,yn,那么经过softmax回归处理后的输出为:
s
o
f
t
m
a
x
(
y
)
i
=
e
y
i
∑
j
=
i
n
e
y
i
softmax(y)_i = \frac {e^{y_i}}{\sum _{j=i}^{n}e^{y_i}}
softmax(y)i=∑j=ineyieyi
这样就把神经网络的输出也变成了一个概率分布,从而可以使用交叉熵作为损失函数来衡量预测概率分布与真实概率分布之间的距离了。
举个例子,假设一个三分类问题,正确的概率分布为(1,0,0),一个模型输出概率分布为(0.5,0.4,0.1),那么预测值和标记值之间的交叉熵为:
H
(
(
1
,
0
,
0
)
,
(
0.5
,
0.4
,
0.1
)
)
=
−
(
1
∗
log
0.5
+
0
∗
log
0.4
+
0
∗
log
0.1
)
≈
0.3
H((1,0,0),(0.5,0.4,0.1)) = -(1*\operatorname{log}0.5 + 0*\operatorname{log}0.4 + 0*\operatorname{log}0.1) \approx 0.3
H((1,0,0),(0.5,0.4,0.1))=−(1∗log0.5+0∗log0.4+0∗log0.1)≈0.3
另一个模型的预测值为(0.8,0.1,0.1),交叉熵为:
H
(
(
1
,
0
,
0
)
,
(
0.8
,
0.1
,
0.1
)
)
=
−
(
1
∗
log
0.8
+
0
∗
log
0.1
+
0
∗
log
0.1
)
≈
0.1
H((1,0,0),(0.8,0.1,0.1)) = -(1*\operatorname{log}0.8 + 0*\operatorname{log}0.1 + 0*\operatorname{log}0.1) \approx 0.1
H((1,0,0),(0.8,0.1,0.1))=−(1∗log0.8+0∗log0.1+0∗log0.1)≈0.1
由上例可知,显然(0.8,0.1,0.1)更接近原概率分布,对应的交叉熵也更小。
为什么使用交叉熵作为损失函数
至于为什么使用交叉熵作为损失函数而不是用MSE,请参见我的另一篇博客:
https://blog.youkuaiyun.com/zju_huster/article/details/97394646
利用Tensor flow实现交叉熵
cross_entropy = tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y,1e-10,1.0)))
其中,y_表示标记值,y表示预测值。这里的tf.clip_by_value(v,a,b)表示把v限制在a~b的范围内,小于a的让它等于a,大于b的让它等于b。这样做的目的是避免一些错误运算(比如log0是无效的)。这里需要注意的是:代码中的*不是矩阵相乘,而是对应元素相称,矩阵乘法需要使用tf.matmul函数来完成。