读取大型 HDF5 文件

问题描述 投票:0回答:3

我是使用 HDF5 文件的新手,我正在尝试读取形状为

(20670, 224, 224, 3)
的文件。每当我尝试将 hdf5 的结果存储到列表或其他数据结构中时,要么需要很长时间才能中止执行,要么导致计算机崩溃。我需要能够读取 3 组 hdf5 文件,使用它们的数据,操作它,用它来训练 CNN 模型并做出预测。

任何有关阅读和使用这些大型 HDF5 文件的帮助将不胜感激。

目前,这就是我读取 hdf5 文件的方式:

db = h5py.File(os.getcwd() + "/Results/Training_Dataset.hdf5")
training_db = list(db['data'])
python conv-neural-network hdf5 h5py
3个回答
3
投票

崩溃可能意味着您的内存不足。就像 Vignesh Pillay 所建议的那样,我会尝试对数据进行分块并一次处理其中的一小部分。如果您使用 pandas 方法read_hdf,您可以使用迭代器和 chunksize 参数来控制分块:

import pandas as pd
data_iter = pd.read_hdf('/tmp/test.hdf', key='test_key', iterator=True, chunksize=100)
for chunk in data_iter:
   #train cnn on chunk here
   print(chunk.shape)

注意这需要 hdf 为表格格式


2
投票

我的答案于 2020 年 8 月 3 日更新,以反映您添加到问题中的代码。 正如@Tober 指出的,您的内存不足。读取形状为(20670,224,224,3)的数据集将成为3.1G实体的列表。如果您读取 3 个图像集,则需要更多 RAM。 我假设这是图像数据(可能是 20670 个形状为 (224, 224, 3) 的图像)? 如果是这样,您可以使用

h5py
tables
(Pytables) 读取切片中的数据。 这会将数据作为 NumPy 数组返回,您可以直接使用它(无需操作到不同的数据结构)。

基本流程如下所示:

with h5py.File(os.getcwd() + "/Results/Training_Dataset.hdf5",'r') as db:
     training_db = db['data']
     # loop to get images 1 by 1
     for icnt in range(20670) :
         image_arr = training_db [icnt,:,:,:}

     # then do something with the image

您还可以通过将第一个索引设置为一个范围(例如

icnt:icnt+100
)来读取多个图像,然后适当地处理循环。


2
投票

您的问题是由于内存不足而出现的。因此,虚拟数据集在处理像您这样的大型数据集时会派上用场。虚拟数据集允许通过接口层将多个真实数据集映射到单个可切片数据集。您可以在这里阅读有关它们的更多信息https://docs.h5py.org/en/stable/vds.html

我建议您一次从一个文件开始。首先,创建现有数据的虚拟数据集文件,例如

with h5py.File(os.getcwd() + "/Results/Training_Dataset.hdf5", 'r') as db:
     data_shape = db['data'].shape
     layout = h5py.VirtualLayout(shape = (data_shape), dtype = np.uint8)
     vsource = h5py.VirtualSource(db['data'])
     with h5py.File(os.getcwd() + "/virtual_training_dataset.hdf5", 'w', libver = 'latest') as file:
         file.create_virtual_dataset('data', layout = layout, fillvalue = 0)
     

这将创建现有训练数据的虚拟数据集。现在,如果您想操作数据,您应该以

r+
模式打开文件,例如

with h5py.File(os.getcwd() + "/virtual_training_dataset.hdf5", 'r+', libver = 'latest') as file:
    # Do whatever manipulation you want to do here

我想建议的另一件事是确保切片时的索引是

int
数据类型,否则你会收到错误。

© www.soinside.com 2019 - 2024. All rights reserved.