Керас потеря функции понимания - PullRequest
0 голосов
/ 07 ноября 2018

Чтобы лучше понять некоторые обратные вызовы Keras, я хочу искусственно создать nan убыток.

Это функция

def soft_dice_loss(y_true, y_pred):

  from keras import backend as K
  if K.eval(K.random_normal((1, 1), mean=2, stddev=2))[0][0] // 1 == 2.0:
    # return nan
    return K.exp(1.0) / K.exp(-10000000000.0) - K.exp(1.0) / K.exp(-10000000000.0)

  epsilon = 1e-6

  axes = tuple(range(1, len(y_pred.shape) - 1))
  numerator = 2. * K.sum(y_pred * y_true, axes)
  denominator = K.sum(K.square(y_pred) + K.square(y_true), axes)

 return 1 - K.mean(numerator / (denominator + epsilon))

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

keras outputs

Время от времени, хотя, когда я пытаюсь запустить код, он останавливается прямо в начале (до первой эпохи) с ошибкой, говоря, что An operation has None for gradient. Please make sure that all of your ops have a gradient defined

Значит ли это, что случайная функция Кераса вычисляется только один раз, а затем всегда возвращает одно и то же значение? Если да, то почему и как я могу создать функцию потерь, которая время от времени возвращает nan?

1 Ответ

0 голосов
/ 08 ноября 2018

Ваш первый условный оператор оценивается только после определения функции потерь (т.е. вызывается; именно поэтому Keras останавливается прямо в начале). Вместо этого вы можете использовать keras.backend.switch для интеграции вашего условного выражения в логику графа. Ваша функция потери может быть чем-то вроде:

import keras.backend as K
import numpy as np


def soft_dice_loss(y_true, y_pred):
    epsilon = 1e-6
    axes = tuple(range(1, len(y_pred.shape) - 1))
    numerator = 2. * K.sum(y_pred * y_true, axes)
    denominator = K.sum(K.square(y_pred) + K.square(y_true), axes)
    loss = 1 - K.mean(numerator / (denominator + epsilon))

    return K.switch(condition=K.random_normal((), mean=0, stddev=1) > 3,
                    then_expression=K.variable(np.nan),
                    else_expression=loss)
...