Keras损失函数的理解

时间:2018-11-07 17:27:46

标签: python tensorflow keras nan loss

为了更好地理解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

这是否意味着Keras的随机函数仅被求值一次,然后总是返回相同的值? 如果是这样,那是为什么?如何创建一个不时返回nan的损失函数?

1 个答案:

答案 0 :(得分:1)

只有定义了损失函数后(即被调用;这才是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)