我是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'])
崩溃可能意味着内存不足。就像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为表格格式
我的答案更新了2020-08-03,以反映您添加到问题中的代码。正如@Tober所指出的,你的记忆力正在耗尽。读取形状的数据集(2067022243(将变成3.1G实体的列表。如果您读取3个图像集,则需要更多的RAM。我假设这是图像数据(可能是20670个形状的图像(2242243((?如果是,则可以使用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
(来读取多个图像,然后适当地处理循环。
您的问题是由于内存不足而产生的。因此,虚拟数据集在处理像您这样的大型数据集时派上了用场。虚拟数据集允许通过接口层将多个真实数据集映射到一个单一的、可切片的数据集中。你可以在这里阅读更多关于他们的信息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
数据类型,否则会出现错误。