首先,让我们尝试理解您收到的错误消息:
AttributeError:“张量”对象没有属性“ndim”
我们看一下 Keras 文档,找到predict https://keras.io/models/sequential/#predictKeras模型的方法。我们可以看到函数参数的说明:
x:输入数据,作为 Numpy 数组。
因此,该模型试图获得ndims
的财产numpy array
,因为它需要一个数组作为输入。另一方面,Keras框架的自定义损失函数得到tensors
作为输入。因此,不要在其中编写任何 python 代码 - 它在评估期间永远不会被执行。该函数只是被调用来构建计算图。
好的,现在我们已经了解了该错误消息背后的含义,那么我们如何在自定义损失函数中使用 Keras 模型呢?简单的!我们只需要得到模型的评估图即可。
Update
指某东西的用途global
关键字是一种不好的编码习惯。另外,现在到了 2020 年,我们有更好的函数式API https://keras.io/getting-started/functional-api-guide/在 Keras 中,这使得层的 hack 变得不必要。最好使用这样的东西:
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_true
and y_pred
将流经它到最终的操作。