TensorFlow / Keras: Как получить значимые значения потерь из моей обобщенной функции потери костей? - PullRequest
0 голосов
/ 21 июня 2019

Я пытаюсь выполнить семантическую сегментацию в API-интерфейсе Keras в TensorFlow 1.10 (с использованием Python) с помощью функции обобщенной потери кубиков :

def generalized_dice_loss(onehots_true, logits):
    smooth = tf.constant(1e-17)
    onehots_true, logits = mask(onehots_true, logits) # Not all of my pixels contain ground truth, and I filter those pixels out, which results in shape [num_gt_pixels, num_classes]-shaped labels and logits.
    probabilities = tf.nn.softmax(logits)
    weights = 1.0 / (tf.reduce_sum(onehots_true, axis=0)**2)
    weights = tf.clip_by_value(weights, 1e-17, 1.0 - 1e-7) # Is this the correct way of dealing with inf values (the results of zero divisions)?
    numerator = tf.reduce_sum(onehots_true * probabilities, axis=0)
    numerator = tf.reduce_sum(weights * numerator)

    denominator = tf.reduce_sum(onehots_true + probabilities, axis=0)
    denominator = tf.reduce_sum(weights * denominator)

    loss = 1.0 - 2.0 * (numerator + smooth) / (denominator + smooth)
    return loss

Однако я изо всех сил пытаюсь получитьлюбая значимая потеря, которая не всегда 1. Что я здесь делаю не так?

После того, как начальные веса (по одному для каждого класса) вычислены, они содержат много inf от нулевых делений, как обычнотолько небольшое подмножество всех классов присутствует в образце изображения.Поэтому я подрезаю веса к диапазону [1e-17, 1-1e-17] (это хорошая идея?), После чего они выглядят так:

tf.Tensor(
[4.89021e-05 2.21410e-10 5.43187e-11 1.00000e+00 1.00000e+00 4.23855e-07
 5.87461e-09 3.13044e-09 2.95369e-07 1.00000e+00 1.00000e+00 2.22499e-05
 1.00000e+00 1.73611e-03 9.47212e-10 1.12608e-05 2.77563e-09 1.00926e-08
 7.74787e-10 1.00000e+00 1.34570e-07], shape=(21,), dtype=float32)

, что мне кажется хорошимхотя они довольно маленькие.Числители (tf.reduce_sum(onehots_true * probabilities, axis=0) до их взвешивания) выглядят следующим образом:

tf.Tensor(
[3.42069e+01 0.00000e+00 9.43506e+03 7.88478e+01 1.50554e-02 0.00000e+00
 1.22765e+01 4.36149e-01 1.75026e+02 0.00000e+00 2.33183e+02 1.81064e-01
 0.00000e+00 1.60128e+02 1.48867e+04 0.00000e+00 3.87697e+00 4.49753e+02
 5.87062e+01 0.00000e+00 0.00000e+00], shape=(21,), dtype=float32)
tf.Tensor(1.0, shape=(), dtype=float32)

, что также выглядит разумно, поскольку они в основном имеют соответствующие размеры меток, умноженные на уверенность сети относительно них (что, вероятно,низкий в начале обучения).Знаменатели (tf.reduce_sum(onehots_true + probabilities, axis=0), до взвешивания) также выглядят хорошо:

tf.Tensor(
[ 14053.483   25004.557  250343.36    66548.234    6653.863    3470.502
   5318.3926 164206.19    19914.338    1951.0701   3559.3235   7248.4717
   5984.786    7902.9004 133984.66    41497.473   25010.273   22232.062
  26451.926   66250.39     6497.735 ], shape=(21,), dtype=float32)

Они большие, но этого следует ожидать, поскольку вероятности класса пикселя составляют сумму 1, а следовательно, и суммуэти знаменатели должны более или менее равняться количеству пикселей с истинностью.

Тем не менее, суммирование числителей дает очень небольшую сумму (~ 0,001, хотя иногда она находится в диапазоне из одной цифры), в то время как знаменатель суммирует оченьбольшие значения.Это приводит к тому, что моя последняя потеря - 1 или что-то очень похожее на это.Как я могу смягчить этот эффект и получить стабильные градиенты?Я в значительной степени реализовал точную формулу потери игральных костей.Что мне здесь не хватает?

1 Ответ

0 голосов
/ 21 июня 2019

Очевидно, мне нужно опустить веса, тогда я получу работоспособную функцию потерь. Понятия не имею, почему я не могу использовать веса, и что бы это добавило, если бы я мог. Дополнительный вопрос: https://stats.stackexchange.com/questions/414107/why-are-weights-being-used-in-generalized-dice-loss-and-why-cant-i

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...