0

大约一个月前,我问了一个关于在训练神经微分方程时更好地收敛的策略的问题。从那以后,我已经使用给我的建议使该示例起作用,但是当我将相同的建议应用于更困难的模型时,我又被卡住了。我所有的代码都在 Julia 中,主要使用 DiffEqFlux 库。为了使这篇文章尽可能简短,我不会分享我尝试过的所有代码,但如果有人想访问它来解决问题,我可以提供。

我想要做什么

我试图学习的数据来自 SIRx 模型:

function SIRx!(du, u, p, t)
    β, μ, γ, a, b = Float32.([280, 1/50, 365/22, 100, 0.05])
    S, I, x = u
    du[1] = μ*(1-x) - β*S*I - μ*S
    du[2] = β*S*I - (μ+γ)*I
    du[3] = a*I - b*x
    nothing
end;

我使用的初始条件是u0 = Float32.([0.062047128, 1.3126149f-7, 0.9486445]);. 我生成了从 t=0 到 25 的数据,每 0.02 采样一次(在训练中,我只使用每 20 个点左右来提高速度,使用更多并不能提高结果)。数据如下所示:训练数据

我正在训练的 UDE 是

function SIRx_ude!(du, u, p, t)
    μ, γ = Float32.([1/50, 365/22])
    S,I,x = u
    du[1] = μ*(1-x) - μ*S + ann_dS(u, @view p[1:lenS])[1]
    du[2] = -(μ+γ)*I + ann_dI(u, @view p[lenS+1:lenS+lenI])[1]
    du[3] = ann_dx(u, @view p[lenI+1:end])[1]
    nothing
end;

每个神经网络 ( ann_dS, ann_dI, ann_dx) 都使用 定义FastChain(FastDense(3, 20, tanh), FastDense(20, 1))。我尝试使用具有 3 个输入和 3 个输出的单个神经网络,但它速度较慢并且性能也没有更好。我还尝试首先对网络的输入进行规范化,但除了减慢速度之外,它并没有显着的区别。

我试过的

  • 单拍 网络正好适合一条穿过数据中间的线。即使我在损失函数中对早期数据点进行更多加权,也会发生这种情况。单次训练
  • 多重射击 我得到的最好结果是多重射击。如此处所见,它不仅仅是拟合一条直线,而且也不是完全拟合数据Multiple Shooting Result。我尝试了从 0.1 到 100 的连续性术语和从 3 到 30 的组大小,但没有显着差异。
  • 各种其他策略 我也尝试过迭代地增加适合度、搭配搭配的 2 阶段训练和小批量,如下所述:https : //diffeqflux.sciml.ai/dev/examples/local_minima,https://diffeqflux .sciml.ai/dev/examples/collocation/ , https://diffeqflux.sciml.ai/dev/examples/minibatch/. 迭代地增加拟合在前几次迭代中效果很好,但随着长度的增加,它又回到拟合直线。2-stage 搭配训练在第 1 阶段效果非常好,但在第 2 阶段实际上并没有提高性能(我在第 2 阶段尝试过单拍和多拍)。最后,mini-batching 的效果与单次拍摄一样好(也就是说不是很好),但速度要快得多。

我的问题

总之,我不知道该尝试什么。有很多策略,每个策略都有很多可以调整的参数。我需要一种更准确地诊断问题的方法,以便更好地决定如何进行。如果有人有此类问题的经验,我会很感激我能得到的任何建议或指导。

4

1 回答 1

0

这不是一个很好的 SO 问题,因为它更具探索性。您是否降低了 ODE 容差?这将改善您的梯度计算,这可能会有所帮助。你用的是什么激活函数?我会使用类似的东西,softplus而不是tanh这样你就没有饱和行为。您是否缩放了特征值并考虑了僵硬的神经 ODE 论文中探讨的问题?更大的神经网络?不同的学习率?亚当?等等。

这更适合像JuliaLang Discourse 这样的讨论论坛。我们可以继续在那里,因为如果没有一些来回,走过这将不会有成果。

于 2021-06-18T10:03:15.650 回答