import numpy as np
import tensorflow as tf
y_true = np.array([1, 2]) # 整数分类
y_pred = np.array([[0.05, 0.95, 0], [0.1, 0.8, 0.1]]) # 预测概率
delta = 1e-7
y_true_one_hot = tf.keras.utils.to_categorical( # 独热编码
y_true, # 类数组,类值要转换为矩阵(从 0 到 分类数-1 的整数)
num_classes=3, # 分类数
dtype="float32" # 输出数据类型,默认为float32
)
print(y_true_one_hot)
[[0. 1. 0.]
[0. 0. 1.]]
计算公式
l o s s = 1 n ∑ i t r u e i × ( − l o g e p r e d i + l e − 7 ) loss = \frac{1}{n}\sum_{i}^{}true_{i}\times \left ( -log_{e}^{pred_{i}+le^{-7}}\right ) loss=n1∑itruei×(−logepredi+le−7)
n:样本数
true : y_true
pred : y_pred
计算过程
− { [ ( 0 × l o g e 0.5 + l e − 7 ) + ( 1 × l o g e 0.95 + l e − 7 ) + ( 0 × l o g e 0.0 + l e − 7 ) ] + [ ( 0 × l o g e 0.1 + l e − 7 ) + ( 0 × l o g e 0.8 + l e − 7 ) + ( 1 × l o g e 0.1 + l e − 7 ) ] } ÷ 2 = 1.176939193635535 -\left \{[(0 \times log_{e}^{0.5+le^{-7}})+(1 \times log_{e}^{0.95+le^{-7}})+(0 \times log_{e}^{0.0+le^{-7}})]+[(0 \times log_{e}^{0.1+le^{-7}})+(0 \times log_{e}^{0.8+le^{-7}})+(1 \times log_{e}^{0.1+le^{-7}})]\right \}\div 2 = 1.176939193635535 −{[(0×loge0.5+le−7)+(1×loge0.95+le−7)+(0×loge0.0+le−7)]+[(0×loge0.1+le−7)+(0×loge0.8+le−7)+(1×loge0.1+le−7)]}÷2=1.176939193635535
tf.keras.losses.SparseCategoricalCrossentropy 实现
scce = tf.keras.losses.SparseCategoricalCrossentropy()
print(scce(y_true, y_pred).numpy())
1.1769392490386963
numpy 实现
y_pred_delta = y_pred+delta # 添加一个微小值可以防止负无限大(np.log(0))的发生。
print(y_pred_delta)
[[5.0e-02 9.5e-01 1.0e-11]
[1.0e-01 8.0e-01 1.0e-01]]
y_pred_log = np.log(y_pred_delta) # log表示以e为底数的自然对数
print(y_pred_log)
[[ -2.99573227 -0.05129329 -25.32843602]
[ -2.30258509 -0.22314355 -2.30258509]]
print(y_true_one_hot*y_pred_log)
[[-0. -0.05129329 -0. ]
[-0. -0. -2.30258509]]
loss = -np.sum(y_true_one_hot*y_pred_log)/2
print(loss)
1.1769392490386963