Python 如何在MNIST数据集上计算负对数?

Python 如何在MNIST数据集上计算负对数?,python,tensorflow,machine-learning,recurrent-neural-network,mnist,Python,Tensorflow,Machine Learning,Recurrent Neural Network,Mnist,下表 这是报纸上的。但我找不到他们计算NLL的代码。我想问一下,它是否仅仅是二进制交叉熵。我能用张量流函数计算吗 在教授强迫论文中,没有给出教师强迫的评价结果。我训练了一个简单的LSTM,并获得了80.394的NLL。我的最后一个问题是获得~80或~70的可能性有多大 更具体地说,我正在尝试逐像素生成MNIST图像。我的模型对每个像素进行二进制预测,可以取0和1的值。logits和label的维度都是[batch_size,28*28,1],其中28是MNIST图像的高度和宽度。事实上,负对数

下表

这是报纸上的。但我找不到他们计算NLL的代码。我想问一下,它是否仅仅是二进制交叉熵。我能用张量流函数计算吗

在教授强迫论文中,没有给出教师强迫的评价结果。我训练了一个简单的LSTM,并获得了80.394的NLL。我的最后一个问题是获得~80或~70的可能性有多大


更具体地说,我正在尝试逐像素生成MNIST图像。我的模型对每个像素进行二进制预测,可以取0和1的值。logits和label的维度都是
[batch_size,28*28,1]
,其中28是MNIST图像的高度和宽度。

事实上,负对数似然是对数损失,或(二进制)分类问题的(二进制)交叉熵,但由于MNIST是一个多类问题,因此我们在这里讨论分类交叉熵。它通常是首选的,因为对数似然本身是负数,它的负数将是正数;从scikit学习文档(重点添加):

对数损失,又名逻辑损失或交叉熵损失

这是(多项式)逻辑回归中使用的损失函数 以及它的扩展,如神经网络,定义为<强>负 给定概率分类器的真实标签的对数似然性 预言。日志丢失仅为两个或多个标签定义。对于 具有{0,1}中真标签yt的单个样本及其估计概率 yp表示yt=1,则日志损失为

-log P(yt|yp) = -(yt log(yp) + (1 - yt) log(1 - yp))
不太确定如何使用Tensorflow实现这一点;下面是一种使用Keras的方法(为了保持代码简短,我在这里只运行了两个时代,因为我们只对获得我们的
y_pred
&演示过程感兴趣):

首先,以下是Keras报告的测试集分类交叉熵损失结果:

现在,让我们看看如何“手动”获得该损失结果,以防我们的预测
y_pred
和真实标签
y_test
与使用的任何特定模型无关;请注意,当我们的预测和真实标签都是一个热编码时,该程序才适用,即:

y_pred[0]
# array([2.4637930e-07, 1.0927782e-07, 1.0026793e-06, 7.6613435e-07,
#        4.1209915e-09, 1.4566888e-08, 2.3195759e-10, 9.9999702e-01,
#        4.9344425e-08, 8.6051602e-07], dtype=float32)
y_test[0]
# array([0., 0., 0., 0., 0., 0., 0., 1., 0., 0.])
以下是程序:

from keras import backend as K
import numpy as np

y_test = y_test.astype('float32') # necessary here, since y_pred comes in this type - check in your case with y_test.dtype and y_pred.dtype
y_test = K.constant(y_test)
y_pred = K.constant(y_pred)

g = K.categorical_crossentropy(target=y_test, output=y_pred)  # tensor
ce = K.eval(g)  # 'ce' for cross-entropy
ce.shape
# (10000,) # i.e. one loss quantity per sample

# sum up and divide with the no. of samples:
log_loss = np.sum(ce)/ce.shape[0]
log_loss
# 0.05165323486328125
正如您可以直观地验证的那样,就所有实际目的而言,这等于Keras自身报告的上述损失(
score[0]
);事实上:

虽然不完全相等,但可能是由于两种方法的数值精度不同:

log_loss == score[0]
# False

希望您现在能够使用上述过程获得任意两个集之间的日志丢失
y_true
y_pred
,这两个集都是一个热编码集(如MNIST),谢谢您的回答。我更感兴趣的是生成性建模任务,而不是分类。基本上,我正在尝试逐像素生成MNIST图像。我的模型对每个像素进行二进制预测,可以取0和1的值。我认为你的回答对这个案件也是有效的。登录和标签的维度都是[batch_size,28*28,1]。@eaksan可能是,但此信息应该明确包含在您的OP中;我花了相当多的时间来回答这个问题,我真的希望至少会得到相应的赞赏(可以说,我已经回答了你在作品中提出的确切问题)…谢谢你的努力。我认为参考文件足够了,因为我在问如何计算我提供的表格中的数字。
np.isclose(log_loss, score[0])
# True
log_loss == score[0]
# False