N-Beats:一种用于时间序列预测的纯前馈神经网络模型

介绍

N-Beats(Neural Basis Expansion Analysis for Interpretable Time Series Forecasting)是一种基于纯前馈神经网络的时间序列预测模型,由Boris Oreshkin等人在2019年提出。与传统的递归神经网络(如LSTM和GRU)不同,N-Beats通过堆叠多个简单的前馈块来生成预测,具有高度的可解释性和灵活性。

工作原理

模型架构

N-Beats的核心思想是使用一系列简单的前馈块(称为"基础块")来逐步生成预测值。每个基础块包含一个全连接层(或多个全连接层),用于学习时间序列的模式,并输出两个部分:

  1. 后向分量(Backcast):用于拟合输入的历史数据。
  2. 前向分量(Forecast):用于生成未来的预测值。

基础块可以分为两种类型:

  • 通用块(Generic Block):直接学习时间序列的复杂模式。
  • 趋势块 (Trend Block)和季节性块(Seasonality Block):分别用于捕捉时间序列的趋势成分和季节性成分。

训练过程

  1. 数据准备

    • 输入数据包括历史观测值。
    • 每个时间序列被分成训练集和测试集。
  2. 模型训练

    • 对于每个基础块,输入为历史观测值的一部分(即"窗口")。
    • 基础块生成后向分量和前向分量。
    • 后向分量用于拟合输入的历史数据,前向分量用于生成未来预测值。
    • 损失函数通常采用均方误差(MSE),以最小化预测值与真实值之间的差异。
  3. 堆叠基础块

    • 多个基础块按顺序堆叠,每个块的后向分量用于校正前一个块的残差。
    • 最终的预测值是所有基础块前向分量的累加结果。

优势

  • 可解释性:通过堆叠不同类型的基础块(如趋势块和季节性块),N-Beats能够明确地分解时间序列的不同成分,提高模型的可解释性。
  • 灵活性:N-Beats可以处理不同长度和频率的时间序列数据,并且支持多种类型的预测任务。
  • 高效性:由于不依赖递归结构,N-Beats在训练和推理过程中具有较高的计算效率。
  • 鲁棒性:N-Beats在处理噪声和异常值方面表现出色,能够在一定程度上抵抗这些因素的影响。

实现步骤

数据准备

  1. 收集数据:获取时间序列数据及其相关的协变量。
  2. 预处理
    • 处理缺失值。
    • 标准化或归一化数据。
    • 提取时间特征(如月份、星期几等)。

模型构建

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

class GenericBlock(nn.Module):
    def __init__(self, input_size, theta_size, hidden_size, num_layers):
        super(GenericBlock, self).__init__()
        layers = [nn.Linear(input_size, hidden_size), nn.ReLU()]
        for _ in range(num_layers - 1):
            layers.append(nn.Linear(hidden_size, hidden_size))
            layers.append(nn.ReLU())
        layers.append(nn.Linear(hidden_size, theta_size))
        self.layers = nn.Sequential(*layers)

    def forward(self, x):
        return self.layers(x)

class NBeatsBlock(nn.Module):
    def __init__(self, input_size, theta_size, hidden_size, num_layers, basis_function):
        super(NBeatsBlock, self).__init__()
        self.input_size = input_size
        self.theta_size = theta_size
        self.basis_function = basis_function
        self.fc = GenericBlock(input_size, theta_size, hidden_size, num_layers)

    def forward(self, x):
        backcast, forecast = self.basis_function(self.fc(x))
        return backcast, forecast

class NBeatsNet(nn.Module):
    def __init__(self, input_size, output_size, stack_types, nb_blocks_per_stack, thetas_dim, hidden_layer_units, share_weights_in_stack=False):
        super(NBeatsNet, self).__init__()
        self.blocks = []
        for stack_id in range(len(stack_types)):
            for block_id in range(nb_blocks_per_stack[stack_id]):
                if share_weights_in_stack and block_id != 0:
                    self.blocks[-1].requires_grad_(True)
                else:
                    self.blocks.append(NBeatsBlock(input_size, thetas_dim[stack_id], hidden_layer_units[stack_id], 4, stack_types[stack_id]))
        self.blocks = nn.ModuleList(self.blocks)

    def forward(self, x):
        residuals = x
        forecast = 0
        for i, block in enumerate(self.blocks):
            backcast, block_forecast = block(residuals)
            residuals = (residuals - backcast)
            forecast = forecast + block_forecast
        return forecast

# 参数设置
input_size = 10  # 输入窗口大小
output_size = 1  # 输出窗口大小
stack_types = ['generic', 'trend', 'seasonality']
nb_blocks_per_stack = [2, 2, 2]
thetas_dim = [5, 3, 7]
hidden_layer_units = [64, 64, 64]
batch_size = 32
epochs = 100

# 初始化模型
model = NBeatsNet(input_size, output_size, stack_types, nb_blocks_per_stack, thetas_dim, hidden_layer_units)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 数据加载
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

# 训练模型
for epoch in range(epochs):
    for i, (inputs, targets) in enumerate(train_loader):
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, targets)
        loss.backward()
        optimizer.step()
    print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')

模型评估

  1. 生成预测

    • 使用训练好的模型对测试集进行预测。
    • 生成未来时间点的预测值。
  2. 评估指标

    • 计算均方误差(MSE)、平均绝对误差(MAE)等点估计指标。
    • 评估预测的准确性。

结果分析

  • 可视化:绘制预测值与真实值的对比图。
  • 成分分解:展示各个基础块的后向分量和前向分量,分析其对最终预测结果的贡献。

总结

N-Beats是一种强大的时间序列预测模型,通过堆叠简单的前馈块来生成预测值,具有高度的可解释性和灵活性。

相关推荐
Chatopera 研发团队6 分钟前
使用 AlexNet 实现图片分类 | PyTorch 深度学习实战
pytorch·深度学习·分类·cnn·cv·alexnet
EterNity_TiMe_15 分钟前
【人工智能】deepseek R1模型在蓝耘智算平台的搭建与机器学习的探索
人工智能·python·机器学习·deepseek
灵魂画师向阳17 分钟前
白嫖RTX 4090?Stable Diffusion:如何给线稿人物快速上色?
java·大数据·人工智能·ai作画·stable diffusion
新加坡内哥谈技术1 小时前
ChunkKV:优化 KV 缓存压缩,让 LLM 长文本推理更高效
人工智能·科技·深度学习·语言模型·机器人
Narnat1 小时前
opencv打开摄像头出现读取帧错误问题
人工智能·opencv·计算机视觉
珠江上上上1 小时前
支持向量机原理
人工智能·深度学习·算法·机器学习·支持向量机·数据挖掘
pchmi1 小时前
C# OpenCV机器视觉:对位贴合
人工智能·opencv·c#·机器视觉·opencvsharp
土拨鼠不是老鼠1 小时前
树莓派上 基于Opencv 实现人脸检测与人脸识别
人工智能·opencv·计算机视觉
郑万通1 小时前
10.推荐系统的用户研究
深度学习·推荐系统
霍格沃兹测试开发学社测试人社区2 小时前
人工智能丨Deepseek vs 传统测试工具:谁将主导软件质量保障?
软件测试·人工智能·测试开发·测试工具·deepseek