为什么我的对数损失(或交叉熵)实现结果不一致?

我正在研究对数损失和交叉熵,发现计算它们似乎有两种方法,基于以下方程。

enter image description here

第一种方法是如下所示。

import numpy as npfrom sklearn.metrics import log_lossdef cross_entropy(predictions, targets):    N = predictions.shape[0]    ce = -np.sum(targets * np.log(predictions)) / N    return cepredictions = np.array([[0.25,0.25,0.25,0.25],                        [0.01,0.01,0.01,0.97]])targets = np.array([[1,0,0,0],                   [0,0,0,1]])x = cross_entropy(predictions, targets)print(log_loss(targets, predictions), 'our_answer:', ans)

前述程序的输出是 0.7083767843022996 our_answer: 0.71355817782,几乎相同。所以这不是问题所在。

上述实现是上述方程的中间部分。

第二种方法是基于上述方程的右侧部分。

res = 0for act_row, pred_row in zip(targets, np.array(predictions)):    for class_act, class_pred in zip(act_row, pred_row):        res += - class_act * np.log(class_pred) - (1-class_act) * np.log(1-class_pred)print(res/len(targets))

输出是 1.1549753967602232,与之前的并不完全相同。

我还尝试了使用NumPy的相同实现,但也未能成功。我做错了什么?

附注:我还很好奇,-y log (y_hat) 看起来与 - sigma(p_i * log( q_i)) 相同,那么为什么会有 -(1-y) log(1-y_hat) 部分。显然我误解了如何计算 -y log (y_hat)


回答:

我无法重现您在第一部分报告的结果差异(您还提到了一个ans变量,看起来您没有定义它,我猜它应该是x):

import numpy as npfrom sklearn.metrics import log_lossdef cross_entropy(predictions, targets):    N = predictions.shape[0]    ce = -np.sum(targets * np.log(predictions)) / N    return cepredictions = np.array([[0.25,0.25,0.25,0.25],                        [0.01,0.01,0.01,0.97]])targets = np.array([[1,0,0,0],                   [0,0,0,1]])

结果如下:

cross_entropy(predictions, targets)# 0.7083767843022996log_loss(targets, predictions)# 0.7083767843022996log_loss(targets, predictions) == cross_entropy(predictions, targets)# True

您的cross_entropy函数看起来运行正常。

关于第二部分:

显然我误解了如何计算-y log (y_hat)

确实,仔细阅读您链接的fast.ai wiki后,您会发现方程的右侧部分仅适用于二元分类(其中y1-y中总有一个为零),而这里的情况不是这样——您有一个4类多项分类。因此,正确的表述是

res = 0for act_row, pred_row in zip(targets, np.array(predictions)):    for class_act, class_pred in zip(act_row, pred_row):        res += - class_act * np.log(class_pred)

即丢弃(1-class_act) * np.log(1-class_pred)的减法部分。

结果如下:

res/len(targets)# 0.7083767843022996res/len(targets) == log_loss(targets, predictions)# True

在更一般的层面上(对数损失和二元分类的准确性机制),您可能会发现这个回答有用。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注