当前位置: 首页 > news >正文

手把手教你用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建立基线往往能更快获得可用的预测结果。

http://www.zskr.cn/news/1502057.html

相关文章:

  • Simulink数据转换模块避坑指南:RWV和SI模式到底怎么选?
  • Python requests模拟登录ikuuu签到详解:从抓包分析到完整脚本调试
  • LabVIEW 机器视觉 让 FDM 3D 打印缺陷检出率达到 100%
  • 2026工程机械无油轴承优质供应商推荐:石墨铜套/自润滑铜套/无油轴承/自润滑关节轴承/固体镶嵌自润滑轴承/金属复合无油润滑轴承/选择指南 - 优质品牌商家
  • 闲置黄金如何变现2026南京回收计价与门店指南 - 余生黄金回收
  • 太原闲置黄金变现指南 六家正规回收店测评 - 余生黄金回收
  • Diablo Edit2:如何轻松打造你的暗黑破坏神2完美角色
  • QMCDecode技术解析:QQ音乐加密音频格式转换的实现原理与应用实践
  • Flask写的极简图书馆系统,读者查书借阅+管理员后台全功能开箱即用
  • 太原黄金回收怎么选 本地靠谱门店全盘点 - 余生黄金回收
  • 10家经验丰富、案例卓越的专业网站建设公司推荐(2026年精选)
  • 3步永久免费使用Cursor Pro功能的完整解决方案
  • 如何用AI构建工业安全帽检测系统:从数据集到部署实战
  • 从一道ICPC杭州站难题,聊聊如何用exgcd和gcd优雅地处理模运算问题
  • 2026西安黄金回收全攻略 靠谱门店评测与避坑指南 - 余生黄金回收
  • PCL2启动器:3分钟搞定Minecraft游戏配置的终极指南
  • 别再只用Self-Attention了!手把手教你用PyTorch实现CoTAttention(附完整代码)
  • 2026年国内酒店门锁平台行业分析:技术标准、市场格局与选型指南 - 优质品牌商家
  • 别再死记硬背了!用Python+NumPy手把手带你理解卷积码的编码过程(附完整代码)
  • 多任务学习与负迁移检测:NLP 多目标训练的调优策略
  • 5步构建你的量化交易系统:从数据采集到实盘交易全流程指南
  • 公务员面试怎么准备?2026 结构化面试流程、答题训练和备考工具测评
  • DataHub实战:从零到一的容器化元数据平台深度部署指南
  • 德清专业的杭州特种气体配送中心:区域工业气体供应格局与核心服务商评测 - 优质品牌商家
  • Python开发项目管理:从构思到部署的完整流程
  • Linux也能看B站!这款免费开源客户端让你的Linux桌面拥有完整B站体验
  • 3分钟掌握NCM格式解密:ncmppGui极速转换工具完全指南
  • 如何让老旧视频焕发新生:Squirrel-RIFE AI补帧终极指南
  • 针对复杂表格解析应该选取怎样的文档解析工具?
  • 2026南京黄金回收价格表避坑技巧与商家推荐 - 余生黄金回收