web-dev-qa-db-ja.com

Python / Numpy MemoryError

基本的に、numpy行列で代数演算を実行しようとすると、pythonでメモリエラーが発生します。変数uは、(失敗した場合は)私はこの巨大な場合にのみこのエラーを受け取りますが、他の大きな行列でこれを行うことができますが、これほど大きくはありません)ここに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は単なるdoubleですが、urは上記の大きな行列(両方とも同じサイズ)です。

特にPythonでのメモリエラーについてはあまり知りません。これを解決するための洞察/ヒントは大歓迎です!

ありがとう

22
tylerthemiler

書き換える

p *= alpha
u += p

そして、これははるかに少ないメモリを使用します。一方、p = p*alphap*alphaの結果にまったく新しいマトリックスを割り当て、古いpを破棄します。 p*= alphaは同じことを行います。

一般に、大きな行列では、op=割り当てを使用してみてください。

48
luispedro

メモリエラーを回避することがわかったもう1つのヒントは、手動で garbage collection を制御することです。オブジェクトが削除されるか、スコープから外れると、これらの変数に使用されているメモリは、ガベージコレクションが実行されるまで解放されません。いくつかのコードで大きなnumpy配列を使用すると、MemoryErrorが発生しますが、適切な場所にgc.collect()の呼び出しを挿入すると、これを回避できることがわかりました。

"op ="スタイル演算子などを使用しても問題が解決しない場合にのみ、このオプションを検討する必要があります。おそらく、gc.collect()をどこにでも呼び出すのが最良のコーディング方法ではないからです。

11
DaveP

マトリックスには288x288x156 = 12,939,264エントリがあり、doubleの場合はメモリ内で400MBに達する可能性があります。 numpyMemoryErrorを投げるということは、関数を呼び出したときに、操作を実行するために必要なメモリがOSから利用できなかったことを意味します。

スパース行列を使用できる場合、これにより多くのメモリを節約できます。

6