2

我有一个名为的常规 keras 模型,e我想比较它在自定义损失函数中的输出。y_predy_true

from keras import backend as K
def custom_loss(y_true, y_pred):
    return K.mean(K.square(e.predict(y_pred)-e.predict(y_true)), axis=-1)

我收到错误消息:AttributeError: 'Tensor' object has no attribute 'ndim' 这是因为y_trueandy_pred都是张量对象,并且keras.model.predict期望通过numpy.array.

知道如何keras.model在自定义损失函数中成功使用我的吗?

如果需要,我愿意获取指定层的输出,或者将我的转换keras.modeltf.estimator对象(或其他任何东西)。

4

1 回答 1

6

首先,让我们尝试了解您收到的错误消息:

AttributeError:“张量”对象没有属性“ndim”

我们看一下 Keras 文档,找到 Keras 模型的predict方法。我们可以看到函数参数的描述:

x:输入数据,作为 Numpy 数组。

因此,模型试图获取 a 的ndims属性numpy array,因为它需要一个数组作为输入。另一方面,Keras 框架的自定义损失函数tensors作为输入。因此,不要在其中编写任何 python 代码——它永远不会在评估期间执行。这个函数只是被调用来构建计算图。


好的,既然我们发现了该错误消息背后的含义,那么我们如何在自定义损失函数中使用 Keras 模型呢?简单的!我们只需要得到模型的评估图。

更新

使用global关键字是一种不好的编码习惯。此外,现在到 2020 年,我们在 Keras 中拥有更好的功能性 API ,这使得分层黑客变得不必要。最好使用这样的东西:

from keras import backend as K

def make_custom_loss(model):
    """Creates a loss function that uses `model` for evaluation
    """
    def custom_loss(y_true, y_pred):
        return K.mean(K.square(model(y_pred) - model(y_true)), axis=-1)
    return custom_loss

custom_loss = make_custom_loss(e)

已弃用

尝试这样的事情(仅适用于Sequential模型和非常旧的 API):

def custom_loss(y_true, y_pred):
    # Your model exists in global scope
    global e

    # Get the layers of your model
    layers = [l for l in e.layers]

    # Construct a graph to evaluate your other model on y_pred
    eval_pred = y_pred
    for i in range(len(layers)):
        eval_pred = layers[i](eval_pred)

    # Construct a graph to evaluate your other model on y_true
    eval_true = y_true
    for i in range(len(layers)):
        eval_true = layers[i](eval_true)

    # Now do what you wanted to do with outputs.
    # Note that we are not returning the values, but a tensor.
    return K.mean(K.square(eval_pred - eval_true), axis=-1)

请注意,上面的代码未经测试。但是,无论实现如何,总体思路都将保持不变:您需要构建一个图,其中y_trueandy_pred将通过它流向最终操作。


于 2018-02-11T02:58:32.207 回答