神经网络中的交叉熵
[参考《TensorFlow实战Google深度学习框架(第2版)》]
作为分类问题中的损失函数
在神经网络的多分类问题中,常常使用one-hot的方法设置n类输出,比如在手写体识别问题中,如果是数字1,神经网络的输出越接近[0,1,0,0,0,0,0,0,0,0]越好。那么如何衡量神经网络与label的接近程度呢?交叉熵是常用的使用方法。其刻画的是两个概率分布之间的距离 。
交叉熵是信息论中的概念。对于给定的两个概率分布p和q,交叉熵的计算公式是(PyTorch中对数以自然常数e为底):
H(p,q)=-\sum_{i}p_i\,ln\, q_i
在神经网络中常常通过一个Softmax层将原始输出层变成一个概率分布 (神经网络图如下:):
y_{output}=softmax(y)_i=\frac{e^{yi}}{\sum_{j=1}^{n}e^{yj}}

e.g.将神经网络原始输出[1,0,0]转化成概率分布[0.5761, 0.2119, 0.2119],就可以通过使用交叉熵来计算预测的概率分布和真实概率分布间的距离。
通过观察交叉熵的计算公式:H(p,q)=-\sum_{i}p_i\,log\, q_i,可以看出p和q是不对称的,即不可交换。它刻画的是使用概率分布q表示概率分布p的困难程度。在神经网络中,要的是预测结果描述真实label,所以q是预测值,而p是真实值。公式中,真实在前 。交叉熵刻画的是两个概率分布的距离,即交叉熵数值越小,两个概率分布越接近。下面给出两个具体样例直观地说明通过交叉熵可以判断预测答案和真实答案之间的距离。假设有一个三分类问题,某个样例的正确答案是(1,0,0)。某模型进过Softmox回归之后的预测答案是(0.5,0.4,0.1),那么这个预测和正确答案之间的交叉熵为:
H((1,0,0),(0.5,0.4,0.1))=-(1*ln0.5+0*ln0.4+0*ln0.1)\approx0.69
如果另一个模型的预测是(0.8.0.1,0.1),那么这个预测 值和真实值之间的交叉熵是:
H((1,0,0),(0.8,0.1,0.1))=-(1*ln0.8+0*ln0.1+0*ln0.1)\approx0.22
从上面可以看出,后面这个模型的预测要好于第一个模型(后者的交叉熵小于前者),这与直观上的感觉一致。
PyTorch中的交叉熵
PyTorch中的交叉熵torch.nn.CrossEntropy将Softmax回归与交叉熵一起使用,即PyTorch将两个功能进行了封装,并提供torch.nn.CrossEntropy的方法(以下代码使用softmox的输出供间接验证CrossEntropy内包含softmax):
import torch as t
import numpy as np
criterion = t.nn.CrossEntropyLoss()
softmax = t.nn.Softmax()
original_output = t.from_numpy(np.array([[1, 0, 0]])).float()
softmax_output = softmax(original_output) # softmax_output:tensor([[0.5761,0.2119,0.2119]])
output = criterion(t.from_numpy(np.array([[1, 0, 0]], dtype=np.float32)), t.from_numpy(np.array([0], dtype=np.int32)).long()) #output:0.5514
# H([1,0,0], [0.5761,0.2119,0.2119])=-(1*ln0.5761+0*ln0.2119+0*ln0.2119)=0.5514
AI写代码
