基本的に、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ですが、u
とr
は上記の大きな行列(両方とも同じサイズ)です。
特にPythonでのメモリエラーについてはあまり知りません。これを解決するための洞察/ヒントは大歓迎です!
ありがとう
書き換える
p *= alpha
u += p
そして、これははるかに少ないメモリを使用します。一方、p = p*alpha
はp*alpha
の結果にまったく新しいマトリックスを割り当て、古いp
を破棄します。 p*= alpha
は同じことを行います。
一般に、大きな行列では、op=
割り当てを使用してみてください。
メモリエラーを回避することがわかったもう1つのヒントは、手動で garbage collection を制御することです。オブジェクトが削除されるか、スコープから外れると、これらの変数に使用されているメモリは、ガベージコレクションが実行されるまで解放されません。いくつかのコードで大きなnumpy配列を使用すると、MemoryErrorが発生しますが、適切な場所にgc.collect()の呼び出しを挿入すると、これを回避できることがわかりました。
"op ="スタイル演算子などを使用しても問題が解決しない場合にのみ、このオプションを検討する必要があります。おそらく、gc.collect()をどこにでも呼び出すのが最良のコーディング方法ではないからです。
マトリックスには288x288x156 = 12,939,264エントリがあり、double
の場合はメモリ内で400MBに達する可能性があります。 numpy
がMemoryError
を投げるということは、関数を呼び出したときに、操作を実行するために必要なメモリがOSから利用できなかったことを意味します。
スパース行列を使用できる場合、これにより多くのメモリを節約できます。