Я хочу решить задачу наименьших квадратов, используя некоторый итерационный решатель. Мне нужны разреженные матрицы, и у Сципи есть функции scipy.sparse.linalg.lsqr()
и scipy.sparse.linalg.lsmr()
. Однако, если я помещу их в цикл, потребление памяти возрастает. Так что, похоже, где-то произошла утечка памяти.
Вот пример того, как это выглядит:
for i in range(0,200):
print(i)
tmp = sparse.linalg.lsmr(A_tot, np.asarray(b_tot.toarray().squeeze()))
delta = tmp[0]
Кто-нибудь знает, как это исправить или есть другие решатели? Я пробовал как lsqr
, так и lsmr
.
Вот связанная ссылка , но она с 2014 года и помечена как решенная. Однако это не мой опыт.
Когда я пробую следующий код, используемая память стабильна (не увеличивается):
Этот код воспроизводит ошибку:
A_tot2 = sparse.rand(128365, 535, density=0.05)
b_tot2 = sparse.rand(128365,1)
pdb.set_trace()
i = 0
while True:
i += 1
start = time.time()
tmp = sparse.linalg.lsmr(A_tot2, b_tot2.toarray().squeeze())
stop = time.time()
print("Time: " + str(stop-start))
delta = tmp[0]
print(i)
# pdb.set_trace()
Поведение памяти можно увидеть на рисунке ниже. Я также попытался сделать шаг вперед, используя pdb.set_trace()
с тем же поведением. Память увеличивается, поскольку цикл повторяется, и он падает и снова начинает увеличиваться. Над тем, где он стоит 15%
, есть маленький зигзагообразный рисунок. Это было для density=0.01
.
РЕДАКТИРОВАТЬ:
Я только что добавил gc.collect()
внизу for-loop
, и это решило проблему. Но что именно происходит? Я не очень понимаю, как работает Python.
Коллега предположил, что в scipy.linalg.lsqr()
могут быть циклические ссылки, которые препятствуют освобождению памяти.