ce1*_*ce1 5 python zip machine-learning conv-neural-network pytorch
我正在尝试实现一个包含两个图像的暹罗网络。我加载这些图像并创建两个单独的数据加载器。
在循环中,我想同时浏览两个数据加载器,以便可以在两个图像上训练网络。
for i, data in enumerate(zip(dataloaders1, dataloaders2)):
# get the inputs
inputs1 = data[0][0].cuda(async=True);
labels1 = data[0][1].cuda(async=True);
inputs2 = data[1][0].cuda(async=True);
labels2 = data[1][1].cuda(async=True);
labels1 = labels1.view(batchSize,1)
labels2 = labels2.view(batchSize,1)
# zero the parameter gradients
optimizer.zero_grad()
# forward + backward + optimize
outputs1 = alexnet(inputs1)
outputs2 = alexnet(inputs2)
Run Code Online (Sandbox Code Playgroud)
数据加载器的返回值是一个元组。但是,当我尝试使用zip
它们进行迭代时,出现以下错误:
OSError: [Errno 24] Too many open files
Exception NameError: "global name 'FileNotFoundError' is not defined" in <bound method _DataLoaderIter.__del__ of <torch.utils.data.dataloader._DataLoaderIter object at 0x7f2d3c00c190>> ignored
Run Code Online (Sandbox Code Playgroud)
不应在所有可迭代项目上进行压缩吗?但是似乎在这里我不能在数据加载器上使用它。
还有其他方法可以做到这一点吗?还是我错误地接近了暹罗网络的实现?
afr*_*iti 10
继它是什么已经提到的,cycle()
并zip()
可能造成内存泄漏问题-使用图像数据集时特别!为了解决这个问题,而不是像这样迭代:
dataloaders1 = DataLoader(DummyDataset(0, 100), batch_size=10, shuffle=True)
dataloaders2 = DataLoader(DummyDataset(0, 200), batch_size=10, shuffle=True)
num_epochs = 10
for epoch in range(num_epochs):
for i, (data1, data2) in enumerate(zip(cycle(dataloaders1), dataloaders2)):
do_cool_things()
Run Code Online (Sandbox Code Playgroud)
你可以使用:
dataloaders1 = DataLoader(DummyDataset(0, 100), batch_size=10, shuffle=True)
dataloaders2 = DataLoader(DummyDataset(0, 200), batch_size=10, shuffle=True)
num_epochs = 10
for epoch in range(num_epochs):
dataloader_iterator = iter(dataloaders1)
for i, data1 in enumerate(dataloaders2)):
try:
data2 = next(dataloader_iterator)
except StopIteration:
dataloader_iterator = iter(dataloaders1)
data2 = next(dataloader_iterator)
do_cool_things()
Run Code Online (Sandbox Code Playgroud)
请记住,如果您也使用标签,则应在此示例data1
中用(inputs1,targets1)
和data2
替换inputs2,targets2
,正如@Sajad Norouzi 所说。
对这个点赞:https : //github.com/pytorch/pytorch/issues/1917#issuecomment-433698337
如果您想同时迭代两个数据集,则无需定义自己的数据集类,只需使用如下 TensorDataset:
dataset = torch.utils.data.TensorDataset(dataset1, dataset2)
dataloader = DataLoader(dataset, batch_size=128, shuffle=True)
for index, (xb1, xb2) in enumerate(dataloader):
....
Run Code Online (Sandbox Code Playgroud)
如果您想要标签或迭代两个以上的数据集,只需将它们作为参数提供给 dataset2 之后的 TensorDataset。
完成@ManojAcharya的答案:
您得到的错误既不是来自zip()
也不是DataLoader()
直接来自。Python试图告诉您,它可能找不到您所要的数据文件之一(参见FileNotFoundError
异常跟踪中的cf )Dataset
。
在下面使用DataLoader
和zip
一起找到工作示例。请注意,如果您想重新整理数据,则很难保留两个数据集之间的对应关系。这证明了@ManojAcharya的解决方案。
import torch
from torch.utils.data import DataLoader, Dataset
class DummyDataset(Dataset):
"""
Dataset of numbers in [a,b] inclusive
"""
def __init__(self, a=0, b=100):
super(DummyDataset, self).__init__()
self.a = a
self.b = b
def __len__(self):
return self.b - self.a + 1
def __getitem__(self, index):
return index, "label_{}".format(index)
dataloaders1 = DataLoader(DummyDataset(0, 9), batch_size=2, shuffle=True)
dataloaders2 = DataLoader(DummyDataset(0, 9), batch_size=2, shuffle=True)
for i, data in enumerate(zip(dataloaders1, dataloaders2)):
print(data)
# ([tensor([ 4, 7]), ('label_4', 'label_7')], [tensor([ 8, 5]), ('label_8', 'label_5')])
# ([tensor([ 1, 9]), ('label_1', 'label_9')], [tensor([ 6, 9]), ('label_6', 'label_9')])
# ([tensor([ 6, 5]), ('label_6', 'label_5')], [tensor([ 0, 4]), ('label_0', 'label_4')])
# ([tensor([ 8, 2]), ('label_8', 'label_2')], [tensor([ 2, 7]), ('label_2', 'label_7')])
# ([tensor([ 0, 3]), ('label_0', 'label_3')], [tensor([ 3, 1]), ('label_3', 'label_1')])
Run Code Online (Sandbox Code Playgroud)
小智 5
添加 @Aldream 的解决方案,用于当我们有不同长度的数据集时,如果我们想在同一时期传递它们,那么我们可以使用 from cycle()
,itertools
一个 Python 标准库。使用@Aldrem的代码片段,更新后的代码将如下所示:
from torch.utils.data import DataLoader, Dataset
from itertools import cycle
class DummyDataset(Dataset):
"""
Dataset of numbers in [a,b] inclusive
"""
def __init__(self, a=0, b=100):
super(DummyDataset, self).__init__()
self.a = a
self.b = b
def __len__(self):
return self.b - self.a + 1
def __getitem__(self, index):
return index
dataloaders1 = DataLoader(DummyDataset(0, 100), batch_size=10, shuffle=True)
dataloaders2 = DataLoader(DummyDataset(0, 200), batch_size=10, shuffle=True)
num_epochs = 10
for epoch in range(num_epochs):
for i, data in enumerate(zip(cycle(dataloaders1), dataloaders2)):
print(data)
Run Code Online (Sandbox Code Playgroud)
只有zip()
当长度等于最小数据集(这里是100)的长度时,迭代器才会被耗尽。但是通过使用cycle()
,我们将再次重复最小的数据集,除非我们的迭代器查看最大数据集(此处为 200)中的所有样本。
PS 人们总是会争辩说,只要随机采样,就可能不需要这种方法来实现收敛,但使用这种方法,评估可能会更容易。
我发现您正在努力构建正确的数据加载器功能。我会做:
class Siamese(Dataset):
def __init__(self, transform=None):
#init data here
def __len__(self):
return #length of the data
def __getitem__(self, idx):
#get images and labels here
#returned images must be tensor
#labels should be int
return img1, img2 , label1, label2
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4509 次 |
最近记录: |