我对在时间序列数据上实现 PyTorch 数据管道的"最佳实践"有点困惑。
我有一个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)
文档指出启用自动批处理时,它总是在批处理维度前面加上一个新维度,这让我相信自动批处理被禁用,但我不明白为什么?
如果你有一个张量对的数据集(x, y)
,其中每个x
的形状都是(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])
我发现了一些似乎有效的东西,一种选择似乎是使用 DataLoader 的collate_fn
但更简单的选择是使用BatchSampler
,即
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((效率不是特别高(。