为什么我的对数损失(或交叉熵)的实现没有产生相同的结果?
Why is my implementations of the log-loss (or cross-entropy) not producing the same results?
我正在阅读 log-loss 和交叉熵,似乎有 2 种计算方法,基于以下等式。
第一个是。
import numpy as np
from sklearn.metrics import log_loss
def cross_entropy(predictions, targets):
N = predictions.shape[0]
ce = -np.sum(targets * np.log(predictions)) / N
return ce
predictions = 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
,几乎是一样的。所以这不是问题。
上面的实现是上面等式的中间部分。
第二种方法基于上述等式的 RHS 部分。
res = 0
for 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 尝试过相同的实现,但也没有用。我做错了什么?
PS:我也很好奇-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 np
from sklearn.metrics import log_loss
def cross_entropy(predictions, targets):
N = predictions.shape[0]
ce = -np.sum(targets * np.log(predictions)) / N
return ce
predictions = 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.7083767843022996
log_loss(targets, predictions)
# 0.7083767843022996
log_loss(targets, predictions) == cross_entropy(predictions, targets)
# True
您的 cross_entropy
函数似乎工作正常。
关于第二部分:
Clearly I am misunderstanding how -y log (y_hat)
is to be calculated.
确实,更仔细地阅读您链接到的 fast.ai wiki,您会发现等式的 RHS 仅适用于二进制 classification(其中总是 y
和 1-y
将为零),这里不是这种情况 - 你有一个 4-class 多项式 class 化。所以,正确的表述是
res = 0
for 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.7083767843022996
res/len(targets) == log_loss(targets, predictions)
# True
在更一般的层面上(二进制 class化的对数丢失机制和准确性),您可能会发现 很有用。
我正在阅读 log-loss 和交叉熵,似乎有 2 种计算方法,基于以下等式。
第一个是
import numpy as np
from sklearn.metrics import log_loss
def cross_entropy(predictions, targets):
N = predictions.shape[0]
ce = -np.sum(targets * np.log(predictions)) / N
return ce
predictions = 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
,几乎是一样的。所以这不是问题。
上面的实现是上面等式的中间部分。
第二种方法基于上述等式的 RHS 部分。
res = 0
for 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 尝试过相同的实现,但也没有用。我做错了什么?
PS:我也很好奇-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 np
from sklearn.metrics import log_loss
def cross_entropy(predictions, targets):
N = predictions.shape[0]
ce = -np.sum(targets * np.log(predictions)) / N
return ce
predictions = 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.7083767843022996
log_loss(targets, predictions)
# 0.7083767843022996
log_loss(targets, predictions) == cross_entropy(predictions, targets)
# True
您的 cross_entropy
函数似乎工作正常。
关于第二部分:
Clearly I am misunderstanding how
-y log (y_hat)
is to be calculated.
确实,更仔细地阅读您链接到的 fast.ai wiki,您会发现等式的 RHS 仅适用于二进制 classification(其中总是 y
和 1-y
将为零),这里不是这种情况 - 你有一个 4-class 多项式 class 化。所以,正确的表述是
res = 0
for 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.7083767843022996
res/len(targets) == log_loss(targets, predictions)
# True
在更一般的层面上(二进制 class化的对数丢失机制和准确性),您可能会发现