2

对于在时间序列数据上实现 PyTorch 数据管道的“最佳实践”,我有点困惑。

我有一个使用自定义 DataLoader 读取的 HD5 文件。似乎我应该将数据样本作为(特征,目标)元组返回,每个元组的形状都是(L,C),其中 L 是 seq_len,C 是通道数 - 即不要在数据加载器中进行批处理,只是作为一张桌子返回。

PyTorch 模块似乎需要批量调暗,即 Conv1D 需要 (N, C, L)。

我的印象是DataLoader该类会预先设置批处理维度,但事实并非如此,我正在获取数据形状(N,L)。

dataset = HD5Dataset(args.dataset)

dataloader = DataLoader(dataset,
                        batch_size=N,
                        shuffle=True,
                        pin_memory=is_cuda,
                        num_workers=num_workers)

for i, (x, y) in enumerate(train_dataloader):
    ...

在上面的代码中,x 的形状是 (N,C) 而不是 (1,N,C),这导致下面的代码(来自公共 git 存储库)在第一行失败。

def forward(self, x):
    """expected input shape is (N, L, C)"""
    x = x.transpose(1, 2).contiguous() # input should have dimension (N, C, L)

文档状态启用自动批处理时 它总是预先添加一个新维度作为批处理维度,这让我相信自动批处理被禁用但我不明白为什么?

4

2 回答 2

1

如果你有一个张量对的数据集(x, y),其中每个x都是 shape (C,L),那么:

N, C, L = 5, 3, 10
dataset = [(torch.randn(C,L), torch.ones(1)) for i in range(50)]
dataloader = data_utils.DataLoader(dataset, batch_size=N)

for i, (x,y) in enumerate(dataloader):
    print(x.shape)

将产生 (50/N)=10 批形状(N,C,L)x

torch.Size([5, 3, 10])
torch.Size([5, 3, 10])
torch.Size([5, 3, 10])
torch.Size([5, 3, 10])
torch.Size([5, 3, 10])
torch.Size([5, 3, 10])
torch.Size([5, 3, 10])
torch.Size([5, 3, 10])
torch.Size([5, 3, 10])
torch.Size([5, 3, 10])
于 2021-04-20T17:19:36.903 回答
0

我发现了一些似乎可行的方法,一个选项似乎是使用 DataLoader,collate_fn但更简单的选项是使用BatchSamplerie

dataset = HD5Dataset(args.dataset)
train, test = train_test_split(list(range(len(dataset))), test_size=.1)

train_dataloader = DataLoader(dataset,
                        pin_memory=is_cuda,
                        num_workers=num_workers,
                        sampler=BatchSampler(SequentialSampler(train),batch_size=len(train), drop_last=True)
                        )

test_dataloader = DataLoader(dataset,
                        pin_memory=is_cuda,
                        num_workers=num_workers,
                        sampler=BatchSampler(SequentialSampler(test),batch_size=len(test), drop_last=True)
                        )

for i, (x, y) in enumerate(train_dataloader):
    print (x,y)

这会将数据集 dim (L, C) 转换为单批 (1, L, C)(不是特别有效)。

于 2020-06-19T06:12:54.120 回答