所以这是一个说明问题的最小代码:
这是数据集:
class IceShipDataset(Dataset):
BAND1='band_1'
BAND2='band_2'
IMAGE='image'
@staticmethod
def get_band_img(sample,band):
pic_size=75
img=np.array(sample[band])
img.resize(pic_size,pic_size)
return img
def __init__(self,data,transform=None):
self.data=data
self.transform=transform
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
sample=self.data[idx]
band1_img=IceShipDataset.get_band_img(sample,self.BAND1)
band2_img=IceShipDataset.get_band_img(sample,self.BAND2)
img=np.stack([band1_img,band2_img],2)
sample[self.IMAGE]=img
if self.transform is not None:
sample=self.transform(sample)
return sample
这是失败的代码:
PLAY_BATCH_SIZE=4
#load data. There are 1604 examples.
with open('train.json','r') as f:
data=f.read()
data=json.loads(data)
ds=IceShipDataset(data)
playloader = torch.utils.data.DataLoader(ds, batch_size=PLAY_BATCH_SIZE,
shuffle=False, num_workers=4)
for i,data in enumerate(playloader):
print(i)
它在for循环中给出了奇怪的打开文件错误... 我的火炬版本是0.3.0.post4
如果你想要json文件,它可以在Kaggle(https://www.kaggle.com/c/statoil-iceberg-classifier-challenge)
中找到我应该提一下,这个错误与我的笔记本电脑的状态无关:
yoni@yoni-Lenovo-Z710:~$ lsof | wc -l
89114
yoni@yoni-Lenovo-Z710:~$ cat /proc/sys/fs/file-max
791958
我在这里做错了什么?
答案 0 :(得分:1)
我知道如何解决错误,但我没有完整解释原因。
首先,解决方案:您需要确保将图像数据存储为numpy.array
,当您调用json.loads
时,它会将它们加载为python {{1 list
的s。这会导致float
将列表中的每个浮点数单独转换为torch.utils.data.DataLoader
。
查看torch.DoubleTensor
中的default_collate
- 您的torch.utils.data.DataLoader
会返回__getitem__
这是一个映射,因此dict
会在每个元素上再次调用default_collate
dict
。第一对是int
s,但是你得到的图像数据是list
,即collections.Sequence
- 这就是因为调用了default_collate
而变得时髦的地方在列表的每个元素上。这显然不是你想要的。我不知道torch
中关于list
与numpy.array
的内容的假设是什么,但如果出现错误,则表明该假设正在被违反。< / p>
修复非常简单,只需确保两个图像带为numpy.array
,例如__init__
def __init__(self,data,transform=None):
self.data=[]
for d in data:
d[self.BAND1] = np.asarray(d[self.BAND1])
d[self.BAND2] = np.asarray(d[self.BAND2])
self.data.append(d)
self.transform=transform
或者在加载json之后,只要你这样做,那么你做什么并不重要。
为什么上述结果会导致too many open files
?
我不知道,但正如评论所指出的那样,它可能与进程间通信和两个队列上的锁定文件有关,数据是从中获取并添加的。
脚注:由于比赛仍在开放,因此无法从Kaggle下载train.json
(??)。我制作了一个虚拟的json文件,该文件应具有相同的结构并测试该虚拟文件上的修复。