Python / Numpy MemoryError - PullRequest
       30

Python / Numpy MemoryError

20 голосов
/ 01 декабря 2010

По сути, я получаю ошибку памяти в python при попытке выполнить алгебраическую операцию над матрицей с нулевой точкой. Переменная u представляет собой большую матрицу типа double (в случае неудачи это матрица двойных чисел 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 ]

46 голосов
/ 01 декабря 2010

Перепишите на

p *= alpha
u += p

, и это займет намного меньше памяти.Принимая во внимание, что p = p*alpha выделяет новую матрицу для результата p*alpha, а затем отбрасывает старую p;p*= alpha делает то же самое на месте.

В общем, с большими матрицами, попробуйте использовать присваивание op=.

11 голосов
/ 01 декабря 2010

Еще один совет, который я нашел, чтобы избежать ошибок памяти, - это ручное управление сборкой мусора . Когда объекты удаляются или выходят из области видимости, память, используемая для этих переменных, не освобождается, пока не будет выполнена сборка мусора. Я обнаружил, что с некоторыми моими кодами, использующими большие массивы numpy, я получаю MemoryError, но этого я могу избежать, если я вставлю вызовы gc.collect () в соответствующих местах.

Эту опцию следует изучать только в том случае, если использование операторов стиля "op =" и т. Д. Не решит вашу проблему, поскольку, вероятно, не самая лучшая практика кодирования - везде использовать gc.collect ().

6 голосов
/ 01 декабря 2010

Ваша матрица имеет 288x288x156 = 12 939 264 записей, что для double может составить 400 МБ в памяти. numpy выброс MemoryError в вас просто означает, что в вызванной вами функции память, необходимая для выполнения операции, была недоступна из ОС.

Если вы можете работать с разреженными матрицами, это может сэкономить вам много памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...