【问题标题】:Fastest way to read huge numpy arrays (with image data) from hDf5 files从 hDf5 文件中读取巨大的 numpy 数组(带有图像数据)的最快方法
【发布时间】:2016-02-22 02:56:07
【问题描述】:

我有大量的图像,我使用 hdf5 文件格式将它们存储在磁盘上(存储了浮点数的 numpy 数组(22500,3,224,224))。 hdf5 文件的大小为 22 GB。

为此,我使用了 python 的 h5py 库。我使用以下代码创建文件。

h5f = h5py.File('data.h5', 'w')
h5f.create_dataset('data' , data=myNumpyArray)
h5f.close()

我有一个机器学习程序可以学习这些数据。所以我有一个在这些文件上运行的迭代器(我有大量数据,所以我制作了 8 个文件,每个文件 22GB)。迭代器加载每个文件并训练网络。然而,这种文件加载非常非常慢。加载文件大约需要 15 分钟。我正在使用下面的代码来加载文件。

h5f = h5py.File('data.h5', 'r')
myNumpyArray= h5f['data'][:]
h5f.close()

因此,要对数据运行 100 次迭代,我将花费 15*8*100(将其乘以 8,因为我有 8 个文件)= 12,000 分钟(仅用于文件读取),这是我负担不起的。

我第一次做这样的事情,不确定我做的是否正确。

有人可以帮助我如何减少文件读取时间吗?或者我写入数据的方式本身是错误的? 任何帮助将不胜感激。

谢谢, 维杰塔。

【问题讨论】:

  • 您的实例有多少内存?如果您的数据比内存大,您将假脱机到磁盘,这将非常慢
  • @maxymoo 提出了一个很好的观点。我会尝试每 220 MB 制作 800 个文件,或者循环遍历类似 h5f['data'][chunksize*i:chunksize*(i+1)]
  • [:] 运算符将在 RAM 中创建数组的副本,这真的是您想要的吗?您是否修改数据本身?根据docs.h5py.org/en/latest/high/dataset.html#chunked-storage,HDF5 中的数据默认是连续存储的,这意味着对任何元素的访问基本上都是即时的,不需要 RAM。
  • @maxymoo 我的系统上有 128 GB,我的数据比这大得多。
  • @scf 我尝试使用命令“ myNumpyArray= h5f['data'][0:150] ”循环遍历数据。但总的来说,它所花费的时间与一次加载整个文件所花费的时间相同。所以我被困在这里。

标签: python image-processing machine-learning computer-vision h5py


【解决方案1】:

使用 SSD — 现在您可以花 200 美元左右购买 500GB 外置硬盘,或者如果您在 AWS 上,租用 EBS SSD 每天只需花费大约 1.50 美元。

当我阅读 100 行块时,我需要 55 秒,而我只是在 8GB 的​​ Macbook Air 上;在更高功率的机器上应该更快。

m = np.random.random((20000,3,255,255))
h5f = h5py.File('data.h5', 'w')
h5f.create_dataset('data' , data=m)
h5f.close()
def access_data(d):
     for i in range(200):
         a = d[i*100:(i+1)*100]


h5f = h5py.File('data.h5', 'r')
%time access_data(h5f['data'])

CPU times: user 84.8 ms, sys: 35.4 s, total: 35.5 s
Wall time: 55.7 s

【讨论】:

  • 是的,我有 64 位 python,我运行了相同的代码,它说“在 284 秒内访问”。当您运行上述代码时,是否有可能将数组“m”存储在缓存中?我的电脑上还有 32 个处理器和一个 GPU。您认为此系统配置是否存在任何额外开销?
  • 不,它不是缓存,我只是在重新启动 python 后重新定时数据访问,这次有 1 分钟 4 秒,奇怪的是它对你来说运行得这么慢。你有固态硬盘吗?这对我来说可能会加快速度。无论如何,您可能想研究另一种类型的数据存储,如上面@svohara 所建议的 LMDB,hdf5 有点老派。
  • 我刚刚尝试从 SSD 加载,现在速度快了 30 倍。加载大约需要 8 秒。但是我有大量数据,无法将所有内容都存储在 SSD 上。从硬盘驱动器加载的最佳方式是什么?谢谢@maxymoo,我明白为什么我现在花了很多时间。
  • 不幸的是,我没有一个简单的答案。也许您可以编写一个脚本,根据需要将 hdf5 文件复制到 SSD,然后在完成后将其删除?否则可能会查看 LMDB,但我从未使用过它,所以我不能保证它。
  • 也就是说,这些天您可以花 200 美元左右购买 500GB SSD,因此考虑到您已经证明这将是高性能的,这实际上可能是您的最佳选择......而不是数周之久试图让其他东西发挥作用
猜你喜欢
  • 1970-01-01
  • 2021-07-14
  • 2019-08-02
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 2019-04-01
  • 2017-09-23
相关资源
最近更新 更多