Pytorch贝叶斯深度学习库BLiTZ实现LSTM预测时序数据(二)

简介: Pytorch贝叶斯深度学习库BLiTZ实现LSTM预测时序数据(二)

创建神经网络类

我们的网络类接收variantal_estimator装饰器,该装饰器可简化对贝叶斯神经网络损失的采样。我们的网络具有一个贝叶斯LSTM层,参数设置为in_features = 1以及out_features = 10,后跟一个nn.Linear(10, 1),该层输出股票的标准化价格。

@variational_estimator
class NN(nn.Module):
     def __init__(self):
         super(NN, self).__init__()
         self.lstm_1 = BayesianLSTM(1, 10)
         self.linear = nn.Linear(10, 1)
     def forward(self, x):
         x_, _ = self.lstm_1(x)
         #gathering only the latent end-of-sequence for the linear layer
         x_ = x_[:, -1, :]
         x_ = self.linear(x_)
         return x_

如您所见,该网络可以正常工作,唯一的不同点是BayesianLSTM层和variantal_estimator装饰器,但其行为与一般的Torch对象相同。

完成后,我们可以创建我们的神经网络对象,分割数据集并进入训练循环:

创建对象

我们现在可以创建损失函数、神经网络、优化器和dataloader。请注意,我们不是随机分割数据集,因为我们将使用最后一批时间戳来计算模型。由于我们的数据集很小,我们不会对训练集创建dataloader。

Xs, ys = create_timestamps_ds(close_prices)
X_train, X_test, y_train, y_test = train_test_split(Xs,
                                                     ys,
                                                     test_size=.25,
                                                     random_state=42,
                                                     shuffle=False)
ds = torch.utils.data.TensorDataset(X_train, y_train)
dataloader_train = torch.utils.data.DataLoader(ds, batch_size=8, shuffle=True)
net = NN()
criterion = nn.MSELoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

我们将使用MSE损失函数和学习率为0.001的Adam优化器

训练循环

对于训练循环,我们将使用添加了variational_estimatorsample_elbo方法。它对X个样本的损失进行平均,并帮助我们轻松地用蒙特卡洛估计来计算损失。

为了使网络正常工作,网络forward方法的输出必须与传入损失函数对象的标签的形状一致。

iteration = 0
for epoch in range(10):
     for i, (datapoints, labels) in enumerate(dataloader_train):
         optimizer.zero_grad()
         loss = net.sample_elbo(inputs=datapoints,
                                labels=labels,
                                criterion=criterion,
                                sample_nbr=3)
         loss.backward()
         optimizer.step()
         iteration += 1
         if iteration%250==0:
             preds_test = net(X_test)[:,0].unsqueeze(1)
             loss_test = criterion(preds_test, y_test)
             print("Iteration: {} Val-loss: {:.4f}".format(str(iteration), loss_test))

评估模型并计算置信区间

我们将首先创建一个具有要绘制的真实数据的dataframe:

original = close_prices_unscaled[1:][window_size:]
df_pred = pd.DataFrame(original)
df_pred["Date"] = df.Date
df["Date"] = pd.to_datetime(df_pred["Date"])
df_pred = df_pred.reset_index()

要预测置信区间,我们必须创建一个函数来预测同一数据X次,然后收集其均值和标准差。同时,在查询真实数据之前,我们必须设置将尝试预测的窗口大小。

让我们看一下预测函数的代码:

def pred_stock_future(X_test,
                                            future_length,
                                            sample_nbr=10):
     #sorry for that, window_size is a global variable, and so are X_train and Xs
     global window_size
     global X_train
     global Xs
     global scaler
     #creating auxiliar variables for future prediction
     preds_test = []
     test_begin = X_test[0:1, :, :]
     test_deque = deque(test_begin[0,:,0].tolist(), maxlen=window_size)
     idx_pred = np.arange(len(X_train), len(Xs))
     #predict it and append to list
     for i in range(len(X_test)):
         #print(i)
         as_net_input = torch.tensor(test_deque).unsqueeze(0).unsqueeze(2)
         pred = [net(as_net_input).cpu().item() for i in range(sample_nbr)]
         test_deque.append(torch.tensor(pred).mean().cpu().item())
         preds_test.append(pred)
         if i % future_length == 0:
             #our inptus become the i index of our X_test
             #That tweak just helps us with shape issues
             test_begin = X_test[i:i+1, :, :]
             test_deque = deque(test_begin[0,:,0].tolist(), maxlen=window_size)
     #preds_test = np.array(preds_test).reshape(-1, 1)
     #preds_test_unscaled = scaler.inverse_transform(preds_test)
     return idx_pred, preds_test

我们要将置信区间保存下来,确定我们置信区间的宽度。

def get_confidence_intervals(preds_test, ci_multiplier):
     global scaler
     preds_test = torch.tensor(preds_test)
     pred_mean = preds_test.mean(1)
     pred_std = preds_test.std(1).detach().cpu().numpy()
     pred_std = torch.tensor((pred_std))
     upper_bound = pred_mean + (pred_std * ci_multiplier)
     lower_bound = pred_mean - (pred_std * ci_multiplier)
     #gather unscaled confidence intervals
     pred_mean_final = pred_mean.unsqueeze(1).detach().cpu().numpy()
     pred_mean_unscaled = scaler.inverse_transform(pred_mean_final)
     upper_bound_unscaled = upper_bound.unsqueeze(1).detach().cpu().numpy()
     upper_bound_unscaled = scaler.inverse_transform(upper_bound_unscaled)
     lower_bound_unscaled = lower_bound.unsqueeze(1).detach().cpu().numpy()
     lower_bound_unscaled = scaler.inverse_transform(lower_bound_unscaled)
     return pred_mean_unscaled, upper_bound_unscaled, lower_bound_unscaled

由于我们使用的样本数量很少,因此用一个很高的标准差对其进行了补偿。我们的网络将尝试预测7天,然后将参考数据:

future_length=7
sample_nbr=4
ci_multiplier=10
idx_pred, preds_test = pred_stock_future(X_test, future_length, sample_nbr)
pred_mean_unscaled, upper_bound_unscaled, lower_bound_unscaled = get_confidence_intervals(preds_test,
                                                                                           ci_multiplier)

我们可以通过查看实际值是否低于上限并高于下限来检查置信区间。设置好参数后,您应该拥有95%的置信区间,如下所示:

y = np.array(df.Close[-750:]).reshape(-1, 1)
under_upper = upper_bound_unscaled > y
over_lower = lower_bound_unscaled < y
total = (under_upper == over_lower)
print("{} our predictions are in our confidence interval".format(np.mean(total)))


检查输出图形

现在,我们将把预测结果绘制为可视化图形来检查我们的网络是否运行的很顺利,我们将在置信区间内绘制真实值与预测值。

params = {"ytick.color" : "w",
           "xtick.color" : "w",
           "axes.labelcolor" : "w",
           "axes.edgecolor" : "w"}
plt.rcParams.update(params)
plt.title("IBM Stock prices", color="white")
plt.plot(df_pred.index,
          df_pred.Close,
          color='black',
          label="Real")
plt.plot(idx_pred,
          pred_mean_unscaled,
          label="Prediction for {} days, than consult".format(future_length),
          color="red")
plt.fill_between(x=idx_pred,
                  y1=upper_bound_unscaled[:,0],
                  y2=lower_bound_unscaled[:,0],
                  facecolor='green',
                  label="Confidence interval",
                  alpha=0.5)
plt.legend()

image.png

最后,我们放大一下着重看看预测部分。

params = {"ytick.color" : "w",
           "xtick.color" : "w",
           "axes.labelcolor" : "w",
           "axes.edgecolor" : "w"}
plt.rcParams.update(params)
plt.title("IBM Stock prices", color="white")
plt.fill_between(x=idx_pred,
                  y1=upper_bound_unscaled[:,0],
                  y2=lower_bound_unscaled[:,0],
                  facecolor='green',
                  label="Confidence interval",
                  alpha=0.75)
plt.plot(idx_pred,
          df_pred.Close[-len(pred_mean_unscaled):],
          label="Real",
          alpha=1,
          color='black',
          linewidth=0.5)
plt.plot(idx_pred,
          pred_mean_unscaled,
          label="Prediction for {} days, than consult".format(future_length),
          color="red",
          alpha=0.5)
plt.legend()

image.png

总结

我们看到BLiTZ内置的贝叶斯LSTM使得贝叶斯深度学习的所有功能都变得非常简单,并且可以顺利地在时间序列上进行迭代。我们还看到,贝叶斯LSTM已与Torch很好地集成在一起,并且易于使用,你可以在任何工作或研究中使用它。

我们还可以非常准确地预测IBM股票价格的置信区间,而且这比一般的点估计可能要有用的多。

目录
相关文章
|
3月前
|
机器学习/深度学习 数据可视化 算法
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
神经常微分方程(Neural ODEs)是深度学习领域的创新模型,将神经网络的离散变换扩展为连续时间动力系统。本文基于Torchdyn库介绍Neural ODE的实现与训练方法,涵盖数据集构建、模型构建、基于PyTorch Lightning的训练及实验结果可视化等内容。Torchdyn支持多种数值求解算法和高级特性,适用于生成模型、时间序列分析等领域。
246 77
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
|
2月前
|
机器学习/深度学习 自然语言处理 算法
PyTorch PINN实战:用深度学习求解微分方程
物理信息神经网络(PINN)是一种将深度学习与物理定律结合的创新方法,特别适用于微分方程求解。传统神经网络依赖大规模标记数据,而PINN通过将微分方程约束嵌入损失函数,显著提高数据效率。它能在流体动力学、量子力学等领域实现高效建模,弥补了传统数值方法在高维复杂问题上的不足。尽管计算成本较高且对超参数敏感,PINN仍展现出强大的泛化能力和鲁棒性,为科学计算提供了新路径。文章详细介绍了PINN的工作原理、技术优势及局限性,并通过Python代码演示了其在微分方程求解中的应用,验证了其与解析解的高度一致性。
194 5
PyTorch PINN实战:用深度学习求解微分方程
|
3月前
|
机器学习/深度学习 PyTorch TensorFlow
深度学习工具和框架详细指南:PyTorch、TensorFlow、Keras
在深度学习的世界中,PyTorch、TensorFlow和Keras是最受欢迎的工具和框架,它们为研究者和开发者提供了强大且易于使用的接口。在本文中,我们将深入探索这三个框架,涵盖如何用它们实现经典深度学习模型,并通过代码实例详细讲解这些工具的使用方法。
|
6月前
|
机器学习/深度学习 监控 PyTorch
深度学习工程实践:PyTorch Lightning与Ignite框架的技术特性对比分析
在深度学习框架的选择上,PyTorch Lightning和Ignite代表了两种不同的技术路线。本文将从技术实现的角度,深入分析这两个框架在实际应用中的差异,为开发者提供客观的技术参考。
148 7
|
7月前
|
机器学习/深度学习 算法 PyTorch
深度学习笔记(十三):IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU、WIOU损失函数分析及Pytorch实现
这篇文章详细介绍了多种用于目标检测任务中的边界框回归损失函数,包括IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU和WIOU,并提供了它们的Pytorch实现代码。
1288 1
深度学习笔记(十三):IOU、GIOU、DIOU、CIOU、EIOU、Focal EIOU、alpha IOU、SIOU、WIOU损失函数分析及Pytorch实现
|
8月前
|
机器学习/深度学习 PyTorch 调度
在Pytorch中为不同层设置不同学习率来提升性能,优化深度学习模型
在深度学习中,学习率作为关键超参数对模型收敛速度和性能至关重要。传统方法采用统一学习率,但研究表明为不同层设置差异化学习率能显著提升性能。本文探讨了这一策略的理论基础及PyTorch实现方法,包括模型定义、参数分组、优化器配置及训练流程。通过示例展示了如何为ResNet18设置不同层的学习率,并介绍了渐进式解冻和层适应学习率等高级技巧,帮助研究者更好地优化模型训练。
630 4
在Pytorch中为不同层设置不同学习率来提升性能,优化深度学习模型
|
7月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于贝叶斯优化CNN-LSTM网络的数据分类识别算法matlab仿真
本项目展示了基于贝叶斯优化(BO)的CNN-LSTM网络在数据分类中的应用。通过MATLAB 2022a实现,优化前后效果对比明显。核心代码附带中文注释和操作视频,涵盖BO、CNN、LSTM理论,特别是BO优化CNN-LSTM网络的batchsize和学习率,显著提升模型性能。
|
7月前
|
机器学习/深度学习 算法 数据可视化
如果你的PyTorch优化器效果欠佳,试试这4种深度学习中的高级优化技术吧
在深度学习领域,优化器的选择对模型性能至关重要。尽管PyTorch中的标准优化器如SGD、Adam和AdamW被广泛应用,但在某些复杂优化问题中,这些方法未必是最优选择。本文介绍了四种高级优化技术:序列最小二乘规划(SLSQP)、粒子群优化(PSO)、协方差矩阵自适应进化策略(CMA-ES)和模拟退火(SA)。这些方法具备无梯度优化、仅需前向传播及全局优化能力等优点,尤其适合非可微操作和参数数量较少的情况。通过实验对比发现,对于特定问题,非传统优化方法可能比标准梯度下降算法表现更好。文章详细描述了这些优化技术的实现过程及结果分析,并提出了未来的研究方向。
149 1
|
8月前
|
机器学习/深度学习 数据挖掘 PyTorch
🎓PyTorch深度学习入门课:编程小白也能玩转的高级数据分析术
踏入深度学习领域,即使是编程新手也能借助PyTorch这一强大工具,轻松解锁高级数据分析。PyTorch以简洁的API、动态计算图及灵活性著称,成为众多学者与工程师的首选。本文将带你从零开始,通过环境搭建、构建基础神经网络到进阶数据分析应用,逐步掌握PyTorch的核心技能。从安装配置到编写简单张量运算,再到实现神经网络模型,最后应用于图像分类等复杂任务,每个环节都配有示例代码,助你快速上手。实践出真知,不断尝试和调试将使你更深入地理解这些概念,开启深度学习之旅。
120 1
|
7月前
|
机器学习/深度学习 自然语言处理 PyTorch
【机器学习】探索LSTM:深度学习领域的强大时间序列处理能力
【机器学习】探索LSTM:深度学习领域的强大时间序列处理能力