14

我正在尝试实现此损失函数:本文档中的MCFD_loss_function (P6):损失函数

所以我创建了一个这样的新函数:

def mcfd_loss(y_true, y_pred):
    return K.sum( # ∑
        K.cast(
            K.greater( # only values greater than 0 (+ float32 cast)
                  K.dot(K.sign(y_pred),  # π
                        K.sign(y_true))
           , 0)
        , 'float32')
    )

但是当我开始训练时,会出现这个错误:

ValueError:一个操作有None梯度。请确保您的所有操作都定义了渐变(即可微分)。没有梯度的常见操作:K.argmax、K.round、K.eval。

我不知道我错过了哪一点。似乎引发了错误,因为我使用了更大的功能。我不知道这个错误是什么意思以及如何纠正我的问题。

谢谢。

4

1 回答 1

4

您希望您的损失函数检查是否sign(f_(t,1))*sign(Y_(t+1))大于 0。由于sign在 0 处不可微,我建议softsign改用。

由于大于函数也是不可微分的,因此可以使用以下近似值(参见此处):maxϵ(x,y):= 0.5(x + y + absϵ(x − y))、 whereabsϵ(x):=sqrt(x^2 + ϵ)ϵ > 0。为简单起见,我将在下面的代码示例中将此近似称为greater_approx. (请注意,您只需插入上面的计算)

查看损失函数的定义,您必须将总和除以预测数 ( K.get_variable_shape(y_pred)[0])(还要加上一个减号)。P对应于根据时间序列预测论文中损失函数的预测数量。

总而言之,您的损失函数应如下所示:

def mcfd_loss(y_true, y_pred):
   return - (1/K.get_variable_shape(y_pred)[0]) * K.sum( # ∑
      K.cast(
         greater_approx( # only values greater than 0 (+ float32 cast)
            K.dot(K.softsign(y_pred),  # π
                    K.softsign(y_true))
         , 0)
      , 'float32')
   )

最后一句话:对于在 Keras 中使用自定义损失函数,请查看这个SO question

于 2019-02-27T22:41:07.360 回答