You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用自定义损失函数时Keras出现InvalidArgumentError报错求助

解决Keras自定义损失函数中的InvalidArgumentError问题

嘿,我一眼就看出问题出在哪了——你在自定义损失函数里直接用了K.eval(),这可是Keras自定义损失函数的大忌!

错误原因

Keras的损失函数必须全程使用符号张量运算,不能中途把符号张量转换成数值(比如用K.eval()或者直接转numpy数组)。当你调用K.eval()时,会强制要求立即计算张量的值,但此时模型还在编译阶段,输入输出的占位符(比如你报错里的dense_95_target)还没有被喂入实际数据,自然就会抛出这个占位符未赋值的错误。

而且你的my_loss_np函数完全没必要存在,我们可以直接用Keras后端的符号函数实现相同的逻辑。

修正后的代码

下面是正确的自定义损失函数实现,全程用符号张量操作,不会破坏计算图:

import keras.backend as K
from keras.models import Sequential
from keras.layers import Bidirectional, LSTM, Dense

# 构建模型部分保持不变
model = Sequential()
model.add(Bidirectional(LSTM(128, return_sequences=True), input_shape=(1,8)))
model.add(Bidirectional(LSTM(128)))
model.add(Dense(64, activation='relu'))
model.add(Dense(20, activation='softmax'))

def my_loss(y_true, y_pred):
    # 用Keras后端的argmax对每个样本的预测结果取最大值索引(符号运算)
    labels = K.argmax(y_pred, axis=-1)
    # 把整数张量转换成浮点型,因为均值运算需要浮点类型
    labels_float = K.cast(labels, K.floatx())
    # 计算均值作为损失
    loss = K.mean(labels_float)
    return loss

# 现在编译模型就不会报错了
model.compile(loss=my_loss, optimizer='adam')

额外提醒

我注意到你的损失函数里完全没用到y_true(真实标签),这有点奇怪——通常损失函数需要结合真实标签和预测值来计算误差。如果这是你故意设计的逻辑那没问题,但如果是不小心遗漏了,记得把y_true加入到损失计算的逻辑里哦。

总的来说,写Keras自定义损失函数的核心原则就是:所有运算都要用Keras后端的符号函数实现,绝不中途转成数值数组,这样Keras才能正确构建计算图,避免这类占位符错误。

内容的提问来源于stack exchange,提问作者John Watts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:19:16