如何为Keras多输出模型传递样本权重?
如何为Keras多输出模型传递样本权重?
我太懂你这种明明形状对却报错的头疼了!在多输出模型里传样本权重确实容易踩结构匹配的坑,咱们来搞定这个问题:
首先说报错的原因:从你贴的错误栈来看,Keras在解析样本权重的时候找不到键0,这本质是样本权重的传递结构和模型输出的结构不匹配。你的模型是按列表顺序定义的两个输出层,但你尝试的两种传递方式(直接传一维数组、用字典映射)在新版本Keras里没能正确和输出结构对应上。
给你两种亲测有效的解决方法:
方法一:用列表对应输出顺序传递(最稳妥)
因为你的模型输出是按[回归输出, 分类输出]的顺序定义的,直接用列表传递样本权重,每个元素对应一个输出的权重(你要给两个输出用相同权重,就传两次同一个数组就行):
history = model.fit( X, {'regression_output': y_regression, 'classification_output': y_classification}, epochs=10, batch_size=32, sample_weight=[sample_weights, sample_weights], # 顺序和模型输出层定义的顺序完全一致 )
这种方式完全贴合模型的输出结构,Keras不需要额外解析键名,直接按顺序匹配,基本不会出错。如果之后你想给两个输出用不同的样本权重,只需要把列表里的两个元素换成对应的不同数组就行,非常灵活。
方法二:用字典传递(需严格匹配键名)
如果你偏好字典的方式,要确保所有字典的键名和输出层的name属性完全一致,同时注意在Keras 3.x(也就是TensorFlow 2.15及以后的集成Keras)中,需要确保模型编译时的损失/指标键、训练时的目标值字典键、样本权重字典键三者完全统一:
history = model.fit( X, {'regression_output': y_regression, 'classification_output': y_classification}, epochs=10, batch_size=32, sample_weight={ 'regression_output': sample_weights, 'classification_output': sample_weights }, )
不过这种方式有时候会因为版本兼容问题出现匹配错误,所以更推荐第一种列表传递的方式。
另外补充个小细节:样本权重只需要是和样本数一致的一维数组(比如你的(1000,)),不需要和输出的形状(比如(1000,1))完全一致,Keras会自动处理维度匹配的问题。
备注:内容来源于stack exchange,提问作者Vaida
相关产品推荐
相关产品推荐

