【问题标题】:How to define a weighted loss function in TensorFlow?如何在 TensorFlow 中定义加权损失函数?
【发布时间】:2016-09-19 20:59:55
【问题描述】:

我有一个 train_data 和 train_labels 的训练数据集,即 tensorflow 图中的 train_data_node 和 train_labels_node。 如你所知,我可以使用 tensorflow 的损失函数如下:

logits = model(train_data_node)
loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
    logits,train_labels_node))

但是,此损失函数平等地处理所有训练数据。 但在我们的情况下,我们希望有区别地处理数据。 例如,我们有一个与训练数据相对应的 csv 文件,以指示训练数据是原始数据还是增强数据。 然后我们要定义一个自定义的损失函数,让原始数据的损失起到更重要的作用,而增强数据的损失起到次要的作用,例如:

loss_no_aug = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(noAugLogits, noAugLabels))
loss_aug = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(augLogits, augLabels))
loss = loss_no_aug * PENALTY_COEFFICIENT + loss_aug

我已经定义了如下的损失函数,但它不起作用:

def calLoss(logits, labels, augs):
  noAugLogits = []
  noAugLabels = []
  augLogits = []
  augLabels = []
  tf.get_collection()
  for i in range(augs.shape[0]):
    if augs[i] == 1:
      noAugLogits.append(logits[i])
      noAugLabels.append(labels[i])
    else:
      augLogits.append(logits[i])
      augLabels.append(labels[i])
  noAugLogits = tf.convert_to_tensor(noAugLogits)
  noAugLabels = tf.convert_to_tensor(noAugLabels)
  augLogits = tf.convert_to_tensor(augLogits)
  augLabels = tf.convert_to_tensor(augLabels)
  return tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
      noAugLogits, noAugLabels)) * PENALTY_COEFFICIENT + \
      tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(augLogits, augLabels))

我认为我们应该使用张量运算来编写损失函数,但是我不熟悉它们。那么谁能给我一些关于如何定义损失函数的建议。

感谢您的友好回答或建议。

【问题讨论】:

  • 我在tensorflow中找到了一些处理张量的函数,例如tf.cond()、tf.boolen_mask和tf.gather()。但我不知道如何使用它们。在我们的情况下,关键问题是如何根据由 0 或 1 组成的 augs 张量对数据和标签张量进行切片,对应于增强和非增强。那么有人可以给我一个建议吗?非常感谢。

标签: python tensorflow


【解决方案1】:

我终于用tensorflow的函数tf.boolen_mask()自己解决了这个问题。定义的自定义加权损失函数如下:

def calLoss(logits, labels, augs):
  augSum = tf.reduce_sum(augs)
  pred = tf.less(augSum, BATCH_SIZE)

  def noaug(logits, labels, augs):
    augs = tf.cast(augs, tf.bool)
    noaugs = tf.logical_not(augs)
    noAugLogits = tf.boolean_mask(logits, noaugs)
    noAugLabels = tf.boolean_mask(labels, noaugs)
    augLogits = tf.boolean_mask(logits, augs)
    augLabels = tf.boolean_mask(labels, augs)
    noaugLoss = tf.reduce_mean(
        tf.nn.sparse_softmax_cross_entropy_with_logits(noAugLogits, noAugLabels))
    augLoss = tf.reduce_mean(
        tf.nn.sparse_softmax_cross_entropy_with_logits(augLogits, augLabels))
    return noaugLoss * PENALTY_COEFFICIENT + augLoss

  def aug(logits, labels):
    return tf.reduce_mean(
        tf.nn.sparse_softmax_cross_entropy_with_logits(logits, labels))

  return tf.cond(pred, lambda: noaug(logits, labels, augs), lambda: aug(logits, labels))

如你所见,我使用了一个 numpy 数组变量,augs,在对应的位置使用 1 和 0 来表示一批样本中的一个样本是增强的还是未增强的。然后我将变量转换为布尔张量并将其用作 tf.boolen_mask() 的布尔掩码来获取增强和非增强样本并分别计算损失。

【讨论】:

  • 觉得很有用!感谢分享
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-28
  • 2017-12-29
  • 2020-01-13
  • 2020-07-28
  • 2018-02-24
相关资源
最近更新 更多