实施二元交叉熵损失给出了与 Tensorflow 不同的答案

9 python keras tensorflow loss-function

我正在使用Raw python实现二进制交叉熵损失函数,但它给了我一个与 Tensorflow 非常不同的答案。这是我从 Tensorflow 得到的答案:-

import numpy as np
from tensorflow.keras.losses import BinaryCrossentropy

y_true = np.array([1., 1., 1.])
y_pred = np.array([1., 1., 0.])
bce = BinaryCrossentropy()
loss = bce(y_true, y_pred)
print(loss.numpy())
Run Code Online (Sandbox Code Playgroud)

输出:

>>> 5.1416497230529785
Run Code Online (Sandbox Code Playgroud)

据我所知,二元交叉熵的公式是这样的:

在此输入图像描述

我用原始 python 实现了相同的功能,如下所示:

def BinaryCrossEntropy(y_true, y_pred):
    m = y_true.shape[1]
    y_pred = np.clip(y_pred, 1e-7, 1 - 1e-7)
    # Calculating loss
    loss = -1/m * (np.dot(y_true.T, np.log(y_pred)) + np.dot((1 - y_true).T, np.log(1 - y_pred)))

    return loss

print(BinaryCrossEntropy(np.array([1, 1, 1]).reshape(-1, 1), np.array([1, 1, 0]).reshape(-1, 1)))
Run Code Online (Sandbox Code Playgroud)

但从这个函数我得到的损失值为:

>>> [[16.11809585]]
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到正确的答案?

M.I*_*nat 9

您的实施存在一些问题。这是正确的一个numpy

def BinaryCrossEntropy(y_true, y_pred):
    y_pred = np.clip(y_pred, 1e-7, 1 - 1e-7)
    term_0 = (1-y_true) * np.log(1-y_pred + 1e-7)
    term_1 = y_true * np.log(y_pred + 1e-7)
    return -np.mean(term_0+term_1, axis=0)

print(BinaryCrossEntropy(np.array([1, 1, 1]).reshape(-1, 1), 
                         np.array([1, 1, 0]).reshape(-1, 1)))
[5.14164949]
Run Code Online (Sandbox Code Playgroud)

请注意,在tf. keras模型训练期间,最好使用keras后端功能。您可以使用后端实用程序以相同的方式实现它keras

def BinaryCrossEntropy(y_true, y_pred): 
    y_pred = K.clip(y_pred, K.epsilon(), 1 - K.epsilon())
    term_0 = (1 - y_true) * K.log(1 - y_pred + K.epsilon())  
    term_1 = y_true * K.log(y_pred + K.epsilon())
    return -K.mean(term_0 + term_1, axis=0)

print(BinaryCrossEntropy(
    np.array([1., 1., 1.]).reshape(-1, 1), 
    np.array([1., 1., 0.]).reshape(-1, 1)
    ).numpy())
[5.14164949]
Run Code Online (Sandbox Code Playgroud)