【发布时间】:2022-06-28 20:44:50
【问题描述】:
我想在 Tensorflow 中实现多标签边距损失,使用 pytorch 的定义作为方向,即
https://pytorch.org/docs/stable/generated/torch.nn.MultiLabelMarginLoss.html
这是我想出的天真的解决方案:
def naive(y_true, y_pred, mu = 1.0):
pos = tf.ragged.boolean_mask(y_pred, tf.cast(y_true, dtype=tf.bool))
neg = tf.ragged.boolean_mask(y_pred, tf.cast(1 - y_true, dtype=tf.bool))
loss = 0
for i in range(y_true.shape[0]):
loss += tf.reduce_mean(tf.nn.relu(mu - (tf.transpose([pos[i]]) - neg[i])))
return loss
上面的实现产生了正确的结果(见下面的例子),但我很难从函数中删除循环,即用矩阵/向量乘法等表示。
例子:
y_pred = tf.constant([[0.1, 0.2, 0.4, 0.8]], dtype=tf.float32)
print(y_pred)
y_true = tf.constant([[1, 0, 0, 1]], dtype=tf.float32)
print(y_true)
naive(y_true, y_pred)
# 0.25 * ((1-(0.1-0.2)) + (1-(0.1-0.4)) + (1-(0.8-0.2)) + (1-(0.8-0.4)))
# 0.8500
# (see pytorch example)
非常欢迎任何想法。
【问题讨论】:
-
除了您使用的是 for 循环之外,结果是否正确?
-
@AloneTogether 是的,结果是正确的,我在问题中添加了一个示例。
-
但是为什么你需要一个循环呢?
-
@AloneTogether 我没有。我的目标是摆脱循环并使用高效的 numpy/tensorflow 表达式(例如矩阵向量乘法、广播等)来表达整个损失函数,以在训练 NN 模型时加快损失计算。
-
@AloneTogether 输入
y_true和y_pred的第一个维度对应于批次维度,因此多个样本相互堆叠。在我的实现中,该函数在批次维度上循环以单独处理每个样本。 (事实上,在上面的例子中,批次只包含一个样本,即输入形状是(1, 4)。
标签: python numpy tensorflow tensorflow2.0