在我的追求中理解' binary_crossentropy'在Keras的损失函数(因此编写自定义损失函数),我遇到了一个问题。
我制作了2 tf形状(1,1000): labels (y_true)
和logits (y_pred=sigmoid(logits))
的张量
然后我通过TensorFlow,Keras后端和numpy计算了损失函数。在计算时,我试图尽可能地复制Keras损失计算(即我使用K.epsilon()
剪切了值)。 最终的损失值相互偏离。
示例:
对于d=0.05
(只是不同的logit值):
(arr_npbin, arr_kbin, arr_tfbin)=(2.425,2.545,2.688)
对于d=0.12
(只是不同的logit值):
(arr_npbin, arr_kbin, arr_tfbin)=(2.454,2.575,2.720)
等等...
有人可以解释一下我做错了什么吗?上面重现的代码如下:
Python(3.6)代码:
import numpy as np
import tensorflow as tf
import keras.backend as K
d=0.12
# ten0/arr0: Randomly generated labels in {0,1}
ten0=tf.cast(tf.random_uniform(shape=(1,1000),seed=0)>0.5,dtype=tf.float32) #labels
# ten1/arr1: raw logit values
ten1=tf.reshape(tf.range(d,d+10,delta=0.01,dtype=tf.float32),shape=(1,1000))
# ten2/arr2: clipped and activated(sigmoid) values
ten2=tf.clip_by_value(tf.sigmoid(ten1), K.epsilon(), 1 - K.epsilon())
# ten_logit: reverting back to logits after clipping as in keras
ten_logit=tf.log(ten2 / (1 - ten2))
# ten_tfbin/arr_tfbin: binary_crossentropy from tf
ten_tfbin=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits\
(labels=ten0,logits=ten_logit),axis=-1)
sess=tf.Session()
K.set_session(sess)
arr0=ten0.eval(session=sess)
arr1=ten1.eval(session=sess)
arr2=ten2.eval(session=sess)
arr_logit=ten_logit.eval(session=sess)
arr_tfbin=ten_tfbin.eval(session=sess)
# ten_kbin/arr_kbin: binary_crossentropy from Keras
y_true=ten0;y_pred=ten2
ten_kbin=K.mean(K.binary_crossentropy(y_true, y_pred), axis=-1)
arr_kbin=ten_kbin.eval(session=sess)
sess.close()
# arr_npbin: binary_crossentropy from numpy
bin_cross=-(arr0*np.log(arr2)+(1-arr0)*(np.log(1-arr2)))
arr_npbin=np.mean(bin_cross,axis=-1)