Почему a.dot (b) быстрее, чем @ b, хотя Numpy рекомендует a @ b - PullRequest
0 голосов
/ 28 августа 2018

Согласно ответам на этот вопрос , а также согласно numpy , матричное умножение двумерных массивов лучше всего выполнять с помощью a @ b или numpy.matmul(a,b) по сравнению с a.dot(b).

Если a и b являются двумерными массивами, это матричное умножение, но с использованием matmul или @ b предпочтительнее.

Я сделал следующий тест и нашел противоположные результаты.

Вопросы: Есть ли проблема с моим тестом? Если нет, то почему Numpy не рекомендует a.dot(b), если он быстрее, чем a@b или numpy.matmul(a,b)?

бенчмарк использовал python 3.5 numpy 1.15.0.

$ pip3 list | grep numpy
numpy                         1.15.0
$ python3 --version
Python 3.5.2

Код эталона:

import timeit

setup = '''
import numpy as np
a = np.arange(16).reshape(4,4)
b = np.arange(16).reshape(4,4)
''' 
test = '''
for i in range(1000):
    a @ b
'''
test1 = '''
for i in range(1000):
    np.matmul(a,b)
'''
test2 = '''
for i in range(1000):
    a.dot(b)
'''

print( timeit.timeit(test, setup, number=100) )
print( timeit.timeit(test1, setup, number=100) )
print( timeit.timeit(test2, setup, number=100) )

Результаты:

test  : 0.11132473500038031
test1 : 0.10812476599676302
test2 : 0.06115105600474635

Добавить в результаты:

>>> a = np.arange(16).reshape(4,4)
>>> b = np.arange(16).reshape(4,4)
>>> a@b
array([[ 56,  62,  68,  74],
       [152, 174, 196, 218],
       [248, 286, 324, 362],
       [344, 398, 452, 506]])
>>> np.matmul(a,b)
array([[ 56,  62,  68,  74],
       [152, 174, 196, 218],
       [248, 286, 324, 362],
       [344, 398, 452, 506]])
>>> a.dot(b)
array([[ 56,  62,  68,  74],
       [152, 174, 196, 218],
       [248, 286, 324, 362],
       [344, 398, 452, 506]])

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

matmul и dot не делают одно и то же. Они ведут себя по-разному с 3D-массивами и скалярами. В документации может быть указано, что matmul предпочтительнее, потому что она более «понятна» и носит общий характер, не обязательно по соображениям производительности. Было бы хорошо, если бы в документации было более понятно, почему один из них предпочтительнее другого.

Как было отмечено @jpp, не обязательно верно, что производительность matmul на самом деле хуже.

0 голосов
/ 28 августа 2018

Ваша предпосылка неверна. Вы должны использовать матрицы большего размера для измерения производительности, чтобы избежать вызовов функций, затягивающих незначительные вычисления.

Используя Python 3.60 / NumPy 1.11.3, вы обнаружите, как объяснено здесь , что @ вызывает np.matmul и оба превосходят np.dot.

import numpy as np

n = 500
a = np.arange(n**2).reshape(n, n)
b = np.arange(n**2).reshape(n, n)

%timeit a.dot(b)        # 134 ms per loop
%timeit a @ b           # 71 ms per loop
%timeit np.matmul(a,b)  # 70.6 ms per loop

Также обратите внимание, что, как объяснено в документации, np.dot функционально отличается от @ / np.matmul. В частности, они отличаются обработкой матриц с размерами, превышающими 2.

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