在机器学习中(特别是分类模型),模型训练时,通常都是使用交叉熵(Cross-Entropy)作为损失进行最小化:
C E ( p , q ) = − ∑ i = 1 C p i l o g ( q i ) CE(p,q)=- sum_{i=1}^{C} p_i log(q_i) CE(p,q)=−i=1∑Cpilog(qi)
其中 C C C代表类别数。 p i p_i pi为真实, q i q_i qi为预测。
我们以MNIST多分类为例,通常Label会编码为One-Hot,最后一层输出会使用Softmax函数进行概率化输出,如下表所示:
SampleTruePredicted[0, 1, 0, 0, 0, 0, 0, 0, 0, 0][0.1, 0.6, 0.3, 0, 0, 0, 0, 0, 0, 0][0, 0, 0, 0, 1, 0, 0, 0, 0, 0][0, 0.3, 0.2, 0, 0.5, 0, 0, 0, 0, 0][0, 0, 0, 0, 0, 1, 0, 0, 0, 0][0.6, 0.3, 0, 0, 0, 0.1, 0, 0, 0, 0]对于第一个样本,交叉熵损失为:
− l n ( 0.6 ) ≈ 0.51 -ln(0.6) approx 0.51 −ln(0.6)≈0.51
对于第二个样本,交叉熵损失为:
− l n ( 0.5 ) ≈ 0.69 -ln(0.5) approx 0.69 −ln(0.5)≈0.69
对于第三个样本,交叉熵损失为:
− l n ( 0.1 ) ≈ 2.30 -ln(0.1) approx 2.30 −ln(0.1)≈2.30
平均交叉熵损失为:
− ( l n ( 0.6 ) + l n ( 0.5 ) + l n ( 0.1 ) ) 3 ≈ 1.17 -frac{(ln(0.6)+ln(0.5)+ln(0.1))}{3} approx 1.17 −3(ln(0.6)+ln(0.5)+ln(0.1))≈1.17
从上面的计算可以知道,预测越准,损失越小。
Scikit-learn中提供了交叉熵损失的计算方法:
from sklearn.metrics import log_losstrue = ['1', '4', '5']pred=[[0.1, 0.6, 0.3, 0, 0, 0, 0, 0, 0, 0], [0, 0.3, 0.2, 0, 0.5, 0, 0, 0, 0, 0], [0.6, 0.3, 0, 0, 0, 0.1, 0, 0, 0, 0]]labels=['0','1','2','3','4','5','6','7','8','9']log_loss(true, pred, labels)Out:1.1688526324400008为什么训练时采取交叉熵损失,而不用均方误差(Mean Squared Error, MSE)呢?
Why You Should Use Cross-Entropy Error Instead Of Classification Error Or Mean Squared Error For Neural Network Classifier Training -> 翻译版