从 PyTorch 自定义数据集 __getitem__ 中巨大的未压缩 tar 文件读取图像的最快方法

Fastest way to read an image from huge uncompressed tar file in __getitem__ of PyTorch custom dataset

我在一个未压缩的 TAR 文件中有一个巨大的 jpg 图像数据集(200 万)。我还有一个 txt 文件,每一行都是 TAR 文件中图像的名称,按顺序排列。

img_0000001.jpg
img_0000002.jpg
img_0000003.jpg
...

和tar文件中的图片完全一样。 我搜索了很多,发现 tarfile 模块是最好的模块,但是当我尝试使用 name 从 tar 文件读取图像时,它花费的时间太长了。原因是,每次我调用 getmemeber(name) 方法时,它都会调用扫描整个 tar 文件的 getmembers() 方法,然后 return 所有名称的 Namespace,然后start 在这个 Namespace.

中发现

如果有帮助,我的数据集大小是 20GB 单个 tar 文件。

我不知道先提取所有内容然后在我的 CustomDataset 中使用提取的文件夹或直接从存档中读取更好的主意。

这是我用来从 tar 文件中读取单个文件的代码:

        with tarfile.open('data.tar') as tf:
            tarinfo = tf.getmember('img_000001.jpg')
            image = tf.extractfile(tarinfo)
            image = image.read()
            image = Image.open(io.BytesIO(image))

我在 CustomDataset class 的 __getitem__ 方法中使用了这段代码,它循环遍历 filelist.txt

中的所有名称

感谢任何建议

tarfile 似乎有 getmember 的缓存,它重复使用 getmembers() 个结果。

但是,如果您使用 __getitem__ 中提供的片段,那么对于数据集中的每个项目,tar 文件都会打开并完全读取,提取一个图像文件,然后 tar 文件关闭,相关信息丢失。

解决此问题的最简单方法可能是像 self.tf = tarfile.open('data.tar') 一样打开数据集 __init__ 中的 tar 文件,但您需要记得最后关闭它。