使用自定义损失函数时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
相关产品推荐
相关产品推荐

