将 HDF5 文件中的大型数据集读入 x_train 并在 keras 模型中使用

Posted

技术标签:

【中文标题】将 HDF5 文件中的大型数据集读入 x_train 并在 keras 模型中使用【英文标题】:Reading large dataset from HDF5 file into x_train and use it in keras model 【发布时间】:2021-08-11 15:36:47 【问题描述】:

我有一个包含 16000 个不同的 512x512 numpy 数组的大型 HDF5 文件。显然将文件读入内存会导致崩溃(文件总大小为 40 GB)。

我想将此数组加载到数据中,然后将数据拆分为 train_x 和 test_x。 Tha标签存储在本地。

我这样做只是创建了一个文件路径而不获取

    h5 = h5py.File('/file.hdf5', 'r')
    data = h5.get('data')

但是当我尝试将数据拆分为训练和测试时:

x_train= data[0:14000]
y_train= label[0:16000]
x_test= data[14000:]
y_test= label[14000:16000]

我得到了错误

MemoryError: 无法为形状为 (14000, 256, 256) 且数据类型为 float32 的数组分配 13.42 GiB

我想批量加载它们并训练一个 keras 模型,但显然以前的错误不允许我这样做

model.compile(optimizer=Adam(learning_rate =0.001),loss 
                          ='sparse_categorical_crossentropy',metrics =['accuracy'])
history= model.fit(x_train,y_train,validation_data= 
                         (x_test,y_test),epochs =32,verbose=1)

我该如何解决这个问题?

【问题讨论】:

您还在为这个问题寻找解决方案吗? 【参考方案1】:

首先,让我们描述一下你在做什么。 此语句为名为“data”的数据集返回一个 h5py 对象:data = h5.get('data')。它不会将整个数据集加载到内存中(这很好)。注意:该语句更典型地写成这样:data = h5.['data']。另外,我假设有一个类似的调用来获取“标签”数据集的 h5py 对象。

接下来的 4 个语句中的每一个都将根据索引和数据集返回一个 NumPy 数组。 NumPy 数组存储在内存中,这就是出现内存错误的原因。当程序执行x_train= data[0:14000] 时,需要 13.42 GiB 才能将数组加载到内存中。 (注意:错误意味着数组是 256x256,而不是 512x512。)

如果您没有足够的 RAM 来存储数组,您将不得不“做一些事情”来减少内存占用。要考虑的选项:

    将图像从 256x256(或 512x512)调整为更小的尺寸并保存在新的 h5 文件中 修改“数据”以使用整数而不是浮点数并保存在新的 h5 文件中 将图片数据写入.npy文件并批量加载 读取更少的图像,批量训练。

我写了一个与一些相关的问题的答案,该问题描述了 h5py 行为与训练和测试数据,以及如何随机化来自 .npy 文件的输入。这可能会有所帮助。看到这个答案:h5py writing: How to efficiently write millions of .npy arrays to a .hdf5 file?

顺便说一句,您可能希望随机选择测试和训练数据(而不是简单地选择前 14000 张图像进行训练,然后选择最后 2000 张图像进行测试)。另外,请检查您的索引是否有 y_train= label[0:16000]。我认为您会收到与 x_trainy_train 大小不匹配的错误。

【讨论】:

您好 kcw78,谢谢您的回答。你的前两个建议对我来说不可行,因为我需要保留这个数据集。我直接从本地文件加载我的标签(本地存储)。我有兴趣尝试您的最后两个建议,但我不知道如何。你能用 keras 中的 hoad train 上的虚拟代码来解释一下,并分批加载吗? 我提到了基于 cmets 的“批量训练”,我读过其他人需要帮助才能批量读取 HDF5。过去,.fit_generator() 函数与 Python 生成器一起使用来执行此操作。但是,TF 正在弃用.fit_generator()。如果您使用的是 TF 2.2.0(或更高版本),则必须使用 .fit() 方法。 .fit() 方法现在可以使用生成器输入并包括数据增强。您还可以使用tf.data.Dataset() 并遍历图像数据的切片。 非常感谢您的反馈,您是否知道我可以找到有关如何实施它的更多详细信息的来源。因为我不习惯这个? 我想你可能会问,所以做了一点谷歌搜索。 :-) 所以有一些很好的答案。从这些开始:Keras: load images batch wise for large dataset 和 How to split dataset into K-fold without loading the whole dataset at once? 如果这没有帮助,请谷歌“keras fit_generator”获取一些教程。您需要编写一个 Python 生成器函数来从 H5 文件中读取和加载图像数组的子集。 HI kcw,感谢您的指导,我找到了一种使用名为 h5imagegenerator 的 python 包的更快方法。基本上: train_generator = HDF5ImageGenerator( src='path/to/train.h5', X_key='images, y_key='labels, scaler=True, labels_encoding='hot', batch_size=32, mode='train') 这将基本上是实时将批量数据馈送到模型中,如果有兴趣甚至可以进行一些处理。那么您可以将其提供给您的模型:model.fit_generator(train_generator, validation_data=test_generator,...) 如果有人需要,这是一个解决方案

以上是关于将 HDF5 文件中的大型数据集读入 x_train 并在 keras 模型中使用的主要内容,如果未能解决你的问题,请参考以下文章

编写并将float数组附加到C ++中hdf5文件中的唯一数据集

读取存储在 HDF5 中的部分数据集 - python 2.7

高效地为具有内存限制的神经网络训练创建 HDF5 图像数据集

用于不适合内存的大型 hdf5 文件的 Keras 自定义数据生成器

将浮点数组写入和附加到 C++ 中 hdf5 文件中的唯一数据集

使用 h5py 编写大型 hdf5 数据集