Pytorch's dataloader" слишком много открытых файлов " ошибка, когда файлы не должны быть открыты
Так это минимальный код, который иллюстрирует проблему:
- Это набор данных:
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
что я здесь делаю не так?
1 ответов
я знаю как исправить ошибку, но у меня нет полного объяснения, почему это происходит.
во-первых, решение: вы должны убедиться, что данные изображения хранятся в виде numpy.array
s, Когда вы вызываете json.loads
он загружает их как python list
С float
s. Это вызывает torch.utils.data.DataLoader
чтобы индивидуально преобразовать каждый поплавок в списке в torch.DoubleTensor
.
посмотреть default_collate
на torch.utils.data.DataLoader
- код __getitem__
возвращает dict
, который является отображением, так что default_collate
снова вызывается для каждого элемента dict
. Первая пара int
s, но затем вы получаете данные изображения, которое является list
, то есть a collections.Sequence
- вот где все становится фанки, как default_collate
вызывается для каждого элемента списка. Это явно не то, что вы хотели. Я не знаю, какое предположение в torch
о содержании list
и numpy.array
, но, учитывая ошибку, кажется, что это предположение нарушается.
исправление довольно тривиально, просто убедитесь, что две полосы изображений numpy.array
s, например в __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
?
я не знаю, но, как указано в комментариях, это, скорее всего, связано с межпроцессной связью и блокировкой файлов в двух очередях, данные берутся и добавляются к.
Примечание:train.json
не было доступно для загрузки из Kaggle из-за того, что конкурс все еще открыт (??). Я сделал фиктивный файл json, который должен иметь ту же структуру и протестировал исправление этого фиктивного файла.