PyTorch 时序预测中 Dataloader 的构建要点
在使用 PyTorch 进行时序预测(如 GRU、LSTM)时,Dataloader 的构建方式直接影响模型能否正确学习时间依赖。很多开发者会纠结两个问题:自定义 Dataset 时如何处理序列切片,以及开启 shuffle=True 是否会打乱时间顺序。
时序数据与静态数据的差异
对于非时序数据,Dataset 的 __getitem__ 直接根据索引返回单条样本即可,此时 shuffle 与否主要影响训练时的批次顺序。但时序数据不同,一个'样本'往往是由多个时刻组成的序列。
如果数据量不大,我们可以预先用循环将所有序列拼接成一个大矩阵。例如设定窗口大小为 2,遍历原始数据生成输入 X 和标签 y:
X = []
y = []
window_size = 2
for i in range(len(data) - window_size):
X.append(data[i:i+window_size, :])
y.append(labels[i+window_size-1])
X = np.array(X)
y = np.array(y)
这种方式直观,但在数据量大时会消耗大量内存且耗时。更推荐的做法是在 Dataset 内部动态切片,既节省空间又灵活。
自定义 Dataset 实现
下面是一个标准的时序 Dataset 写法。注意 __len__ 需要减去窗口大小,防止越界:
class TimeSeriesDataset(Dataset):
def __init__(self, features, labels, window_size=2):
self.window_size = window_size
self.features = features
self.labels = labels
def __getitem__(self, index):
# 获取当前索引开始的窗口序列
feature = self.features[index:index+self.window_size, :]
if self.labels is not None:
label = self.labels[index+self.window_size-1]
return feature, label
:
feature
():
(.features) - .window_size


