Keras LSTM中非对称MAE自定义损失函数实现(张量输入)
实现适用于Keras LSTM的非对称MAE自定义损失函数(张量版本)
你这个非对称MAE的思路挺有意思——对预测右移(p>a)的情况根据真实值的变化趋势加罚,左移反而奖励对吧?不过原来的numpy写法没法直接用到Keras里,因为Keras损失函数接收的是TensorFlow张量,不能像numpy那样直接切片赋值,得用TF的张量操作来重构逻辑。
先拆解下你原来的numpy代码逻辑:
- 计算真实值序列的差分(
a[1:] - a[:-1]),第一个元素设为0得到product - 把
product乘以-10,用真实值的上升/下降趋势来调整惩罚系数 - 计算预测与真实值的差
delta,最终损失是|delta| + delta * product的平均值
下面是转换成TensorFlow张量操作的版本,完全适配Keras的损失函数要求:
import tensorflow as tf def asymmetric_mae(y_true, y_pred): # 计算真实值的差分:对应原代码的product[1:] = a[1:] - a[:-1] diff_true = tf.slice(y_true, [1], [-1]) - tf.slice(y_true, [0], [-1]) # 给差分序列补第一个0元素,对应原代码的product[0] = 0 product = tf.concat([tf.zeros(shape=(1,)), diff_true], axis=0) # 调整惩罚系数,对应原代码的product = -product*10 product = -product * 10 # 计算预测与真实值的差值 delta = y_pred - y_true # 计算非对称损失项 loss = tf.abs(delta) + delta * product # 取平均损失,替代原代码的sum(delta)/len(delta),适配张量批量处理 return tf.reduce_mean(loss)
关键注意点:
- 张量是不可变对象,不能像numpy数组那样直接切片赋值,所以用
tf.slice做切片、tf.concat补0来构建product序列 - 用
tf.reduce_mean计算平均损失更安全,尤其是处理批量时序数据(比如形状为(batch_size, timesteps)的输入)时,它会自动处理维度计算 - 如果你的输入是多特征时序数据(形状
(batch_size, timesteps, features)),可以根据需求调整tf.reduce_mean的axis参数,比如axis=[1,2]来对每个样本的所有时序步和特征取平均
内容的提问来源于stack exchange,提问作者Doctor
相关产品推荐
相关产品推荐

