在定制的keras损失中使用keras模型 [英] Use a keras model in a custom keras loss
问题描述
我有一个名为e
的常规keras模型,我想在自定义损失函数中比较y_pred
和y_true
的输出.
I have a regular keras model called e
and I would like to compare its output for both y_pred
and y_true
in my custom loss function.
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_true
和y_pred
都是张量对象,并且keras.model.predict
希望传递给numpy.array
.
I am getting the error: AttributeError: 'Tensor' object has no attribute 'ndim'
This is because y_true
and y_pred
are both tensor object and keras.model.predict
expects to be passed a numpy.array
.
有人知道如何在自定义损失函数中成功使用keras.model
吗?
Any idea how I may succeed in using my keras.model
in my custom loss function?
如果需要,我愿意获取指定图层的输出,也可以将我的keras.model
转换为tf.estimator
对象(或其他任何对象).
I am open to getting the output of a specified layer if need be or to converting my keras.model
to a tf.estimator
object (or anything else).
推荐答案
首先,让我们尝试了解您收到的错误消息:
First, let's try to understand the error message you're getting:
AttributeError:张量"对象没有属性"ndim"
AttributeError: 'Tensor' object has no attribute 'ndim'
让我们看看Keras文档,找到Keras模型的 predict 方法.我们可以看到函数参数的描述:
Let's take a look at the Keras documentation and find the predict method of Keras model. We can see the description of the function parameters:
x:输入数据,作为一个Numpy数组.
x: the input data, as a Numpy array.
因此,该模型试图获取numpy array
的ndims
属性,因为它希望将数组作为输入.另一方面,Keras框架的自定义损失函数将tensors
作为输入.因此,请勿在其中编写任何python代码-永远不会在评估过程中执行该代码.只是调用此函数来构造计算图.
So, the model is trying to get a ndims
property of a numpy array
, because it expects an array as input. On other hand, the custom loss function of the Keras framework gets tensors
as inputs. So, don't write any python code inside it - it will never be executed during evaluation. This function is just called to construct the computational graph.
好吧,现在我们找到了该错误消息的含义,我们如何在自定义损失函数中使用Keras模型?简单的!我们只需要获取模型的评估图即可.
Okay, now that we found out the meaning behind that error message, how can we use a Keras model inside custom loss function? Simple! We just need to get the evaluation graph of the model.
使用global
关键字是一种不良的编码习惯.此外,现在在2020年,我们会在Keras中使用更好的功能API 与不必要的层.最好使用这样的东西:
The use of global
keyword is a bad coding practice. Also, now in 2020 we have better functional API in Keras that makes hacks with layers uneccessary. Better use something like this:
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):
Deprecated
Try something like this (only for Sequential
models and very old 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
和y_pred
将通过它进行最终操作.
Please note that the code above is not tested. However, the general idea will stay the same regardless of the implementation: you need to construct a graph, in which the y_true
and y_pred
will flow through it to the final operations.
这篇关于在定制的keras损失中使用keras模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!