使用shap.DeepExplainer解释含GlobalMaxPooling1D的CNN时出现形状不匹配错误
错误原因
- SHAP的DeepExplainer对TensorFlow/Keras的
GlobalMaxPooling1D操作的梯度计算逻辑存在适配缺陷。GlobalMaxPooling1D会把形状为(批量大小, 序列长度, 通道数)的三维张量压缩为(批量大小, 通道数)的二维张量,反向传播计算梯度时,SHAP没有正确处理维度扩张逻辑,导致梯度计算时二维的梯度张量和三维的上游张量形状不匹配,就是你报错中[100,128]与[100,46,128]的冲突。 - 你的SHAP初始化代码中传入的模型变量为
model_lstm,但你贴出的是CNN模型的定义代码,若你实际传入的模型和需要解释的CNN模型不是同一个,也会触发维度不匹配问题。
解决方案
你可以根据自己的需求选择以下任意一种方案修复问题:
- 改动最小的方案:将
GlobalMaxPooling1D替换为SHAP兼容性更好的GlobalAveragePooling1D,即把代码中的out = GlobalMaxPooling1D()(out)修改为out = GlobalAveragePooling1D()(out),该改动对情感分析CNN的精度影响很小,可直接验证效果。 - 若必须保留
GlobalMaxPooling1D,可以将DeepExplainer替换为兼容性更好的GradientExplainer,示例代码如下:
explainer = shap.GradientExplainer(model, train_padded[:100]) shap_values = explainer.shap_values(test_padded[:20])
- 先修正变量名错误,确保传入
DeepExplainer的模型变量是你实际训练好的CNN模型,将explainer = shap.DeepExplainer(model_lstm, train_padded[:100])中的model_lstm替换为你定义CNN时的模型变量名(即你代码中的model)。 - 升级SHAP和TensorFlow到最新正式版本,部分新版本已经修复了
GlobalMaxPooling1D的梯度适配问题。
内容的提问来源于stack exchange,提问作者user6694665
相关产品推荐
相关产品推荐

