Почему векторизованный Pinv медленнее, чем невекторизованный? - PullRequest
2 голосов
/ 10 марта 2019

У меня есть десять 6000 x 784 матриц.Если я запускаю np.cov и затем pinv для каждого из них, общее время составляет:

%timeit for n in range(10): pinv(np.cov(A,rowvar = False))
1.64 s ± 78.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Если я вместо этого зациклю np.cov и вычислю pinv 3D-стека, я получу:

%timeit for n in range(10): dd[n] = np.cov(A,rowvar = False)
485 ms ± 18 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit pinv(dd)
4.59 s ± 369 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Почему pinv в 3D такой медленный?

Что я могу сделать, чтобы вычислить np.cov стека и соответствующего pinv?

1 Ответ

1 голос
/ 11 марта 2019

Это связано с реализацией.Ограничивающим шагом является numpy matmul.Сначала я думал, что SVD является ограничивающим шагом, но он масштабируется линейно (~ 130 мс на итерацию, 1,3 с для пакета из десяти).

Вот некоторые части профилирования:

1 вызов (ваш первый фрагмент)

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.131    0.131    0.131    0.131 linalg.py:1299(svd)
    1    0.011    0.011    0.011    0.011 {built-in method numpy.core.multiarray.matmul}
    1    0.003    0.003    0.144    0.144 <ipython-input-76-2a63f1c84429>:1(pinv)

1 вызов пакета из 10 (ваш второй фрагмент)

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    2.952    2.952    2.952    2.952 {built-in method numpy.core.multiarray.matmul}
    1    1.265    1.265    1.265    1.265 linalg.py:1299(svd)
    1    0.026    0.026    4.266    4.266 <ipython-input-76-2a63f1c84429>:1(pinv)

Возможно, существует внутренняя проблема C-упорядочения (но об этом должны упоминать недавние версии с клочками), или это просто неэффективно в этом случае ... Кратко пытался перейти на интерфейс BLAS напрямуюиспользуя scipy реализацию , но она работает только с двумерными матрицами.Эти проблемы (что matmul медленный) на самом деле были подняты в другом месте .

Итог, сделайте это не векторизованным или попробуйте использовать другие реализации.Иногда самым быстрым способом умножения матриц является использование функций eigen, но я никогда не пробовал это в многомерной задаче.

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