Python pkl 文件的内存错误

0 投票
1 回答
1271 浏览
提问于 2025-04-18 00:28

我正在使用一个Python库来进行深度学习和神经网络的开发。我的电脑有16GB的内存,频率是1866 MHz。最开始我的输入数据文件太大了,所以我把它分成了几个小文件:

-rw-rw-r-- 1 jt jt 1.8G Mar 20 18:09 covarFile.pkl

这导致了以下错误:

Traceback (most recent call last): File "PYJT2/pp_dbn.py", line 69, in <module> go() File "PYJT2/pp_dbn.py", line 32, in go model = cPickle.load(open(CONTROL_DBN.INPUT, "rb")) MemoryError

因为这个文件只是一个包含多个numpy数组的numpy数组,所以我可以把它分成多个文件,然后在程序中动态地加载这些小的pickle文件,重新组合成一个大文件。

total 5.2G drwxrwxr-x 2 jt jt 4.0K Mar 20 18:15 ./ drwxrwxr-x 4 jt jt 4.0K Mar 20 18:15 ../ -rw-rw-r-- 1 jt jt 351M Mar 20 18:09 outfile-0.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:11 outfile-10.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:11 outfile-11.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:12 outfile-12.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:12 outfile-13.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:12 outfile-14.pkl -rw-rw-r-- 1 jt jt 2.3M Mar 20 18:12 outfile-15.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:09 outfile-1.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:09 outfile-2.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:10 outfile-3.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:10 outfile-4.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:10 outfile-5.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:10 outfile-6.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:11 outfile-7.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:11 outfile-8.pkl -rw-rw-r-- 1 jt jt 351M Mar 20 18:11 outfile-9.pkl

这个方法效果很好。但我现在的问题是,我有一个非常大的文件,导致了MemoryError,我不知道该如何进一步拆分。这个文件是一个theano张量变量,表示一个30,000x30,000的浮点数矩阵。我的问题有:

  1. 有没有办法将数据保存到多个pkl文件中,即使你不确定如何划分底层的数据结构?
  2. 在我们实验室的服务器上(48GB内存)运行这个会更好吗?还是这个内存错误和架构无关?
  3. 我现在这个太大的pkl文件是没用的吗?我希望不是,因为它花了我大约8个小时进行神经网络训练。
  4. 除了使用数据库,还有其他解决方案吗?如果可能的话,我非常希望使用数据库,因为我已经不得不把软件转移到多个服务器上,其中很多我没有管理员权限,安装其他东西非常麻烦。

1 个回答

1

首先,pkl格式并不适合保存二进制数据,而且在内存使用上也不太友好。因为在写入磁盘之前,它需要先把所有数据复制到内存中,这样就会导致内存使用量翻倍!你可以使用numpy.save和numpy.load来存储ndarray,这样就不会出现内存翻倍的问题。

关于Theano变量,我猜你在使用Theano的共享变量。默认情况下,当你通过get_value()获取它时,会复制数据。你可以使用get_value(borrow=True)来避免复制。

这两种方法结合起来,可以将内存使用量降低三倍。如果这还不够,或者你不想自己处理多个文件,我建议你使用pytables:http://www.pytables.org/。它可以让你在一个文件中存储一个比可用内存更大的ndarray,但它会提供一个类似于ndarray的对象,你可以像操作ndarray一样操作它。

撰写回答