如何在 Darts 中实现具有静态协变量的 ODE 的自定义损失函数?

问题描述 投票:0回答:1

我正在使用 darts 来预测 Lorenz 系统,这是一个来自 3 个常微分方程的 3D 多元混沌时间序列。我创建了一个 TFT 模型,该模型经过合成数据的训练 - 使用的每个数据集都被放入一个系列中:

train_series = TimeSeries.from_group_dataframe(training_df, 
                                group_cols = 'simNum',
                                time_col = 'time_idx',
                                value_cols = ['x','y','z'],
                                static_cols = ['sigma','rho','beta'])

其中 sigma、rho 和 beta 是恒定的、静态的协变量,对于每个组都是有界和随机的(这个特定的尝试有 200 次模拟)。输入数据帧的所有列都是浮点数(使用

Scaler
进行缩放,
time_idx
除外,它是为每个组重置的时间整数。

我的目标是将洛伦兹系统的 3 个 ODE 合并到损失函数中作为残差最小化,所以我目前有:

import torch
import torch.nn as nn

def grad(outputs, inputs):
    """Computes the partial derivative of 
    an output with respect to an input."""
    return torch.autograd.grad(
        outputs, 
        inputs, 
        grad_outputs=torch.ones_like(outputs), 
        create_graph=True
    )
def lorenz(x, y, z, s, r, b):
    # Function modeling lorenz attractor system
    x_dot = s * (y - x)
    y_dot = x * (r - z) - y
    z_dot = (x * y) - (b * z)
    return x_dot, y_dot, z_dot
def odeLoss(model):
    #defining collocation points
    ts = torch.linspace(0, timeMax, TOTAL_SAMPLES).view(-1, 1).requires_grad_(True)
    # Run collocation points through network
    out = model.predict(ts, TOTAL_SAMPLES)
    # Get gradient
    dT = grad(out, ts)
    # Compute ODE
    odeOut = 0
    # Return MSE of ODE
    return torch.mean(odeOut**2)

除了数据丢失项之外,我还打算使用

loss_fn = MSELoss() + odeLoss()
将其添加到模型参数中。

odeLoss 函数是我需要帮助的地方:我不确定如何在搭配点上生成模型预测或将 ODE 合并到具有未知静态协变量的函数中。我是否只需生成 3 个随机值来定义搭配点上的 sigma、rho 和 beta,并将它们集成到

model.predict
odeOut
计算中?我陷入了僵局,不知道如何继续。我相信 darts 库使用 pytorch 和 pytorch lighting,所以我可能会尝试定义一个继承训练器的子类。

odeLoss 函数是我需要帮助的地方:我不确定如何在搭配点上生成模型预测或将 ODE 合并到具有未知静态协变量的函数中。我是否只需生成 3 个随机值来定义搭配点上的 sigma、rho 和 beta,并将它们集成到 model.predict 和 odeOut 计算中?

python machine-learning time-series loss-function u8darts
1个回答
0
投票

在这里,只需使用函数的残差作为损失:

    class LorenzLoss(nn.Module):
      def __init__(self, sigma, rho, beta, dt):
         super(LorenzLoss, self).__init__()
         self.sigma = sigma
         self.rho = rho
         self.beta = beta
         self.dt = dt

     def forward(self, y_pred, y_true):
    # Extracting the predicted values for x, y, and z
        x, y, z = y_pred[:, 0], y_pred[:, 1], y_pred[:, 2]
    
    # Calculating the residuals for the Lorenz system
        dx = self.sigma * (y - x) - (x - y_true[:, 0]) / self.dt
        dy = x * (self.rho - z) - y - (y - y_true[:, 1]) / self.dt
        dz = x * y - self.beta * z - (z - y_true[:, 2]) / self.dt
    
        # Summing up the residuals to compute the loss
        loss = torch.mean(dx**2 + dy**2 + dz**2)

        return loss
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.