python - 不应打开任何文件时 PyTorch 的数据加载器 "too many open files"错误

标签 python python-3.x pytorch

所以这是说明问题的最小代码:

这是数据集:

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

我在这里做错了什么?

最佳答案

我知道如何修复错误,但我没有完整的解释为什么会发生。

首先,解决方案:您需要确保图像数据存储为numpy.array s,当你调用json.loads它将它们加载为 python listfloat秒。这会导致 torch.utils.data.DataLoader将列表中的每个 float 单独转换为 torch.DoubleTensor .

看看default_collatetorch.utils.data.DataLoader - 你的__getitem__返回 dict这是一个映射,所以 default_collatedict 的每个元素上再次调用.第一对是int s,但是你得到的图像数据是 list ,即 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 文件,并测试了对该虚拟文件的修复。

关于python - 不应打开任何文件时 PyTorch 的数据加载器 "too many open files"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48250053/

相关文章:

python - 如何从 python 中的文本文件中读取整数值(逐位)

python - Quickbase模块add_record()函数——文件上传参数?

Python Multiprocessing Pool.map 导致 __new__ 错误

python-3.x - 在终端 debian 中运行 python 脚本 (file.py),错误 (<function b at 0x7f63232c01e0>)

tensorflow - 如何实现强大的背景去除?

python - 用于获取 RSS 的 Django cron

python - 在Python中将markdown标题转换为 anchor

python - 将类转换为模块 Python3

Python (Pytorch) 多处理抛出错误 : Connection reset by peer and File Not Found

deep-learning - 如何计算 PyTorch 中的自举交叉熵损失?