7
$\begingroup$

Binary cross entropy for multi-label classification can be defined by the following loss function:

$$-\frac{1}{N}\sum_{i=1}^N [y_i \log(\hat{y}_i)+(1-y_i) \log(1-\hat{y}_i)]$$

Why does keras binary_crossentropy loss function return different values? What is formula bellow them? I tried to read source code but it's not easy to understand.

Updated

The code that gives approximately the same result like Keras:

import keras.backend as K
def binary_crossentropy(y_true, y_pred):
    result = []
    for i in range(len(y_pred)):
        y_pred[i] = [max(min(x, 1 - K.epsilon()), K.epsilon()) for x in y_pred[i]]
        result.append(-np.mean([y_true[i][j] * math.log(y_pred[i][j]) + (1 - y_true[i][j]) * math.log(1 - y_pred[i][j]) for j in range(len(y_pred[i]))]))
    return np.mean(result)
$\endgroup$
1
  • $\begingroup$ Would you be able to provide us some example code, and the value you expected to see? $\endgroup$
    – datddd
    Commented Sep 14, 2017 at 22:22

1 Answer 1

10
$\begingroup$

A mistake in your code:

$$-\frac{1}{N}\sum_{i=1}^N [\color{red}{\hat{y}_i} \log(\hat{y}_i)+(1-y_i) \log(1-\hat{y}_i)]$$

It should be

$$-\frac{1}{N}\sum_{i=1}^N [\color{blue}{y_i} \log(\hat{y}_i)+(1-y_i) \log(1-\hat{y}_i)]$$

Your code:

result.append([y_pred[i][j] * math.log(y_pred[i][j]) + (1 - y_true[i][j]) * math.log(1 - y_pred[i][j]) for j in range(len(y_pred[i]))])

should be changed to

result.append([y_true[i][j] * math.log(y_pred[i][j]) + (1 - y_true[i][j]) * math.log(1 - y_pred[i][j]) for j in range(len(y_pred[i]))])

where I have change your first y_pred to y_true.

Edit: Also from keras documentation, we have

binary_crossentropy(y_true, y_pred)

rather than

binary_crossentropy(y_pred, y_true)
$\endgroup$
6
  • $\begingroup$ Thanks, I fixed the error, but values are still different! The question remains. $\endgroup$
    – Dmitry
    Commented Sep 15, 2017 at 4:48
  • 1
    $\begingroup$ Have you tried different base? base $e$, base $2$, base $10$? $\endgroup$ Commented Sep 15, 2017 at 4:50
  • 1
    $\begingroup$ Can you try switching the order of y_true and y_pred in binary_crossentropy and see if it works? $\endgroup$ Commented Sep 15, 2017 at 5:17
  • $\begingroup$ another potential bug, in your own code, we average over the whole array, in your earlier code, an axis is specified. $\endgroup$ Commented Sep 15, 2017 at 6:08
  • 1
    $\begingroup$ I've found the correct code. Thanks a lot for your help! I am ashamed of the large number of errors in my code. $\endgroup$
    – Dmitry
    Commented Sep 15, 2017 at 6:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.