大数据下使用python生成器按批次导入训练数据

预计阅读时间:10min

分批载入预处理方法一直都有在考虑,不过在之前的研究中数据量一直控制在可以接受的范围内,就拖着拖着始终没实现。但现在的研究中遇到了很大很大数据量的情况,一载入数据内存就崩溃了,没法拖了只能好好考虑一下。

当数据量较大时,直接将全部训练数据加载进内存是不实际的。老师的建议是在线生成训练数据,但考虑到生成训练数据同样比较耗时,因此考虑了一个偷懒的办法,效果上应该是相同的。

结合Keras中模型训练的fit_generator()方法,这里的主要想法是采用python生成器,将硬盘中的数据按批载入内存。采用这种办法的主要限制就是机器的计算能力以及硬盘容量,对内存的限制较小(由于生成器的特性)。

本文首先介绍python生成器的基本概念及用法,然后介绍分批导入数据的随机打散方法,最后结合前面两步实现利用python生成器分批导入数据。

感觉加载效率有点低,急需更高效的方法。。

目录

python生成器介绍

随机加载文件夹中的数据

利用生成器载入一批数据

总结

◆◆◆◆◆

1. python生成器介绍

一般来说,生成器是为迭代器产生数据的。最常用的range()实际上就是一个生成器,使用它可以迭代一个很大的序列,而且不用在内存中存储整个序列。

下面通过一个生成器函数介绍生成器的特点。

上面代码的输出为

生成器函数的关键字为yield而不是return,输出类别为生成器generator而不是列表list

接下去连续使用该对象两次

输出为

可以看见,在用完一次后,该对象变成了空,这是生成器的特点,因此不会占用过多内存。

再创建一次该对象,并迭代它,可以发现

输出为

可以发现,在迭代过后也变成了一个空对象。

我们总结如下:

生成器函数的返回关键字为yield

生成器对象用完即丢。

因此生成器函数很适合用于分批载入数据。

◆◆◆◆◆

2. 随机加载文件夹中的数据

首先给出我们的路径及部分文件列表如下图

总共文件数为149281,下面考虑随机加载其中的10个数据,主要难点在于获取这10个文件的文件名。

方法如下:

观察其打印结果

可以发现,我们确实随机地获取了10个不同的文件名,参数replace=False表明不会重复选择。之后的具体载入很好想到,不做介绍。

◆◆◆◆◆

3. 利用生成器按批次随机载入数据

先定义加载数据的函数以及我们的数据生成器函数。

使用及其结果如下,每次加载数据后都输入训练数据和标签的形状,生成器共会运行4000多次,并没有等它运行到最后。

从结果可以看出,基本实现了每次随机载入32个样本。

目前看来是没啥问题,这就实现了数据随机地分批载入内存。几百几千万的数据量都没事,就是计算速度慢得可怜。

◆◆◆◆◆

4. 总结

期望实现的功能是:

每次随机加载一个批次的数据,在当前文件夹内的所有数据都加载完一次以后进入下一轮,重新开始加载。

实验中目前没遇到问题,暂时有如下注意事项:

每进入一轮新的epoch都要重新获取一次所有的文件名,或者提前备份好文件名然后每次更新,不然一轮过后文件名都被删光了。

生成器注意在循环while中需要对数据进行初始化,防止出问题。

方法比较原始,而且有点慢。后面改进的一点是把训练数据和标签存到一个文件里,这样一组数据只用载入一次就够了,应该能快一点。有更好的方法欢迎给出建议。

用上面的方法在GPU上运行DNN的时候,对GPU的使用率太低了,原因应该是数据被分的太小了,导致数据载入的效率很低。虽然相比在CPU上的运行速度已经快了5倍左右,可是没有充分利用到GPU性能。

如果在使用上面方法的时候发现了问题或者发现它并没有实现上述功能,一定要及时提出。

◆◆◆◆◆

到这里,关于数据分批随机载入的讨论就告一段落,小伙伴们有神马想法的话,欢迎在下方留言~~

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20190122G1BPMU00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券