如何最好地从磁盘读取大型数据集

数据挖掘 深度学习 喀拉斯 张量流 数据集
2022-03-15 04:40:12

我想在 keras 和 tensorflow 中使用 ResNet 解决任务。我的数据集很大,现在我正在考虑我的数据加载选项并试图确定哪个最适合任务。

关于数据集

  • x:-1.0...1.0 范围内的 200x700 单元格数组,我不想对它们进行下采样;它们当前保存为 matlab 或 npz 文件
  • y:标签由每个 x 两个浮点数组成。我有 120 万个 (x, y) 目前保存在 1000 个 npz 文件中,每个文件有 1GB,总计 1TB 数据。

问题:我的系统中没有 1TB RAM,所以我无法将所有数据保存在内存中。因此,我需要一个合适的解决方案来在训练我的神经网络时从磁盘读取我的数据。

到目前为止我找到的解决方案:

  • 将这些文件保存为图像并使用 keras dataset io "load_images_from_directory",缺点:我需要将图像保存在磁盘上,这可能需要超过 1TB 的空间。那么标签呢?加上可能从 0..1 到 -1..1 的额外预处理
  • tfrecords感觉有点矫枉过正,因为我的数据集并不是真正的结构化数据集,而只是 (array, label)
  • hdf 文件,这也更适用于结构化/分层数据。

我还想考虑的事情:

  • 我是按原样保存数据,还是需要保存随机批次?但据此,还应该在每个新纪元中对小批量进行洗牌。这意味着我保存文件的顺序和文件大小(例如,一个文件是一个小批量)并不重要——小批量无论如何都应该被打乱。
  • 稍后,我很可能还需要将整个项目转移到 pytorch,因此(kears/tensorflow 和 pytorch)都支持的数据存储可以为我节省一些时间。
  • 如果我将每个 (x,y) 样本存储为一个小的 .bin 文件,则该文件小于我磁盘的块大小,因此使用的磁盘大小超出了需要。

所以问题是:我的数据集/任务的优缺点是什么,因此我应该使用哪种数据加载?还有更多我还没有发现的选择吗?

1个回答

一种常见的方法是创建一个继承tf.keras.utils.Sequence. 这个类实现了一个__getitem__在你使用model.fit()method时调用的函数。在这种方法中,您只需一次加载一批,因此无需加载整个数据集。请参阅文档调用时也可以直接使用.npz文件__getitem__

随机播放数据

我是按原样保存数据,还是需要保存随机批次?

您将实现on_epoch_end()indices. 然后,当您加载.npz文件时,使用类似data[indices[i]]的方法将索引加载到i已洗牌的索引列表中。 on_epoch_end在每个 epoch 结束时通过.fit()方法调用,您也可以在__init__您的Sequence类中使用它来初始化 shuffle。

从 Keras 到 Pytorch

Pytorch 有类似的模块,称为torch.utils.data.Dataset. 转换很简单。请参阅本教程