8.1 序列模型
8.1.1 统计工具
处理序列数据需要统计工具和新的深度神经网络架构。
用过去的一些时间序列来预测未来的某一时刻
8.1.1.1 自回归模型·
两种策略
1.直接利用近一段(根据需要自己确定)历史时间序列的数据
2.对过去的时间序列的数据做总结
Q:如何生成训练数据?
整个序列的估计值都将通过以下的方式获得:
这预测的是啥?
8.1.1.2 马尔可夫模型
马尔可夫模型(Markov Model)是一种用于描述随机过程的数学模型。它基于马尔可夫性质,即在给定当前状态的情况下,未来的状态只依赖于当前状态,而与过去的状态无关。
马尔可夫模型包括两个基本要素:状态和转移概率。
状态(State):马尔可夫模型中的状态是指系统或过程可能处于的不同情况或状态。状态可以是离散的,也可以是连续的。例如,在天气预测中,状态可以是晴天、阴天或雨天;在股票市场分析中,状态可以是涨、跌或持平。
转移概率(Transition Probability):转移概率定义了从一个状态到另一个状态的概率。它表示在当前状态下,系统转移到下一个状态的可能性大小。转移概率可以通过观察历史数据进行估计,或者根据领域专家的知识进行设定。
基于这两个要素,马尔可夫模型可以分为两种常见形式:马尔可夫链和隐马尔可夫模型。
马尔可夫链(Markov Chain):马尔可夫链是一种离散的马尔可夫模型,它的状态空间是有限的。马尔可夫链可以用状态转移矩阵表示,该矩阵描述了每个状态转移到其他状态的概率。通过马尔可夫链,我们可以预测系统在未来各个时间步的状态。
隐马尔可夫模型(Hidden Markov Model,HMM):隐马尔可夫模型是一种常用的统计模型,用于建模具有隐藏状态的序列数据。在隐马尔可夫模型中,状态是不可观测的,但通过观测到的数据可以推断出隐藏状态。HMM由两组参数组成:状态转移概率和观测概率。状态转移概率描述了隐藏状态之间的转移规律,观测概率描述了每个隐藏状态生成特定观测值的概率。
8.1.1.3 因果关系
8.1.2 训练
#加载必要的库
%matplotlib inline
import torch
from torch import nn
from d2l import torch as d2l
#定义总共产生1000个点
T = 1000
#创建一个包含从1到T的数字序列,数据类型为torch.float32
time = torch.arange(1, T + 1, dtype=torch.float32)
#使用正弦函数和正态分布噪声生成x值
x = torch.sin(0.01 * time) + torch.normal(0, 0.2, (T,))
#使用d2l库中的plot函数绘制time和x的图像,设置横轴和纵轴的标签,以及x轴的取值范围和图像大小
d2l.plot(time, [x], 'time', 'x', xlim=[1, 1000], figsize=(6, 3))
#注释解释如下:
#%matplotlib inline:该语句用于在Jupyter Notebook中显示Matplotlib图形。
#import语句:导入需要使用的库,包括torch、nn和d2l(d2l是一个自定义的深度学习库)。
#T变量:定义总共产生1000个点。
#time变量:创建一个包含从1到T的数字序列,数据类型为torch.float32。
#x变量:使用正弦函数和正态分布噪声生成x值。
#d2l.plot函数:使用d2l库中的plot函数绘制time和x的图像,设置横轴和纵轴的标签,以及x轴的取值范围和图像大小。其中,第一个参数是x轴的数据,第二个参数是y轴的数据,第三个参数是x轴的标签,第四个参数是y轴的标签,xlim参数设置x轴的取值范围,figsize参数设置图像的大小。
定义参数
tau = 4 # 设置tau的值为4
创建特征矩阵
features = torch.zeros((T - tau, tau)) # 创建一个形状为(T-tau, tau)的全零张量作为特征矩阵
for i in range(tau):
features[:, i] = x[i: T - tau + i] # 将x中的元素赋值给特征矩阵的每一列,每一列的起始位置逐步后移
创建标签矩阵
labels = x[tau:].reshape((-1, 1)) # 将x中从第tau个元素开始的部分作为标签,调整形状为(-1, 1)
设置批量大小和训练样本数
batch_size, n_train = 16, 600 # 设置批量大小为16,训练样本数为600
加载数据集
train_iter = d2l.load_array((features[:n_train], labels[:n_train]),
batch_size, is_train=True) # 使用d2l库中的load_array函数加载数据集,将前n_train个样本作为训练集,并设置批量大小为batch_size
注释解释如下:
tau变量:定义了tau的值为4。
features变量:创建一个形状为(T-tau, tau)的全零张量作为特征矩阵。通过一个循环,将x中的元素赋值给特征矩阵的每一列,每一列的起始位置逐步后移。
labels变量:将x中从第tau个元素开始的部分作为标签,调整形状为(-1, 1)。
batch_size和n_train变量:设置批量大小为16,训练样本数为600。
train_iter变量:使用d2l库中的load_array函数加载数据集。将特征矩阵的前n_train个样本和对应的标签作为训练集,并设置批量大小为batch_size。is_train参数设置为True表示该数据集用于训练。
在这里,我们使用一个相当简单的架构训练模型: 一个拥有两个全连接层的多层感知机,ReLU激活函数和平方损失。
初始化网络权重的函数
def init_weights(m):
# 如果该模块是nn.Linear,则使用xavier_uniform_初始化权重
if type(m) == nn.Linear:
nn.init.xavier_uniform_(m.weight)
一个简单的多层感知机
def get_net():
# 定义一个Sequential模型,包含两个全连接层和一个ReLU激活函数层
net = nn.Sequential(nn.Linear(4, 10),
nn.ReLU(),
nn.Linear(10, 1))
# 对模型中所有的nn.Linear模块进行权重初始化
net.apply(init_weights)
# 返回初始化后的模型
return net
平方损失。注意:MSELoss计算平方误差时不带系数1/2
loss = nn.MSELoss(reduction='none')
注释解释如下:
init_weights函数:该函数用于初始化网络权重,输入为一个模块m,如果该模块是nn.Linear,则使用xavier_uniform_初始化其权重。
get_net函数:该函数返回一个简单的多层感知机模型,包含两个全连接层和一个ReLU激活函数层。在创建完模型后,对模型中所有的nn.Linear模块进行权重初始化。
loss变量:该变量定义了平方损失函数,使用MSELoss类实现,reduction参数设置为'none'表示不进行降维操作。注意:MSELoss计算平方误差时不带系数1/2。
#训练
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.sum().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, 5, 0.01)
8.1.3 预测
#单步预测
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))
k步预测效果不理想的原因是每一步都积累了错误