【问题标题】:Fastest way to read an image from huge uncompressed tar file in __getitem__ of PyTorch custom dataset从 PyTorch 自定义数据集的 __getitem__ 中的巨大未压缩 tar 文件中读取图像的最快方法
【发布时间】:2019-08-02 15:21:07
【问题描述】:

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

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

和 tar 文件中的图像完全一样。 我搜索了很多,发现tarfile 模块是最好的模块,但是当我尝试使用name 从tar 文件中读取图像时,需要的时间太长。原因是,每次我调用getmemeber(name) 方法时,它都会调用getmembers() 方法扫描整个tar 文件,然后返回所有名称的Namespace,然后开始在这个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 类的 __getitem__ 方法中使用了这段代码,该方法循环了 filelist.txt 中的所有名称

感谢您的建议

【问题讨论】:

    标签: python image-processing python-imaging-library pytorch tarfile


    【解决方案1】:

    tarfile 似乎对getmember 有缓存,它重用了getmembers() 结果。

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

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

    【讨论】:

    • 感谢您的回答。我会尝试你的想法并更新我的问题。还有一个问题,为什么它不适用于多线程进程?我的意思是如果将num_workers 从 1 增加到任意数字。
    • 实际上它应该适用于并行读取。我将从我的答案中删除该部分。
    • 我用你的想法做了一些修改。我在 init 中调用了tf.getmembers 方法,然后在__getitem__ 方法中使用了tf.extractfile(或tf.getmember)。谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    相关资源
    最近更新 更多