这可能更多是Tensorflow梯度问题。我一直在尝试将联合路口(IoU)实施为损失,并且遇到了一些问题。到目前为止,这是我计算IoU的代码的片段:
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()
合并,但我可以使用tf.train.AdamOptimizer()
计算由this paper得出的IoU损耗的梯度。阅读文档后,我觉得compute_gradients
和apply_gradients
是我需要使用的命令,但是找不到如何使用它们的示例。我的理解是,Tensorflow图应该能够通过链法则提出梯度本身。那么在这个问题上甚至需要自定义渐变吗?如果不需要自定义渐变,那么我可能会遇到不适的问题,需要调整一些超参数。
注意:我已经尝试过Tensorflow的IoU的实现tf.metrics.mean_iou()
,但是每次都会吐出inf
,所以我放弃了。
答案 0 :(得分:3)
梯度计算在optimizer.minimize
函数内部进行,因此不需要在loss函数内部进行显式使用。但是,您的实现只是缺少可优化的,可训练的变量。
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)
除了数值稳定性,可微性和特定的实现之外,这足以将其用作损失函数,该函数会随着迭代而改变。
也来看看: