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

如何为Neural ODEs(神经常微分方程)的损失函数添加L1惩罚项

你的实现逻辑是正确的,只需要正确关联你定义的待训练参数即可,具体修改方式如下:

1. 核心实现逻辑

L1正则的标准实现就是在原有损失基础上加入「超参数λ × 所有待正则参数的绝对值之和」,你的推导完全正确,不需要额外调整逻辑。

2. 损失函数修改示例

假设你要拟合的18个微分方程参数全部存储在变量p中(也就是你代码里Flux.params(p)对应的参数集合),直接按如下方式修改损失函数即可:

# 正则权重超参数,可根据实际效果调整,推荐从1e-4、1e-3、1e-2、0.1、1依次尝试
const LAMBDA = 0.01

function loss_func()
    pred = net()
    # 原有拟合损失
    fit_loss = sum(abs2, truth[1] .- pred[1,:]) +
               sum(abs2, truth[2] .- pred[2,:]) +
               sum(abs2, truth[3] .- pred[3,:])
    # L1惩罚项,仅针对微分方程的18个参数
    l1_penalty = LAMBDA * sum(abs, p)
    return fit_loss + l1_penalty
end

如果你需要给三个方程的参数设置不同的正则权重,可以拆分参数单独计算:

const LAMBDA1 = 0.01 # 第一个方程参数的正则权重
const LAMBDA2 = 0.01 # 第二个方程参数的正则权重
const LAMBDA3 = 0.01 # 第三个方程参数的正则权重

function loss_func()
    pred = net()
    fit_loss = sum(abs2, truth[1] .- pred[1,:]) +
               sum(abs2, truth[2] .- pred[2,:]) +
               sum(abs2, truth[3] .- pred[3,:])
    # p1、p2、p3分别对应三个微分方程的待训练参数
    l1_penalty = LAMBDA1 * sum(abs, p1) + LAMBDA2 * sum(abs, p2) + LAMBDA3 * sum(abs, p3)
    return fit_loss + l1_penalty
end

3. 训练代码调整

训练代码不需要做大幅修改,沿用你现有逻辑即可,确保Flux.params()传入的是你需要训练、需要加正则的参数集合:

callback_func = function ()
    loss_value = loss_func()
    println("Loss: " , loss_value)
end
# 仅把需要训练的18个微分方程参数传入,不要包含其他不需要正则的网络层参数
fparams = Flux.params(p)
Flux.train!(loss_func, fparams, data, optimizer, cb = callback_func)

注意事项

  • 正则权重不要设置过大,否则会过度压制参数导致拟合效果变差,建议从极小值开始逐步上调,平衡拟合精度和参数稀疏度
  • 如果你的网络中除了微分方程参数还有其他层参数,且不需要给这些参数加正则,不要把这些参数放到Flux.params()的传入列表中,避免误惩罚
  • 训练后可以直接打印p查看参数值,接近0的参数可以直接归零,得到稀疏的微分方程组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 21:15:04