代码之家  ›  专栏  ›  技术社区  ›  Ilya

python中的数据库与平面文件(需要速度,但无法放入内存)将与生成器一起用于NN培训

  •  1
  • Ilya  · 技术社区  · 8 年前

    出于分析目的,我正在处理一个相对较大的数据集(>400 GB),但内存有限(256 GB)。我正在使用python。到目前为止,我一直在对一部分数据使用pandas,但很明显,我需要一个允许我访问整个数据集数据的解决方案。

    关于数据的一点信息。现在,数据被隔离在一组平面文件上,这些平面文件是熊猫数据帧。文件由具有2个键的列组成。主键,我们称之为“record”,我希望能够使用它访问数据,还有一个主键,它基本上是主键中的行号。如中所示,我想访问记录“A”中的第2行。

    该数据集用于训练神经网络(keras/tf)。因此,任务是将整个集合按记录划分为train/dev/test,然后将数据传递给train/predict生成器(我实现keras.utils.Sequence(),我必须这样做,因为数据是可变长度的序列,需要为批学习填充)。

    考虑到我希望尽快将示例传递给NN,并且我无法将所有示例存储在内存中,我应该使用数据库(mongodb或sqlite或其他什么?)并根据需要查询示例,或者我应该继续将内容存储在平面文件中并加载/删除它们(希望python垃圾收集器能够工作)?

    另一个复杂的情况是,大约有300万条“记录”。目前,熊猫数据帧以大约10k的批量存储它们,但随机分割训练/测试/验证将对我有利,这意味着我确实需要能够访问特定批次中的一些记录,但不是所有记录。在pandas中,这似乎很难(据我所知,我需要读取整个平面文件,然后访问特定记录,因为我不知道数据位于文件的哪个块),另一方面,我也不认为生成3mil的单个文件是明智的。

    更复杂的是,模型相对简单,由于各种瓶颈,我无法在训练期间饱和我的计算能力,因此,如果我可以将训练流到多个不同的模型,这将有助于超参数搜索,因为否则我会浪费周期。

    您认为处理我的数据需求的正确(快速、简单)后端是什么?

    最好的

    伊利亚

    1 回复  |  直到 8 年前
        1
  •  1
  •   jrjames83    8 年前

    这是编写自定义生成器,然后使用Keras模型的一个很好的用例。安装发电机。这是我前几天与熊猫一起写的东西。

    请注意,我首先将主数据帧拆分为训练和验证拆分(合并的是我的原始数据帧),但您可能需要在磁盘上移动内容,并在生成器中进行选择时指定它们

    许多重塑和查找/加载都是针对我的问题定制的,但您可以看到这种模式。

    msk = np.random.rand(len(merged)) < 0.8
    train = merged[msk]
    valid = merged[~msk]
    
    def train_generator(batch_size):
        sample_rows = train[train['match_id'].isin(npf.id.values)].sample(n=batch_size)
        sample_file_ids = sample_rows.FILE_NAME.tolist()
        sample_data = [np.load('/Users/jeff/spectro/' + x.split(".")[0] + ".npy").T for x in sample_file_ids]
        sample_data = [x.reshape(x.shape[0], x.shape[1]) for x in sample_data]
        sample_data = np.asarray([x[np.random.choice(x.shape[0], 128, replace=False)] for x in sample_data])
        sample_labels = np.asarray([labels.get(x) for x in sample_file_ids])
    
        while True:
            yield (sample_data, sample_labels)
    

    无论何时调用,它都会返回batch\u大小的样本。Keras要求生成器返回一个长度为2的元组,其中第一个元素是预期形状中的数据(无论神经网络输入形状是什么),标签也映射到预期形状(N\u类或其他)。

    这里有另一个关于generator的相对有用的链接,它可以帮助您确定什么时候真正用尽了所有示例。我的生成器只是随机采样,但数据集足够大,我不在乎。

    https://github.com/keras-team/keras/issues/7729#issuecomment-324627132

    也不要忘记编写validation\u生成器,它从随机放置在其他位置的一组文件或数据帧中读取数据,以进行验证。

    最后,这里调用生成器:

    model.fit_generator(train_generator(32), 
                        samples_per_epoch=10000, nb_epoch=20, 
                        validation_data=valid_generator(32), validation_steps=500)
    

    根据keras版本的不同,您可能会发现arg名称略有变化,但通过一些搜索应该可以快速修复。

    推荐文章