使用 TensorFlow 实现联合损失的交集

Posted

技术标签:

【中文标题】使用 TensorFlow 实现联合损失的交集【英文标题】:Implementing Intersection over Union Loss Using Tensorflow 【发布时间】:2019-08-20 21:20:44 【问题描述】:

这可能更像是一个 TensorFlow 梯度问题。我一直在尝试将 Intersection over Union (IoU) 作为损失来实施,并且遇到了一些问题。言归正传,这是我计算 IoU 的代码的 sn-p:

def get_iou(masks, predictions):
    ious = []
    for i in range(batch_size):
        mask = masks[i]
        pred = predictions[i]
        masks_sum = tf.reduce_sum(mask)
        predictions_sum = tf.reduce_mean(pred)
        intersection = tf.reduce_sum(tf.multiply(mask, pred))
        union = masks_sum + predictions_sum - intersection
        iou = intersection / union
        ious.append(iou)
    return ious

iou = get_iou(masks, predictions)
mean_iou_loss = -tf.log(tf.reduce_sum(iou))
train_op = tf.train.AdamOptimizer(0.001).minimize(mean_iou_loss)

它按预期工作。但是,我遇到的问题是损失并没有减少。该模型确实进行了训练,尽管结果不太理想,所以我想知道我是否正确实施它。我必须自己计算梯度吗?我可以使用tf.gradients() 计算由this paper 得出的这个IoU 损失的梯度,尽管我不确定如何将它与tf.train.AdamOptimizer() 结合起来。阅读文档,我觉得compute_gradientsapply_gradients 是我需要使用的命令,但我找不到任何关于如何使用它们的示例。我的理解是,Tensorflow 图应该能够通过链式法则自己得出梯度。那么在这个问题中甚至需要自定义渐变吗?如果不需要自定义渐变,那么我可能只是遇到了不适定问题,需要调整一些超参数。

注意:我已经尝试过 Tensorflow 的 IoU 实现,tf.metrics.mean_iou(),但每次都会吐出inf,所以我放弃了。

【问题讨论】:

loss 是如何定义的?它与mean_iou_loss 有何关系? 好眼光,我只是抄错了。 mean_iou_loss 是损失。在上面修复它。 【参考方案1】:

梯度计算发生在optimizer.minimize 函数内部,因此不需要在损失函数内部显式使用。但是,您的实现只是缺少一个可优化的、可训练的变量。

iou = get_iou(masks, predictions)
mean_iou_loss = tf.Variable(initial_value=-tf.log(tf.reduce_sum(iou)), name='loss', trainable=True)
train_op = tf.train.AdamOptimizer(0.001).minimize(mean_iou_loss)

除了数值稳定性、可微性和特定实现之外,这应该足以将其用作损失函数,它会随着迭代而改变。

也看看:

https://arxiv.org/pdf/1902.09630.pdf

Why does one not use IOU for training?

【讨论】:

感谢您的回答,尽管此修复不起作用。代码挂在定义张量变量阶段mean_iou_loss = tf.Variable(initial_value=-tf.log(tf.reduce_sum(iou)), name='loss', trainable=True) 奇怪,它绝对应该工作。它会抛出任何错误吗? 尝试使用一些小的随机数据,并将日志记录设置为 info,可能只是 oom 错误 不是OOM;我尝试了批量大小为 1 并通过 nvidia-smi 检查内存,但没有任何改变。它似乎挂在树的各个部分。我尝试将其初始化为常量而不是 -tf.log(tf.reduce_sum(iou)),它就是这样工作的。 你使用什么样的输入数据?类型、尺寸?

以上是关于使用 TensorFlow 实现联合损失的交集的主要内容,如果未能解决你的问题,请参考以下文章

Tensorflow 实现 crf 损失

ado.net 和 dapper 之间的交集/联合是啥?

实现二元交叉熵损失给出了与 Tensorflow 不同的答案

损失函数tensorflow2实现——Python实战

在 Swift 数组上设置操作(联合、交集)?

如何为 keras 模型使用 tensorflow 自定义损失?