如何在 Keras 自定义损失函数中使用张量?

Posted

技术标签:

【中文标题】如何在 Keras 自定义损失函数中使用张量?【英文标题】:How to use the tensors inside a Keras custom loss function? 【发布时间】:2021-02-08 03:49:17 【问题描述】:

我需要使用自定义损失函数训练模型,该模型还应在预测后立即更新一些外部函数,如下所示:

def loss_fct(y_true, y_pred):
    global feeder
 
    # Change values of feeder given y_pred
    for value in y_pred:
        feeder.do_something(value)
    
    return K.mean(y_true - y_pred, axis=-1)

但这不起作用,因为 TF 无法遍历 AutoGraph 中的张量:

OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed: AutoGraph did convert this function. This might indicate you are trying to use an unsupported feature.

我的模型是这样的

model = Sequential()
model.add(Input(shape=(DIM, )))
model.add(Dense(DIM, activation=None))
model.add(Dense(16, activation=None))
model.add(Dense(4, activation="softmax"))
model.compile(optimizer="adam", loss=loss_fct)
model.summary()

它是这样训练的:

model.fit(x=feeder.feed,
    epochs=18,
    verbose=1,
    callbacks=None,
)

feeder.feed 是生成 2 个 NumPy 数组的生成器。


【问题讨论】:

首先,检查您的生成器产生的值。 y_pred 似乎是一个 4 dim 张量。那么,您对它的迭代有什么期望呢?您也可以通过使用张量的形状来间接迭代,例如 y_true[0] 是的,你是对的。 y_pred 可以是例如 [1, 0, 1, 0]。但是,当程序在 Autograph 中运行时,我无法执行 y_true[0] 【参考方案1】:

经过大量研究,我遇到了this answer。该方法似乎没有任何问题,但它是一个Tensorflow >= 2.2.0 错误,默认启用Eager Execution。

最后,为了解决这个问题,使用model.compile(..., run_eagerly=True) 并且可以在训练期间进行迭代和访问张量。

【讨论】:

以上是关于如何在 Keras 自定义损失函数中使用张量?的主要内容,如果未能解决你的问题,请参考以下文章

无法向自定义损失输入数据:渴望执行函数的输入不能是 Keras 符号张量

每个张量组的 Keras 自定义损失函数

使用张量流在 keras 中对损失函数的输入进行切片

keras中的加权mse自定义损失函数

如何在生成器提供的 Keras 自定义损失函数中访问样本权重?

在 CNN 的 keras 自定义损失函数中操作数据