为 PyTorch 使用大型数据集的最有效方法?

Dou*_*hur 8 python memory hdf5 data-processing pytorch

也许之前已经问过这个问题,但我无法找到适合我情况的相关信息。

我正在使用 PyTorch 创建一个用于图像数据回归的 CNN。我没有正式的学术编程背景,所以我的许多方法都是临时的,而且效率非常低。有时我可以回顾我的代码并在以后清理内容,因为效率低下并没有那么严重以至于性能受到显着影响。但是,在这种情况下,我使用图像数据的方法需要很长时间,使用大量内存,并且每次我想测试模型中的更改时都会这样做。

我所做的基本上是将图像数据加载到 numpy 数组中,将这些数组保存在 .npy 文件中,然后当我想将所述数据用于模型时,我导入该文件中的所有数据。我不认为数据集真的那么大,因为它由 5000 张 64x64 大小的 3 个颜色通道图像组成。然而,我的内存使用率在加载时高达 70%-80%(16gb),每次加载需要 20-30 秒。

我的猜测是我对加载它的方式很愚蠢,但坦率地说,我不确定标准是什么。我应该以某种方式在我需要之前将图像数据放在某个地方,还是应该直接从图像文件中加载数据?在任何一种情况下,独立于文件结构的最佳、最有效的方法是什么?

我真的很感激这方面的任何帮助。

Odd*_*org 12

对于速度,我建议使用HDF5LMDB

使用 LMDB 的原因:

LMDB 使用内存映射文件,提供更好的 I/O 性能。适用于非常大的数据集。HDF5 文件始终完全读入内存,因此任何 HDF5 文件都不能超出内存容量。不过,您可以轻松地将数据拆分为多个 HDF5 文件(只需在文本文件中放置几个​​指向 h5 文件的路径)。再说一次,与 LMDB 的页面缓存相比,I/O 性能几乎没有那么好。[http://deepdish.io/2015/04/28/creating-lmdb-in-python/]

如果您决定使用LMDB

ml-pyxis是一个使用 LMDBs 创建和读取深度学习数据集的工具。*(我是这个工具的共同作者)

它允许创建二进制 blob (LMDB),并且可以非常快地读取它们。上面的链接提供了一些关于如何创建和读取数据的简单示例。包括 python 生成器/迭代器。

这个笔记本有一个关于如何在使用 pytorch 时创建数据集并并行读取它的示例。

如果您决定使用HDF5

PyTables 是一个用于管理分层数据集的包,旨在高效、轻松地处理海量数据。

https://www.pytables.org/


kma*_*o23 7

这是一个具体的例子来证明我的意思。这假设您已经train_images.hdf5使用h5py.

import h5py
hf = h5py.File('train_images.hdf5', 'r')

group_key = list(hf.keys())[0]
ds = hf[group_key]

# load only one example
x = ds[0]

# load a subset, slice (n examples) 
arr = ds[:n]

# should load the whole dataset into memory.
# this should be avoided
arr = ds[:]
Run Code Online (Sandbox Code Playgroud)

简单来说,ds现在可以用作迭代器,它可以即时提供图像(即它不会在内存中加载任何内容)。这应该使整个运行时间飞快。

for idx, img in enumerate(ds):
   # do something with `img`
Run Code Online (Sandbox Code Playgroud)