由概率论中的贝叶斯公式可知
得到全概率公式
也就是每一个xt时刻的值,是与它之前所有时刻的值都有关系,因此如果可以通过前面的值推算出分布或者函数(不一定完全按照这个分布),那么就可以有准确的预测。
自回归模型的两种策略
1、(马尔科夫假设)假设在现实情况下相当长的序列 xt−1,…,x1可能是不必要的, 因此我们只需要满足某个长度为ττ的时间跨度, 即使用观测序列xt−1,…,xt−τ。 当下获得的最直接的好处就是参数的数量总是不变的, 至少在t>τ时如此,这就使我们能够训练一个上面提及的深度网络。 这种模型被称为自回归模型(autoregressive models)。例如用一段固定的数据去训练mlp模型
※※※2、是保留一些对过去观测的总结ht, 并且同时更新预测x^t和总结ht。 这就产生了基于x^t=P(xt∣ht) 估计xt, 以及公式ht=g(ht−1,xt−1)更新的模型。 由于ht从未被观测到,这类模型也被称为 隐变量自回归模型(latent autoregressive models)。RNN就是一个潜变量模型。
相当于我们每次要找到两个模型, 第一个是从(h,x)→h' ,第二个是从(h‘,x)→x' ,注意h'是新的潜变量的状态。
首先是网络的构建
# 初始化网络权重的函数 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 # 平方损失。注意:MSELoss计算平方误差时不带系数1/2 loss = nn.MSELoss(reduction='none')
在mlp序列预测中,如果每次输入固定量的实际数据,预测下一个数据(1-step preds),可以得到不错的结果(模型不复杂)
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)) batch_size, n_train = 16, 600 # 只有前n_train个样本用于训练 train_iter = d2l.load_array((features[:n_train], labels[:n_train]), batch_size, is_train=True) #训练过程 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()
但是如果把预测出的这个新数据,继续当作训练数据,那就会导致误差累积,从而错的很离谱(multistep preds)。(mlp的限制)
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)))
这里tau是固定的,这个数值后续会有更多的模型进行优化,选取与需要预测的值更为相关的数据进行预测。