Реализация пересечения по потерям объединения с использованием Tensorflow - PullRequest
4 голосов
/ 30 марта 2019

Это может быть больше вопросом градиента Tensorflow. Я пытался внедрить Intersection over Union (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)

Это работает как предсказано. Однако проблема, которую я имею, состоит в том, что потери не уменьшаются. Модель тренируется, хотя результаты не идеальны, поэтому мне интересно, правильно ли я ее реализую. Нужно ли самому вычислять градиенты? Я могу вычислить градиенты для этой потери IoU, полученной из этой статьи , используя tf.gradients(), хотя я не уверен, как включить это в tf.train.AdamOptimizer(). Читая документацию, я чувствую, что compute_gradients и apply_gradients - это команды, которые мне нужно использовать, но я не могу найти примеров того, как их использовать. Насколько я понимаю, граф Tensorflow должен иметь возможность придумывать сам градиент через правило цепочки. Так нужен ли в этой задаче собственный градиент? Если пользовательский градиент не нужен, то у меня может быть просто некорректная проблема, и мне нужно настроить некоторые гиперпараметры.

Примечание: Я пробовал реализацию IoU Tensorflow, tf.metrics.mean_iou(), но каждый раз он выплевывает inf, поэтому я отказался от этого.

1 Ответ

3 голосов
/ 31 марта 2019

Расчет градиента происходит внутри функции 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

Почему нельзя использовать IOU для обучения?

...