如何解决Keras自定义损失函数中Cannot convert a symbolic Tensor报错
问题根因
StandardScaler.inverse_transform是面向numpy数组实现的方法,无法处理Keras损失函数运行时传入的符号张量(损失函数在计算图构建阶段就会被调用,此时传入的y_true/y_pred没有实际数值,仅为占位张量对象),因此触发第一个报错。- Keras张量没有原生numpy风格的
.reshape实例方法,直接调用会触发第二个报错。
可行解决方案
直接用张量操作实现逆标准化逻辑,不需要调用sklearn的方法。StandardScaler的逆变换公式为:原始值 = 标准化值 * 标准差 + 均值,我们提前取出scaler拟合得到的均值、标准差参数,在损失函数里用Keras后端API完成计算即可。
修改后的代码如下:
from keras import backend as k # 提前从拟合好的scaler中取出统计参数,两个都是固定数值常量 lab_mean = lab_scaler2.mean_[0] lab_std = lab_scaler2.scale_[0] def root_mean_squared_error(y_true, y_pred): # 张量操作实现逆标准化,完全适配Keras计算图 y_true_original = y_true * lab_std + lab_mean y_pred_original = y_pred * lab_std + lab_mean # 如需调整形状使用k.reshape,不要用numpy风格的.reshape方法 # 示例:y_pred_original = k.reshape(y_pred_original, (-1, 1)) return k.sqrt(k.mean(k.square(y_pred_original - y_true_original)))
补充优化建议
如果仅需要在最终评估阶段得到原始尺度的RMSE指标,不需要用原始尺度做损失优化的话,更推荐训练时直接用标准化后的标签计算普通RMSE损失,训练完成后对预测结果执行inverse_transform再算指标,训练效率会更高。
内容的提问来源于stack exchange,提问作者Darkstar Dream
相关产品推荐
相关产品推荐

