动手学深度学习之序列模型

该博客介绍了序列模型在时间序列预测中的应用。通过使用马尔科夫假设和潜变量模型来处理历史数据,建立自回归模型进行预测。文章展示了如何用PyTorch实现一个简单的多层感知机进行一阶和多步预测,并通过正弦函数生成的模拟数据进行训练和验证。最终,讨论了不同步数的预测效果。
摘要由CSDN通过智能技术生成

序列模型

序列数据

在这里插入图片描述
在这里插入图片描述

统计工具

  • 在时间t观察到 x t x_t xt,那么得到T个不独立的随机变量(x_1,…,x_T)~p(x)
  • 使用条件概率展开p(a,b)=p(a)p(b|a)=p(b)p(a|b)
    在这里插入图片描述

序列模型

  • 对前面 x − x t − 1 x-x_{t-1} xxt1进行建模表示为一个函数,可以认为是一个机器学习模型。现在是给定前面的让我们去预测现在的,这也是一个自回归模型。
    在这里插入图片描述

方案A-马尔科夫假设

  • 给定定长的 τ \tau τ,然后预测
    在这里插入图片描述

方案B-潜变量模型

  • 引入一个潜变量来记录过去的信息,这样这里就是一个函数。这里的潜变量是前一个状态的潜变量和前一个状态的x
    在这里插入图片描述

总结

在这里插入图片描述

序列模型代码实现

使用正弦函数和一些科加性噪声来生成序列数据,时间步为1,2,3,…,1000

%matplotlib inline
import torch
from torch import nn
from d2l import torch as d2l

T = 1000  # 给定时间
time = torch.arange(1, T + 1, dtype=torch.float32)  # 生成1000个时间的值
x = torch.sin(0.01 * time) + torch.normal(0, 0.2, (T,)) # 正弦函数
d2l.plot(time, [x], 'time', 'x', xlim=[1, 1000], figsize=(6, 3))

在这里插入图片描述

将数据映射为数据对 y t = x t y_t=x_t yt=xt X t = [ x t − τ , . . . , x t − 1 ] X_{t}=[x_{t-\tau},...,x_{t-1}] Xt=[xtτ,...,xt1]

tau = 4  
features = torch.zeros((T - tau, tau))  # 这个就是样本数
for i in range(tau):
    features[:, i] = x[i:T - tau + i]
labels = x[tau:].reshape((-1, 1))  # label就是从定长的开始一直到最后

batch_size, n_train = 16, 600
train_iter = d2l.load_array((features[:n_train], labels[:n_train]),
                            batch_size, is_train=True)

使用一个相当简单的结构:只是一个拥有两个全连接层的多层感知机

def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.xavier_uniform_(m.weight)

def get_net():
    net = nn.Sequential(nn.Linear(4, 10), nn.ReLU(), nn.Linear(10, 1))
    net.apply(init_weights)
    return net

loss = nn.MSELoss()  # MSE损失函数

训练模型

def train(net, train_iter, loss, epochs, lr):
    trainer = torch.optim.Adam(net.parameters(), lr)
    for epoch in range(epochs):
        for X, y in train_iter:
            trainer.zero_grad()
            l = loss(net(X), y)
            l.backward()
            trainer.step()
        print(f'epoch {epoch + 1}, '
              f'loss: {d2l.evaluate_loss(net, train_iter, loss):f}')

net = get_net()
train(net, train_iter, loss, 10, 0.01)
epoch 1, loss: 0.050490
epoch 2, loss: 0.046954
epoch 3, loss: 0.048392
epoch 4, loss: 0.048372
epoch 5, loss: 0.047389
epoch 6, loss: 0.050417
epoch 7, loss: 0.049999
epoch 8, loss: 0.045745
epoch 9, loss: 0.050479
epoch 10, loss: 0.048941

预测下一个时间步

onestep_preds = net(features)
d2l.plot(
    [time, time[tau:]],
    [x.detach().numpy(), onestep_preds.detach().numpy()], 'time', 'x',
    legend=['data', '1-step preds'], xlim=[1, 1000], figsize=(6, 3))

在这里插入图片描述

进行多步预测

multistep_preds = torch.zeros(T)
multistep_preds[:n_train + tau] = x[:n_train + tau]
for i in range(n_train + tau, T):
    multistep_preds[i] = net(multistep_preds[i - tau:i].reshape((1, -1)))

d2l.plot([time, time[tau:], time[n_train + tau:]], [
    x.detach().numpy(),
    onestep_preds.detach().numpy(),
    multistep_preds[n_train + tau:].detach().numpy()], 'time', 'x',
         legend=['data', '1-step preds',
                 'multistep preds'], xlim=[1, 1000], figsize=(6, 3))

在这里插入图片描述

更仔细地看一下𝑘步预测

max_steps = 64

features = torch.zeros((T - tau - max_steps + 1, tau + max_steps))
for i in range(tau):
    features[:, i] = x[i:i + T - tau - max_steps + 1]

for i in range(tau, tau + max_steps):
    features[:, i] = net(features[:, i - tau:i]).reshape(-1)

steps = (1, 4, 16, 64)
d2l.plot([time[tau + i - 1:T - max_steps + i] for i in steps],
         [features[:, (tau + i - 1)].detach().numpy() for i in steps], 'time',
         'x', legend=[f'{i}-step preds'
                      for i in steps], xlim=[5, 1000], figsize=(6, 3))

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值