Deep learning Pytorch默认数据加载器无法用于大型图像分类训练集
我正在Pytorch中训练图像分类模型,并使用它们加载我的训练数据。我有一个非常大的训练数据集,所以通常每个类有几千张样本图像。在过去,我训练过的模型总共有大约200k张图像,没有任何问题。然而,我发现,当Pytorch数据加载程序总共有超过一百万张图像时,就会卡住 我相信当我调用Deep learning Pytorch默认数据加载器无法用于大型图像分类训练集,deep-learning,computer-vision,classification,pytorch,dataloader,Deep Learning,Computer Vision,Classification,Pytorch,Dataloader,我正在Pytorch中训练图像分类模型,并使用它们加载我的训练数据。我有一个非常大的训练数据集,所以通常每个类有几千张样本图像。在过去,我训练过的模型总共有大约200k张图像,没有任何问题。然而,我发现,当Pytorch数据加载程序总共有超过一百万张图像时,就会卡住 我相信当我调用dataset.ImageFolder(…)时,代码是挂起的。当I Ctrl-C时,这始终是输出: Traceback (most recent call last):
dataset.ImageFolder(…)
时,代码是挂起的。当I Ctrl-C时,这始终是输出:
Traceback (most recent call last): │
File "main.py", line 412, in <module> │
main() │
File "main.py", line 122, in main │
run_training(args.group, args.num_classes) │
File "main.py", line 203, in run_training │
train_loader = create_dataloader(traindir, tfm.train_trans, shuffle=True) │
File "main.py", line 236, in create_dataloader │
dataset = datasets.ImageFolder(directory, trans) │
File "/home/username/.local/lib/python3.5/site-packages/torchvision/datasets/folder.py", line 209, in __init__ │
is_valid_file=is_valid_file) │
File "/home/username/.local/lib/python3.5/site-packages/torchvision/datasets/folder.py", line 94, in __init__ │
samples = make_dataset(self.root, class_to_idx, extensions, is_valid_file) │
File "/home/username/.local/lib/python3.5/site-packages/torchvision/datasets/folder.py", line 47, in make_dataset │
for root, _, fnames in sorted(os.walk(d)): │
File "/usr/lib/python3.5/os.py", line 380, in walk │
is_dir = entry.is_dir() │
Keyboard Interrupt
回溯(最近一次呼叫最后一次):│
文件“main.py”,第412行,在│
main()│
文件“main.py”,第122行,在main中│
运行\u培训(args.group、args.num\u类)│
run_training中的文件“main.py”,第203行│
列车加载器=创建数据加载器(列车目录,tfm.train\U trans,随机播放=真)│
文件“main.py”,第236行,在create_dataloader中│
dataset=datasets.ImageFolder(目录,trans)│
文件“/home/username/.local/lib/python3.5/site packages/torchvision/datasets/folder.py”,第209行,在│
是否有效\u文件=是否有效\u文件)│
文件“/home/username/.local/lib/python3.5/site packages/torchvision/datasets/folder.py”,第94行,在│
samples=make_数据集(self.root,class_to_idx,扩展名,是有效的文件)│
make_数据集中第47行的文件“/home/username/.local/lib/python3.5/site packages/torchvision/datasets/folder.py”│
对于根,在排序(os.walk(d)):│
文件“/usr/lib/python3.5/os.py”,第380行,在walk中│
is_dir=entry.is_dir()│
键盘中断
我认为某个地方可能会出现死锁,但是根据Ctrl-C的堆栈输出,它看起来不像是在等待锁。然后我认为数据加载程序很慢,因为我试图加载更多的数据。我让它运行了大约2天,但没有取得任何进展,在加载的最后2个小时里,我检查了RAM的使用量是否保持不变。在过去的不到几个小时内,我还能够加载超过200k图像的训练数据集。我还尝试升级我的GCP机器,使其具有32个内核、4个GPU和超过100GB的RAM,但似乎在加载了一定数量的内存后,数据加载程序就卡住了
我很困惑数据加载器在目录中循环时怎么会卡住,我仍然不确定它是卡住了还是速度太慢。有什么方法可以改变Pytortch数据加载器,使其能够处理超过100万张图像进行培训?任何调试建议也将不胜感激
谢谢大家! 这不是数据加载器的问题,而是torchvision.datasets.ImageFolder的问题,以及它是如何工作的(以及为什么数据越多,它工作得更糟) 如您的错误所示,它挂在这一行上:
for root, _, fnames in sorted(os.walk(d)):
来源可以找到
根本问题是它将每个路径
和相应的标签
保存在巨人列表
中,请参见下面的代码(为了简洁起见删除了一些内容):
显然,图像将包含100万个字符串(相当长)和相应的类int
,这些类肯定非常多,并且依赖于RAM和CPU
不过,您可以创建自己的数据集(前提是您事先更改了图像的名称),这样数据集就不会占用内存
设置数据结构
您的文件夹结构应如下所示:
root
class1
class2
class3
...
使用您拥有/需要的课程数量
现在,每个类
应具有以下数据:
class1
0.png
1.png
2.png
...
鉴于此,您可以继续创建数据集
创建数据集
下面的torch.utils.data.Dataset
使用PIL
打开图像,您可以用另一种方式:
import os
import pathlib
import torch
from PIL import Image
class ImageDataset(torch.utils.data.Dataset):
def __init__(self, root: str, folder: str, klass: int, extension: str = "png"):
self._data = pathlib.Path(root) / folder
self.klass = klass
self.extension = extension
# Only calculate once how many files are in this folder
# Could be passed as argument if you precalculate it somehow
# e.g. ls | wc -l on Linux
self._length = sum(1 for entry in os.listdir(self._data))
def __len__(self):
# No need to recalculate this value every time
return self._length
def __getitem__(self, index):
# images always follow [0, n-1], so you access them directly
return Image.open(self._data / "{}.{}".format(str(index), self.extension))
现在,您可以轻松地创建数据集(假定文件夹结构与上述结构类似:
root = "/path/to/root/with/images"
dataset = (
ImageDataset(root, "class0", 0)
+ ImageDataset(root, "class1", 1)
+ ImageDataset(root, "class2", 2)
)
您可以使用指定的类添加任意数量的数据集
,可以在循环中执行,也可以执行任何操作
最后,按照常规使用torch.utils.data.DataLoader
,例如:
dataloader = torch.utils.data.DataLoader(dataset, batch_size=64, shuffle=True)
这不是数据加载器的问题,而是torchvision.datasets.ImageFolder的问题,以及它是如何工作的(以及为什么它工作得越差,数据越多)
如您的错误所示,它挂在这一行上:
for root, _, fnames in sorted(os.walk(d)):
来源可以找到
根本问题是它将每个路径
和相应的标签
保存在巨人列表
中,请参见下面的代码(为了简洁起见删除了一些内容):
明显的图像