Действительно, отрицательное логарифмическое правдоподобие - это потеря логарифмов или (двоичная) кросс-энтропия для (двоичных) задач классификации, но, поскольку MNIST является многоклассовой проблемой, здесь мы говорим о категориальном кросс-энтропия.Обычно это предпочтительнее, поскольку, поскольку логарифмическое правдоподобие само по себе отрицательно, его отрицательным будет положительное число;из документов scikit-learn log_loss
(выделение добавлено):
Потеря логарифмов, или потеря логистики или потеря перекрестной энтропии.
Этофункция потерь, используемая в (полиномиальной) логистической регрессии и ее расширениях, таких как нейронные сети, определяется как отрицательное логарифмическое правдоподобие истинных меток с учетом вероятностных предсказаний классификатора.Потеря журнала определяется только для двух или более меток.Для отдельной выборки с истинной меткой yt в {0,1} и оценочной вероятностью yp, что yt = 1, потери в журнале составляют
-log P(yt|yp) = -(yt log(yp) + (1 - yt) log(1 - yp))
Не совсем уверен, как вы можете сделать это с Tensorflow;Вот способ сделать это с помощью Keras (для краткости и краткости кода, я опираюсь на пример Keras MNIST CNN , работающий только для 2 эпох здесь, так как мы заинтересованы только в получении нашего y_pred
и демонстрация процедуры):
Прежде всего, вот категорический результат кросс-энтропийной потери, о котором сообщает Keras для набора :
y_pred = model.predict(x_test)
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
# Test loss: 0.05165324027412571
# Test accuracy: 0.9834
Давайте теперь посмотрим, как мы можем получить этот результат потери «вручную», если у нас есть наши прогнозы 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
Как вы можете проверить визуальнодля всех практических целей это равно потерям, о которых сообщал сам Керас выше (score[0]
);действительно:
np.isclose(log_loss, score[0])
# True
хотя и не точно равно, вероятно, из-за различий в точности чисел в двух методах:
log_loss == score[0]
# False
Надеюсь, теперь вы сможете использоватьописанная выше процедура, чтобы получить потерю журнала между любыми двумя наборами y_true
и y_pred
, которые закодированы в горячем виде (например, MNIST, то есть) ...