【发布时间】:2021-02-04 15:13:24
【问题描述】:
我目前正在构建一个 LSTM 模型,以使用 PyTorch 预测时间序列数据。我使用滞后特征将前面的 n 步作为输入来训练网络。我将数据分成三组,即train-validation-test split,并使用前两组来训练模型。我的验证函数从验证数据集中获取数据,并通过使用 DataLoaders 和 TensorDataset 类将其传递给 LSTM 模型来计算预测值。最初,我在 R2 值在 0.85-0.95 范围内时得到了很好的结果。
但是,我对这个验证功能是否也适合测试我的模型的性能感到不安。因为该函数现在从 DataLoader 获取实际的 X 值,即时滞特征来预测 y^ 值,即预测的目标值,而不是使用预测的 y^ 值作为下一次预测中的特征。这种情况似乎与现实相去甚远,因为模型不知道之前时间步的真实值,尤其是如果您预测较长时间段的时间序列数据,例如 3-6 个月。
我目前对解决这个问题并定义一个函数来预测未来值感到有点困惑,该函数依赖于模型的值而不是测试集中的实际值。我有以下函数predict,它可以进行一步预测,但我还没有真正弄清楚如何使用DataLoader来预测整个测试数据集。
def predict(self, x):
# convert row to data
x = x.to(device)
# make prediction
yhat = self.model(x)
# retrieve numpy array
yhat = yhat.to(device).detach().numpy()
return yhat
您可以在下面找到我如何拆分和加载数据集、LSTM 模型的构造函数以及验证函数。如果您需要更多信息,请随时与我联系。
拆分和加载数据集
def create_tensor_datasets(X_train_arr, X_val_arr, X_test_arr, y_train_arr, y_val_arr, y_test_arr):
train_features = torch.Tensor(X_train_arr)
train_targets = torch.Tensor(y_train_arr)
val_features = torch.Tensor(X_val_arr)
val_targets = torch.Tensor(y_val_arr)
test_features = torch.Tensor(X_test_arr)
test_targets = torch.Tensor(y_test_arr)
train = TensorDataset(train_features, train_targets)
val = TensorDataset(val_features, val_targets)
test = TensorDataset(test_features, test_targets)
return train, val, test
def load_tensor_datasets(train, val, test, batch_size=64, shuffle=False, drop_last=True):
train_loader = DataLoader(train, batch_size=batch_size, shuffle=shuffle, drop_last=drop_last)
val_loader = DataLoader(val, batch_size=batch_size, shuffle=shuffle, drop_last=drop_last)
test_loader = DataLoader(test, batch_size=batch_size, shuffle=shuffle, drop_last=drop_last)
return train_loader, val_loader, test_loader
类 LSTM
class LSTMModel(nn.Module):
def __init__(self, input_dim, hidden_dim, layer_dim, output_dim, dropout_prob):
super(LSTMModel, self).__init__()
self.hidden_dim = hidden_dim
self.layer_dim = layer_dim
self.lstm = nn.LSTM(
input_dim, hidden_dim, layer_dim, batch_first=True, dropout=dropout_prob
)
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x, future=False):
h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()
c0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()
out, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach()))
out = out[:, -1, :]
out = self.fc(out)
return out
验证(在培训师课程中定义)
def validation(self, val_loader, batch_size, n_features):
with torch.no_grad():
predictions = []
values = []
for x_val, y_val in val_loader:
x_val = x_val.view([batch_size, -1, n_features]).to(device)
y_val = y_val.to(device)
self.model.eval()
yhat = self.model(x_val)
predictions.append(yhat.cpu().detach().numpy())
values.append(y_val.cpu().detach().numpy())
return predictions, values
【问题讨论】:
标签: machine-learning deep-learning time-series pytorch lstm