如何按元素应用二元交叉熵,然后在 Keras 中对所有这些损失求和?

How do I apply the binary cross-entropy element-wise and then sum all these losses in Keras?

我想写一个带有两个参数的函数,AB,相同形状的张量(例如,13x13,或其他形状),并且returns 一个数字,表示按分量应用二元交叉熵时所有损失的总和。因此,对于 A[i, j]B[i, j],我们找到二元交叉熵损失,然后对所有 ij 求和。如何在 Keras 和 Tensorflow 中实现?

您可以使用后端函数 sum and binary_crossentropy 轻松定义此函数(或直接在 Tensorflow 中使用它们的等效函数):

def func(A, B):
    return K.sum(K.binary_crossentropy(A,B)) 

注意K.binary_crossentropy()假设给定的输入值是概率;如果不是这种情况,则将 from_logit=True 作为另一个参数传递给它。

此外,如果您想在 Lambda 层中使用此函数,则需要对其进行更改,使其接受张量列表作为输入:

def func(inp):
    return K.sum(K.binary_crossentropy(inp[0], inp[1]), [1,2]) # take the sum for each sample independently

# ...
out = Lambda(func)([A, B])

如您所见,[1,2] 已作为其 axis 参数传递给 K.sum(),以对单个样本的所有元素求和(而不是对整个元素求和)批次)。

中建议的解决方案实际上可能不是您 (reader) 正在寻找的。

如果 ABNxM,其中 M > 1,那么 binary_crossentropy(A, B) 将不会按元素计算二进制交叉熵,但是binary_crossentropy(A, B) returns 形状为 Nx1 的数组,其中 binary_crossentropy(A, B)[i] 对应于 A[i]B[i] 之间的平均二进制交叉熵(即它计算A[i][j]B[i][j] 之间的二元交叉熵,对于所有 j,然后计算 M 二元交叉熵的平均值)。

如果你想计算元素A(i, j)B(i, j)之间的二元交叉熵,对于所有ij,那么你可能首先要重塑 AB,使它们具有 (N*M)x1.

的形状
import numpy as np
import tensorflow as tf

a = np.random.rand(4, 2).reshape((-1, 1))
b = np.random.rand(4, 2).reshape((-1, 1))
print("ce between a[i, j] and b[i, j]) =", tf.losses.binary_crossentropy(a, b))
print("average cross-entropy =", np.mean(tf.losses.binary_crossentropy(a, b)))

然而,如果你想逐元素计算 AB 之间的二元交叉熵,并取所有二元交叉熵的平均值,那么你不需要重塑 AB。因此,如果 ABNxM 数组,那么 binary_crossentropy(A, B) 会生成一个 Nx1 数组,其中每个元素对应于行之间的平均二进制交叉熵AiBi 行(对于 i=1, ..., N)。最后,取所有二元交叉熵的平均值,我们还需要取binary_crossentropy(A, B)的平均值,即tf.reduce_mean(binary_crossentropy(A, B)).