【问题标题】:Implementing Multi-Label Margin-Loss in Tensorflow在 TensorFlow 中实现多标签边距损失
【发布时间】: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_truey_pred 的第一个维度对应于批次维度,因此多个样本相互堆叠。在我的实现中,该函数在批次维度上循环以单独处理每个样本。 (事实上​​,在上面的例子中,批次只包含一个样本,即输入形状是(1, 4)

标签: python numpy tensorflow tensorflow2.0


【解决方案1】:

您可以尝试像这样使用tf.while_loop

import tensorflow as tf

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 = tf.Variable(0.0, trainable=False)
    i = tf.constant(0)    
    while_condition = lambda i, loss, pos, neg: tf.math.less(i, tf.shape(y_true)[0])

    def body(i, loss, p, n):
      loss.assign_add(tf.reduce_mean(tf.nn.relu(1.0 - (tf.transpose([p[i]]) - n[i]))))
      return tf.add(i, 1), loss, p, n

    _, loss, _,_ = tf.while_loop(while_condition, body, loop_vars=(i, loss, pos, neg))

    return loss

y_pred = tf.constant([[0.1, 0.2, 0.4, 0.8], [0.1, 0.2, 0.4, 0.8]], dtype=tf.float32)
y_true = tf.constant([[1, 0, 0, 1], [1, 0, 0, 1]], dtype=tf.float32)
naive(y_true, y_pred)
<tf.Tensor: shape=(), dtype=float32, numpy=1.7>

【讨论】:

    猜你喜欢
    • 2018-12-08
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2021-07-08
    • 2017-04-08
    • 1970-01-01
    • 2019-12-16
    相关资源
    最近更新 更多