本文将主要讲述如何使用BLiTZ(PyTorch贝叶斯深度学习库)来建立贝叶斯LSTM模型,以及如何在其上使用序列数据进行训练与推理。
在本文中,我们将解释贝叶斯长期短期记忆模型(LSTM)是如何工作的,然后通过一个Kaggle数据集进行股票置信区间的预测。
贝叶斯LSTM层
众所周知,LSTM结构旨在解决使用标准的循环神经网络(RNN)处理长序列数据时发生的信息消失问题。
在数学上,LSTM结构的描述如下:
我们知道,贝叶斯神经网络的核心思想是,相比设定一个确定的权重,我们可以通过一个概率密度分布来对权重进行采样,然后优化分布参数。
利用这一点,就有可能衡量我们所做的预测的置信度和不确定性,这些数据与预测本身一样,都是非常有用的数据。
从数学上讲,我们只需要在上面的方程中增加一些额外的步骤,也即权值和偏置的采样,这发生在前向传播之前。
这表示在第i次在模型第N层上权重的采样。
这表示在第i次在模型第N层上偏置的采样。
当然,我们的可训练参数是和,用来表示不同的权重分布。BLiTZ具有内置的BayesianLSTM
层,可以为您完成所有这些艰苦的工作,因此您只需要关注您的网络结构设计与网络的训练/测试。
现在我们看一个例子。
第一步,先导入库
除了导入深度学习中最常用的库外,我们还需要从blitz.modules
中导入BayesianLSTM
,并从blitz.utils
导入variational_estimator
,后者是一个用于变量训练与复杂度计算的装饰器。
我们还要导入collections.deque
来执行时间序列数据的预处理。
import pandas as pd import numpy as np import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F from blitz.modules import BayesianLSTM from blitz.utils import variational_estimator from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt %matplotlib inline from collections import deque
数据预处理
现在,我们将创建并预处理数据集以将其输入到网络。我们将从Kaggle数据集中导入Amazon股票定价,获取其“收盘价”数据并将其标准化。
我们的数据集将由标准化股票价格的时间戳组成,并且具有一个形如(batch_size,sequence_length,observation_length)
的shape。
下面我们导入数据并对其预处理:
#importing the dataset amazon="data/AMZN_2006-01-01_to_2018-01-01.csv" ibm="data/IBM_2006-01-01_to_2018-01-01.csv" df = pd.read_csv(ibm) #scaling and selecting data close_prices = df["Close"] scaler = StandardScaler() close_prices_arr = np.array(close_prices).reshape(-1, 1) close_prices = scaler.fit_transform(close_prices_arr) close_prices_unscaled = df["Close"]
我们还必须创建一个函数来按照时间戳转换我们的股价历史记录。为此,我们将使用最大长度等于我们正在使用的时间戳大小的双端队列,我们将每个数据点添加到双端队列,然后将其副本附加到主时间戳列表:
def create_timestamps_ds(series, timestep_size=window_size): time_stamps = [] labels = [] aux_deque = deque(maxlen=timestep_size) #starting the timestep deque for i in range(timestep_size): aux_deque.append(0) #feed the timestamps list for i in range(len(series)-1): aux_deque.append(series[i]) time_stamps.append(list(aux_deque)) #feed the labels lsit for i in range(len(series)-1): labels.append(series[i + 1]) assert len(time_stamps) == len(labels), "Something went wrong" #torch-tensoring it features = torch.tensor(time_stamps[timestep_size:]).float() labels = torch.tensor(labels[timestep_size:]).float() return features, labels