2010-11-30 2 views
16

기본적으로 numpy 행렬에서 대수 연산을 수행하려고하면 파이썬에서 메모리 오류가 발생합니다. 변수 u은 두 배의 큰 매트릭스입니다 (실패한 경우 288x288x156 매트릭스의 두 배입니다.이 큰 경우에만이 오류가 발생하지만 다른 큰 행렬에서는이 오류를 만날 수 있습니다.) 여기 파이썬 오류는 다음과 같습니다Python/Numpy MemoryError

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은 단지 두 배이며, ur은 위에 설명 된 큰 매트릭스입니다 (둘 다 같은 크기 임).

특히 파이썬에서 메모리 오류에 대해 많이 알지 못합니다. 이것에 대한 통찰력/팁은 매우 높이 평가 될 것입니다!

감사

답변

39

재 작성

p *= alpha 
u += p 

이 훨씬 적은 메모리를 사용합니다

합니다. p = p*alphap*alpha의 결과에 대해 완전히 새로운 행렬을 할당 한 다음 이전 p을 버립니다. p*= alpha도 같은 일을합니다.

일반적으로 큰 행렬의 경우 op= 지정을 사용해보십시오.

+0

이것은 매우 도움이됩니다. – tylerthemiler

5

귀하의 행렬 double 메모리에 400메가바이트에 나올 수 288x288x156 = 12,939,264 항목을 가지고 있습니다. numpyMemoryError에 던지면 작동을 수행하는 데 필요한 메모리를 OS에서 사용할 수 없다는 것을 의미합니다.

스파 스 매트릭스로 작업 할 수 있으면 많은 메모리를 절약 할 수 있습니다.

+2

하지만 내 컴퓨터에는 24GB의 RAM이 있습니다 ... Windows에서 더 많은 것을 사용할 수있는 방법이 있습니까 ?? 편집 : 우리가 사용하는 파이썬 버전은 어떤 이유로 32 비트입니다./Edit2 : 불행히도 스파 스 매트릭스는 옵션이 아닙니다. 모든 요소에 값이 있으므로 (문제와 같은 열 방정식). – tylerthemiler

+0

감사합니다. 메모리에서 일부 항목을 지우고 이제 이것을로드 할 수 있습니다. – tylerthemiler

+0

@tylerthemiler : 비공식 64 비트 빌드 사용 http://www.lfd.uci.edu/~gohlke/pythonlibs/ – endolith

9

메모리 오류를 피하기 위해 찾은 또 다른 팁은 garbage collection을 수동으로 제어하는 ​​것입니다. 개체가 삭제되거나 범위를 벗어나면 이러한 변수에 사용되는 메모리는 가비지 수집이 수행 될 때까지 해제되지 않습니다. 내가 MemoryError 얻을 큰 numpy 배열을 사용하여 내 코드 중 일부를 발견했다 그러나 적절한 장소에서 gc.collect() 호출을 삽입하면이 피할 수 있습니다.

"op ="스타일 연산자를 사용하여 문제를 해결하지 못하는 경우이 옵션을 조사해야합니다. 왜냐하면 gc.collect()가 모든 곳에서 호출하는 것이 가장 좋은 코딩 방법은 아니기 때문입니다.

+0

그래, 나는 그 일을 끝내었다. 제안 해 주셔서 감사합니다. – tylerthemiler

+0

MemoryError가 가비지 수집을 자동으로 트리거하지 않는 이유는 무엇입니까? – endolith

+2

@endolith 당신의'malloc()'이 실패 할 때 메모리를 일시 정지하고 정리할 수없는 것과 같은 이유로 - 너무 늦었을 때 _ 실패했습니다. 그런 다음 다시 GC를 시도하고 다시 시도 할 수 있지만 NumPy 개발자는 반창고에 의존하는 것보다는 코드를 수정하는 편이 낫다고 생각합니다. – PythonNut