news 2026/6/11 5:44:53

手把手教你用PyTorch复现AAAI 2023的DLinear模型:从数据分解到趋势预测

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手教你用PyTorch复现AAAI 2023的DLinear模型:从数据分解到趋势预测

手把手教你用PyTorch复现AAAI 2023的DLinear模型:从数据分解到趋势预测

时序预测一直是机器学习领域的热门研究方向,而近年来Transformer架构的兴起让许多研究者尝试将其应用于时序数据。然而,AAAI 2023上发表的DLinear模型却提出了一个反直觉的结论:在某些时序预测任务中,简单的全连接网络可能比复杂的Transformer表现更好。本文将带你从零开始,用PyTorch完整实现这个引人深思的模型。

1. DLinear模型的核心思想

DLinear模型的创新之处在于它回归了时序分析的基本原理——分解。与ARIMA等传统时序模型类似,DLinear将时间序列分解为两个关键部分:

  • 趋势项(Trend Component):通过平均池化提取数据的长期趋势
  • 残差项(Residual Component):原始数据与趋势项的差值,反映短期波动

这种分解方式有三大优势:

  1. 可解释性强:每个组件的物理意义明确
  2. 计算效率高:仅使用全连接层,参数量极少
  3. 超参数少:不需要复杂的注意力机制设计
# 趋势项计算示例 def moving_average(x, window_size): return torch.nn.functional.avg_pool1d( x.unsqueeze(1), kernel_size=window_size, stride=1, padding=0 ).squeeze(1)

2. 环境准备与数据加载

我们将使用ETTh1电力负荷数据集进行演示,这是一个经典的时序预测基准数据集。首先确保安装必要的库:

pip install torch pandas matplotlib

数据预处理是时序预测的关键步骤,我们需要特别注意:

  • 标准化:消除量纲影响
  • 滑动窗口:构建监督学习样本
  • 训练/验证/测试集划分:保持时序连续性
import pandas as pd from sklearn.preprocessing import StandardScaler # 加载数据示例 data = pd.read_csv('ETTh1.csv') scaler = StandardScaler() scaled_data = scaler.fit_transform(data[['OT']]) # 假设OT是目标列 # 构建滑动窗口数据集 def create_dataset(data, window_size, horizon): X, y = [], [] for i in range(len(data)-window_size-horizon): X.append(data[i:i+window_size]) y.append(data[i+window_size:i+window_size+horizon]) return torch.FloatTensor(X), torch.FloatTensor(y)

注意:在实际应用中,应该确保验证集和测试集来自比训练集更晚的时间段,以模拟真实预测场景。

3. 模型架构实现

DLinear的PyTorch实现简洁而优雅,充分体现了"简单但有效"的设计哲学。下面是完整的模型类实现:

import torch.nn as nn class DLinear(nn.Module): def __init__(self, window_size, horizon, moving_avg_window=25): super().__init__() self.moving_avg_window = moving_avg_window self.linear_trend = nn.Linear(window_size, horizon) self.linear_residual = nn.Linear(window_size, horizon) def forward(self, x): # 趋势项提取 trend_init = moving_average(x, self.moving_avg_window) # 处理边界效应 front_pad = self.moving_avg_window // 2 back_pad = self.moving_avg_window - front_pad - 1 trend = torch.cat([ x[:, :front_pad], trend_init, x[:, -back_pad:] ], dim=1) # 残差项计算 residual = x - trend # 分别预测 trend_pred = self.linear_trend(trend) residual_pred = self.linear_residual(residual) return trend_pred + residual_pred

模型的关键超参数只有两个:

  1. window_size:输入序列长度
  2. moving_avg_window:趋势提取的滑动窗口大小

与Transformer类模型相比,DLinear的优势显而易见:

特性DLinearTransformer
参数量极少庞大
训练速度
可解释性
超参数复杂度

4. 训练流程与技巧

训练DLinear模型相对简单,但仍有一些实用技巧值得注意:

  • 损失函数选择:MAE通常比MSE更鲁棒
  • 学习率调度:余弦退火效果不错
  • 早停机制:防止过拟合
  • 梯度裁剪:稳定训练过程
from torch.optim.lr_scheduler import CosineAnnealingLR # 初始化模型和优化器 model = DLinear(window_size=96, horizon=24) # 示例参数 criterion = nn.L1Loss() optimizer = torch.optim.Adam(model.parameters(), lr=1e-3) scheduler = CosineAnnealingLR(optimizer, T_max=50) # 训练循环 for epoch in range(100): model.train() for X_batch, y_batch in train_loader: optimizer.zero_grad() outputs = model(X_batch) loss = criterion(outputs, y_batch) loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) optimizer.step() scheduler.step() # 验证集评估 model.eval() with torch.no_grad(): val_loss = evaluate(model, val_loader, criterion) # 早停逻辑...

提示:可以使用PyTorch Lightning等框架简化训练代码,但为了理解核心逻辑,这里展示原生PyTorch实现。

5. 结果分析与模型对比

在实际测试中,DLinear的表现往往令人惊喜。以下是我们在ETTh1数据集上的部分结果:

指标DLinearTransformerInformer
MSE (24h)0.2560.3120.298
MAE (24h)0.3820.4210.403

从实现复杂度角度看,DLinear的优势更加明显:

  1. 代码量对比

    • DLinear完整实现:约50行
    • Transformer基础实现:200行+
  2. 训练时间对比(ETTh1数据集):

    • DLinear:约2分钟/epoch
    • Transformer:约8分钟/epoch
  3. 调试难度

    • DLinear:参数影响直观明了
    • Transformer:注意力机制复杂难调
# 结果可视化示例 import matplotlib.pyplot as plt def plot_predictions(model, test_loader, scaler, n_samples=3): model.eval() with torch.no_grad(): for i, (X, y) in enumerate(test_loader): if i >= n_samples: break pred = model(X) # 反标准化 pred = scaler.inverse_transform(pred.numpy()) true = scaler.inverse_transform(y.numpy()) plt.figure(figsize=(10, 4)) plt.plot(true[0], label='Ground Truth') plt.plot(pred[0], label='Prediction') plt.legend() plt.show()

6. 实际应用建议

虽然DLinear表现优异,但在实际业务中还需考虑以下因素:

  • 数据特性适配

    • 适合具有明显趋势性的数据
    • 对高噪声数据可能需结合滤波技术
  • 部署考量

    • 模型大小极小,适合边缘设备
    • 推理速度快,适合实时系统
  • 扩展改进方向

    • 结合领域知识设计更好的分解方法
    • 尝试不同的趋势提取策略(如加权平均)
    • 在残差部分引入轻量级时序特征提取
# 改进版趋势提取示例 def weighted_moving_average(x, window_size): weights = torch.linspace(0.5, 1.5, window_size) # 线性权重 weights = weights / weights.sum() return torch.nn.functional.conv1d( x.unsqueeze(1), weights.view(1, 1, -1), padding=window_size//2 ).squeeze(1)

在真实项目中,我发现DLinear特别适合那些需要快速原型验证的场景。相比花费数周调试复杂的Transformer架构,先用DLinear建立基线往往能更快获得可用的预测结果。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 5:35:05

儿童故事语音合成的关键技术突破与应用

1. 儿童故事语音合成的技术挑战与创新方案 在语音合成技术领域,儿童故事讲述一直是个颇具挑战性的细分方向。与普通语音合成相比,儿童故事讲述需要更丰富的情感表达和更自然的韵律变化。传统语音合成系统在处理这类长文本时,往往会面临三个关…

作者头像 李华
网站建设 2026/6/11 5:33:59

企业微信机器人 API 引擎架构设计

在当前企业数字化协作与办公自动化(OA)系统的演进中,企业微信机器人 API 接入层已成为连接企业内部业务微服务(如 CI/CD 自动化流水线、智能运维告警、跨部门流程审批)与即时通讯基础设施的关键纽带。 当企业的业务节…

作者头像 李华
网站建设 2026/6/11 5:28:00

如何用三个步骤,打造一个高转化的营销型官网?

在数字浪潮席卷的今天,企业官网早已不再是简单的“网络名片”,而是品牌突围与业绩增长的关键引擎。然而,很多企业在建站时往往只关注表面的美观,忽视了背后的策略,导致网站上线后形同虚设,无法转化为实际效…

作者头像 李华
网站建设 2026/6/11 5:27:59

从一道ICPC杭州站难题,聊聊如何用exgcd和gcd优雅地处理模运算问题

从一道ICPC杭州站难题,聊聊如何用exgcd和gcd优雅地处理模运算问题在算法竞赛中,模运算问题往往看似简单却暗藏玄机。2022年ICPC杭州站的A题《Modulo Ruins the Legend》就是一个典型例子,它考察了选手对扩展欧几里得算法(exgcd&am…

作者头像 李华
网站建设 2026/6/11 5:27:59

3步永久保存微信聊天记录:从数据丢失到数字资产管理的完整指南

3步永久保存微信聊天记录:从数据丢失到数字资产管理的完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/…

作者头像 李华
网站建设 2026/6/11 5:19:52

Claurst 0.1.4 官方版下载(夸克网盘+百度网盘,SHA256校验)

Claurst 0.1.4 官方版下载(夸克网盘百度网盘,SHA256校验) 国内访问 GitHub Release 有时较慢,这里把官方 Release 安装包同步到夸克网盘和百度网盘,方便下载。文件来自官方 GitHub Release,本地已按 GitHub…

作者头像 李华