You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keras Sequential模型适配自定义精度规则的损失函数选型问题

是否需要自定义损失函数

首先你要优先实现自定义评价指标,损失函数可以先试原生MAE能不能满足需求,达不到预期再自定义损失。你初步写的损失函数不能直接用,因为它是不可导的阶跃函数,梯度为0,无法用于梯度下降训练。


第一步:先实现自定义评价指标

你当前代码里用的accuracy是分类任务的准确率,完全不适用于你的回归场景,先把你定义的精度规则写成Keras可调用的指标函数,训练时就能实时查看你关心的精度数值:

import tensorflow as tf

def custom_accuracy(y_true, y_pred):
    # 计算每个特征的差值绝对值
    diff = tf.abs(y_true - y_pred)
    # 单样本所有特征差值都<=10则标记为正确,否则错误
    sample_correct = tf.cast(tf.reduce_all(diff <= 10, axis=-1), tf.float32)
    # 返回全局平均准确率
    return tf.reduce_mean(sample_correct)

修改模型编译的metrics参数即可:

self.model.compile(loss='mae', optimizer='adam', metrics=['mse', 'mae', custom_accuracy])

改完先跑一轮训练,看原生MAE损失下,你的自定义精度能不能达到要求。MAE本身就是惩罚预测值和真实值的差值,天然会推动所有特征的差值尽可能缩小,大部分场景下够用。


第二步:如需自定义损失,用可导的平滑版本

如果MAE训练后自定义精度达不到要求,再换自定义损失。核心逻辑是给差值超过10的样本加额外惩罚,同时保证损失可导:

def custom_loss(y_true, y_pred):
    diff = tf.abs(y_true - y_pred)
    # 基础损失:所有特征的MAE
    base_loss = tf.reduce_mean(diff, axis=-1)
    # 平滑惩罚项:特征差值越超过10,惩罚越高,用softplus替代阶跃保证可导
    penalty = tf.reduce_mean(tf.nn.softplus(diff - 10) * 10, axis=-1)
    # 总损失 = 基础损失 + 惩罚项,惩罚系数10可根据效果调整
    return base_loss + penalty

修改编译参数的loss字段即可:

self.model.compile(loss=custom_loss, optimizer='adam', metrics=['mse', 'mae', custom_accuracy])

后续优化建议

  • 开启你注释掉的早停策略,把监控指标换成val_custom_accuracy,模式设为max,自动保存验证集上自定义精度最高的权重:
    self.earlystopping = callbacks.EarlyStopping(monitor="val_custom_accuracy",
                                                 mode="max", patience=10,
                                                 restore_best_weights=True)
    
  • 训练时如果出现震荡,可以适当调小Adam的学习率,比如设为1e-4。
  • 可以适当调整损失函数里的惩罚系数,系数越大,模型越优先保证所有特征的差值不超过10。

内容的提问来源于stack exchange,提问作者Petar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 04:36:08