pytorch使用GRU等做时序预测的Dataloader如何构建

一、本文所关注的内容

本文主要聚焦以下几个问题:

  • pytorch的Dataloader中设置shuffle=True的时候究竟打乱的是什么
  • 在构建时序数据的时候,可不可以设置shuffle=True

二、时序数据与非时序数据的区别

在非时序预测中,在自定义dataset的时候根据index直接返回对应索引的一个样本就行了,此时不管dataloader是否设置shuffle=True,都可以正常返回数据,只是shuffle=False的时候可能会稍微影响性能。

但是在时序数据里,如果我们不提前把数据处理成:一个样本就是一个序列。的形式,那么就需要在dataset中自己手动取一个序列,此时需要考虑是否打乱了,打乱会不会让时序关系彻底乱了。

什么意思呢,再解释一下,正常来说我们的数据是这样的:每一个样本就是一个一维向量。下面就是每一个样本有7个特征,一共100个样本。

data = [[i] * 7 for i in range(100)]
data = np.array(data)

如果没有时序关系,每次就取一行拿来训练就完了。此时Dataset就可以这样定义:

class aiDataset(Dataset):
    def __init__(self, features, labels):
        self.features = features
        self.labels = labels

    def __getitem__(self, index):
        feature = self.features[index] # .values
        if self.labels is not None:
            label = self.labels[index]
            return feature, label
        else:
            return feature

    def __len__(self):
        return len(self.features)

如果这100个数据是按照时间的,他们有时序关系,而我们又要使用GRU或者LSTM来做,那么我们的输入就不是一个时刻的数据了,而是当前时刻(含)之前若干个时刻组成的序列。当然,我们可以提前写一个for循环,把所有的序列组成一个新的矩阵,比如:

    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)

    print(X.shape)  # [N-window_size, window_size, features_num]
    print(y.shape)  # [N-window_size]

但是,当数据量很大的时候,可能这个循环就要好久,好不如直接写在dataset里。

class aiDataset(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, :] # .values
        if self.labels is not None:
            label = self.labels[index+self.window_size-1]
            return feature, label
        else:
            return feature

    def __len__(self):
        return len(self.features) - self.window_size

那么这就是时序数据在定义dataset的时候和非时序数据的区别了。

三、时序数据要不要设置shuffle=True

当我们定义好dataset之后,不出意外的话,就可以直接定义dataloader了。

data = [[i] * 7 for i in range(100)]
    data = np.array(data)
    labels = [i*2 for i in range(100)]

    train_dataset = aiDataset(data, None, 4) # window_size设置为4
    train_loader = DataLoader(train_dataset, batch_size=2, shuffle=True, num_workers=2)

上面的代码我们设置了shuffle=True,我们来看看每一个batch的东西是什么。

可以看到,即便设置了shuffle=True,每一个batch中的每一个样本依然是按照原来的时序关系的,所以不需要担心shuffle会打乱原来的时序数据。
在这里插入图片描述

四、Dataloader中的shuffle到底shuffle了什么。

这个其实很简单,具体可以看dataloader的源码,比较简单,结论就是打乱的是index,所以我们看到的上面图中同一个batch内的样本是随机的,但是一个样本内是有序的。

Meta-Learning with Adaptation Layers (MAML) 是一种元学习算法,它允许模型快速适应新的任务。在 PyTorch 中实现 MAML 针对时序预测的一个基本步骤如下: 首先,安装必要的库: ```bash pip install torch torchvision gym pytorch-lightning ``` 1. 导入所需的模块: ```python import torch import torch.nn as nn from torch.optim import Adam from torch.utils.data import DataLoader from typing import List from pytorch_lightning import LightningModule, Trainer ``` 2. 创建 Meta-Learner 类(LightningModule 子类),定义模型、适应层和损失函数: ```python class MAML(nn.Module): def __init__(self, base_model: nn.Module, adaptation_layers: List[nn.Module]): super().__init__() self.base_model = base_model self.adaptation_layers = nn.ModuleList(adaptation_layers) def forward(self, x): adapted_weights = self.adapt_to_task(x) return self.base_model(x, adapted_weights) def adapt_to_task(self, support_set): adapted_weights = self.base_model.module.state_dict() if isinstance(self.base_model, nn.DataParallel) else self.base_model.state_dict() for layer in self.adaptation_layers: adapted_weights.update({k: v + layer(support_set) for k, v in adapted_weights.items()}) return adapted_weights # 定义用于计算内核梯度的辅助方法 def compute_inner_loss(self, support_set, query_set): adapted_weights = self.adapt_to_task(support_set) loss = self.compute_task_loss(query_set, adapted_weights) return loss # 你需要根据你的模型和数据集自定义这个方法 def compute_task_loss(self, query_set, adapted_weights): raise NotImplementedError("Implement your task-specific loss function") class TemporalMAML(MAML): # 假设我们处理的是序列数据,所以这里的adaptation_layer可以是一个LSTM或GRU层 def __init__(...): super().__init__(BaseSequenceModel(), [nn.LSTM(...), nn.Linear(...)]) def compute_task_loss(self, ...): ... ``` 3. 实现训练循环: ```python class TemporalMAMLTrainer(LightningModule): def training_step(self, batch, batch_idx): support_set, query_set = batch inner_loss = self.model.compute_inner_loss(support_set, query_set) outer_loss = inner_loss.mean() # 假设每个任务都有相同的权重 self.log("train_loss", outer_loss) return -outer_loss # 其他回调如验证和测试部分也应包含类似的部分 ``` 4. 训练和评估: ```python # 初始化模型、优化器和数据加载器 model = TemporalMAML(...) optimizer = Adam(model.parameters()) data_loader = ... trainer = Trainer(max_epochs=10, gpus=1 if torch.cuda.is_available() else None) trainer.fit(model, dataloader=data_loader) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值