我想编写一个带有两个参数A和B,具有相同形状(例如13x13或其他形状)的张量的函数,并返回一个数字,该数字表示在逐个应用二进制交叉熵时所有损失的总和。因此,对于A [i,j]和B [i,j],我们找到binary_loss,然后求和所有i,j。如何在Keras和Tensorflow中实现它?
答案 0 :(得分:0)
您可以使用后端函数sum
和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]
已作为其K.sum()
参数传递给axis
,以求和一个样本的所有元素(而不是整个批次)
答案 1 :(得分:0)
this answer中建议的解决方案实际上可能不是您(读者)想要的。
如果A
和B
是NxM
,其中M > 1
,则binary_crossentropy(A, B)
不会按元素计算二进制交叉熵,而是{{ 1}}返回形状为binary_crossentropy(A, B)
的数组,其中Nx1
对应于binary_crossentropy(A, B)[i]
和A[i]
之间的平均二进制交叉熵(即,它计算之间的二进制交叉熵对于所有B[i]
,A[i][j]
和B[i][j]
,然后计算j
二进制交叉熵的平均值。
如果您要计算元素M
和A(i, j)
之间的二进制交叉熵,那么对于所有B(i, j)
和i
,您可能首先想重塑{ {1}}和j
,因此它们的形状为A
。
B
但是,如果要按元素计算(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)))
之间的二进制交叉熵,并取所有二进制交叉熵的平均值,则无需调整{ {1}}和A
。因此,如果B
和A
是B
数组,则A
会生成一个B
数组,其中每个元素对应于行之间的平均二进制交叉熵NxM
中的binary_crossentropy(A, B)
和Nx1
中的i
行(对于A
)。最后,要取所有二进制交叉熵的平均值,我们还需要取i
的平均值,即B
。