Python/Numpy 内存错误
基本上,我在用Python对一个numpy矩阵进行代数运算时遇到了内存错误。变量u
是一个很大的矩阵(在出错的情况下,它是一个288x288x156的双精度矩阵。我只在这个特别大的情况下遇到这个错误,但在其他大矩阵上是可以正常操作的,只是这个太大了)。这里是Python的错误信息:
Traceback (most recent call last):
File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc
t perim erosion flattop\SwSim.py", line 121, in __init__
self.mainSimLoop()
File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc
t perim erosion flattop\SwSim.py", line 309, in mainSimLoop
u = solver.solve_cg(u,b,tensors,param,fdHold,resid) # Solve the left hand si
de of the equation Au=b with conjugate gradient method to approximate u
File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc
t perim erosion flattop\conjugate_getb.py", line 47, in solv
e_cg
u = u + alpha*p
MemoryError
u = u + alpha*p
是出错的那行代码。
alpha
只是一个双精度数,而u
和r
都是上面提到的那种大矩阵(大小相同)。
我对Python中的内存错误了解不多。如果能给我一些解决这个问题的建议或见解,我会非常感激!
谢谢
3 个回答
7
你的矩阵有288x288x156=12,939,264个数据,这样的话,如果用double
类型存储的话,可能会占用大约400MB的内存。numpy
给你抛出一个MemoryError
的错误,意思就是你调用的那个函数在运行时,操作所需的内存没有从操作系统那里得到。
如果你能使用稀疏矩阵,这样可能会节省很多内存。
12
我发现避免内存错误的另一个小窍门是手动控制垃圾回收。当一些对象被删除或者超出作用域时,这些变量占用的内存不会立即释放,直到进行垃圾回收。我在使用大型numpy数组的代码中遇到过内存错误(MemoryError),但如果在合适的地方插入gc.collect()的调用,就可以避免这个问题。
不过,只有在使用“op=”风格的操作符等方法无法解决问题时,才应该考虑这个选项,因为在代码中到处调用gc.collect()可能不是最好的编程习惯。
52
重写为
p *= alpha
u += p
这样做会使用更少的内存。因为 p = p*alpha
会为 p*alpha
的结果分配一个全新的矩阵,然后丢弃旧的 p
; 而 p*= alpha
则是在原地进行同样的操作。
总的来说,对于大矩阵,尽量使用 op=
这种赋值方式。