1 回答
TA贡献1891条经验 获得超3个赞
我认为问题在于您在第一个版本中无意中进行了广播操作,这给您带来了错误的结果。如果您的批次(?, 1)由于tf.squeeze操作而具有 shape ,则会发生这种情况。注意本例中的形状
import tensorflow as tf
# Make random y_true and y_pred with shape (10, 1)
tf.random.set_seed(10)
y_true = tf.dtypes.cast(tf.random.uniform((10, 1), 0, 3, dtype=tf.int32), tf.float32)
y_pred = tf.random.uniform((10, 1), 0, 1, dtype=tf.float32)
# first
y_t = tf.squeeze(y_true)
mask = tf.where(y_t != 2)
y_t = tf.gather_nd(y_t, mask)
tf.print(tf.shape(y_t))
# [7]
y_p = tf.gather_nd(y_pred, mask)
tf.print(tf.shape(y_p))
# [7 1]
loss = tf.keras.losses.binary_crossentropy(y_t, y_p)
first_loss = tf.reduce_mean(loss)
tf.print(tf.shape(loss), summarize=-1)
# [7]
tf.print(first_loss, summarize=-1)
# 0.884061277
# second
mask = tf.where(y_true!=2, True, False)
y_t = y_true[mask]
tf.print(tf.shape(y_t))
# [7]
y_p = y_pred[mask]
tf.print(tf.shape(y_p))
# [7]
loss = tf.keras.losses.binary_crossentropy(y_t, y_p)
tf.print(tf.shape(loss), summarize=-1)
# []
second_loss = tf.reduce_mean(loss)
tf.print(second_loss, summarize=-1)
# 1.15896356
在第一个版本中, 和y_t都y_p被广播到 7x7 张量中,因此交叉熵基本上是“全部对全部”计算的,然后求平均值。在第二种情况下,仅计算每对对应值的交叉熵,这是正确的做法。
如果您只是删除tf.squeeze上面示例中的操作,结果就会得到纠正。
添加回答
举报