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

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

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

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

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