Я использую cosine_similarity
на матрицах и задавался вопросом о необходимой памяти. Итак, я создал небольшой фрагмент:
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
n = 10000
mat = np.random.random((n, n))
sim = cosine_similarity(mat)
С ростом n
, конечно, матрица становится намного больше. Я ожидаю, что размер матрицы будет n**2 * 4
байтов, что означает:
- n = 10000: 400 МБ
- n = 15 000: 900 МБ
- n = 20000: 1,6 ГБ
Я наблюдаю ПУТЬ больше использования памяти. Моя система имеет 16 ГБ, и она падает при n = 20000. Почему это так?
Что я пробовал
Я видел Как мне профилировать использование памяти в Python? . Поэтому я установил memory-profiler и выполнил
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
@profile
def cos(n):
mat = np.random.random((n, n))
sim = cosine_similarity(mat)
return sim
sim = cos(n=10000)
с
python3 -m memory_profiler memory_usage_cosine_similarity.py
и получил
Line # Mem usage Increment Line Contents
================================================
4 62.301 MiB 62.301 MiB @profile
5 def cos(n):
6 825.367 MiB 763.066 MiB mat = np.random.random((n, n))
7 1611.922 MiB 786.555 MiB sim = cosine_similarity(mat)
8 1611.922 MiB 0.000 MiB return sim
но я запутался здесь в большинстве вещей:
- Почему
@profile
на 62,301 МБ (такой большой)?
- Почему
mat
825 МБ вместо 400 МБ?
- Почему
sim
отличается от mat
?
- Почему
htop
показывает увеличение с 3,1 до 5,5 ГБ (2,4 ГБ), но профилировщик говорит, что ему нужно всего 1,6 ГБ?
Игнорирование этого, вот что происходит, когда я увеличиваю n:
n cosine_similarity
1000 11.684 MiB
2000 (x2) 37.547 MiB (x 3.2)
4000 (x4) 134.027 MiB (x11.5)
8000 (x8) 508.316 MiB (x43.5)
Итак, cos cos__sincityity показывает примерно O (n ** 1.8) поведение.
Если я не использую n x n матриц, но вместо этого n x 100, я получаю похожие числа:
n cosine_similarity
1000 9.512 MiB MiB
2000 (x2) 33.543 MiB (x 3.5)
4000 (x4) 127.152 MiB (x13.4)
8000 (x8) 496.234 MiB (x52.2)