Рубрики
Без рубрики

Обновление Matrix Matrix – NP.Matmul () и @ [Ultimate Guide]

Вы когда-нибудь пытались размножаться два насыпных массива вместе и получили результат, который вы не ожидали? Функции умножения Numpy могут быть запутаны. В этой статье мы объясним все, что вам нужно знать о матрице умножения в Numpy. Посмотрите видео, в котором я иду по всей статье: https://youtu.be *erdi5mtyseq Для выполнения матрицы умножения между … NP.Matmul () и @ [Ultimate Guide] Подробнее »

Автор оригинала: Adam Murphy.

Вы когда-нибудь пытались умножить два Numpy Массивы вместе и получили результат, который вы не ожидали? Функции умножения Numpy могут быть запутаны. В этой статье мы объясним все, что вам нужно знать о Матричное умножение в Numpy.

Посмотрите видео, в котором я пробую статью подробно:

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

# Python >= 3.5
# 2x2 arrays where each value is 1.0
>>> A = np.ones((2, 2))
>>> B = np.ones((2, 2))

>>> A @ B
array([[2., 2.],
      [2., 2.]]) 

Далее np.matmul ()

>>> np.matmul(A, B)
array([[2., 2.],
      [2., 2.]]) 

И наконец np.dot ()

>>> np.dot(A, B)
array([[2., 2.],
      [2., 2.]]) 

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

Что такое умножение матрицы?

Если вы не знаете, что такое умножение Matrix, или почему это полезно, проверьте Эта короткая статья Отказ

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

Теперь вы знаете, почему это так важно, давайте доберемся до кода.

numpy.array – поведение по умолчанию

Поведение по умолчанию для любой математической функции в Numpy – это элементные операции. Это одно преимущество NUMPY ARMPY имеет более стандартные списки Python.

Допустим, у нас есть список Python и хочу добавить 5 на каждый элемент. Для этого нам придется либо написать для цикла или в списке.

# For loop - complicated and slow
>>> a = [1, 1, 1, 1]
>>> b = []
>>> for x in a:
        b.append(x + 5)
>>> b
[6, 6, 6, 6]

# List comprehension - nicer but still slow
>>> a = [1, 1, 1, 1]
>>> b = [x + 5 for x in a]
>>> b
[6, 6, 6, 6]

Оба из них медленные и громоздкие.

Вместо этого, если А Одноместный массив намного проще

>>> A = np.array([1, 1, 1, 1])
>>> B = A + 5
>>> B
array([6, 6, 6, 6])

И намного намного быстрее

# Using a list of length 1,000,000 for demonstration purposes
In [1]: a = list(range(100000))

In [2]: b = []

In [3]: %timeit for x in a: b.append(x + 5)
28.5 ms ± 5.71 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [4]: b = []

In [5]: %timeit b = [x+5 for x in a]
8.18 ms ± 235 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [6]: A = np.array(a)

In [7]: %timeit B = A + 5
81.2 µs ± 2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Использование массивов составляет 100x быстрее, чем список списков и почти 350x быстрее, чем для петлей.

Если мы хотим умножить каждый элемент на 5, мы делаем то же самое

>>> C = A * 5
array([5, 5, 5, 5])

То же самое относится и к вычитанию и разделению.

Каждая математическая операция действует элемент мудрым по умолчанию. Так что, если вы умножаете два тазобельника вместе, Numpy предполагает, что вы хотите сделать умножение элемента.

>>> np.ones((2, 2)) * np.array([[1, 2], [3, 4]])
array([[1., 2.],
      [3., 4.]])

Основная особенность матричного умножения состоит в том, что матрица с размером (М х н) можно умножить на другое с измерением (n x p) Для некоторых целых чисел м , N и P Отказ Если вы попробуете это с помощью * , это ValueError.

# This would work for matrix multiplication
>>> np.ones((3, 2)) * np.ones((2, 4))
ValueError: operands could not be broadcast together with shapes (3,2) (2,4)

Это происходит потому, что Numpy пытается сделать элемент мудрого умножения, не умножения матрицы. Он не может сделать элемент мудрые операции, потому что первая матрица имеет 6 элементов, а второй имеет 8.

Элемент WISE операций – невероятно полезная функция. Вы будете использовать его много раз в вашей карьере. Но вы также захотите делать умножение матрицы в какой-то момент.

Возможно, ответ находится в использовании numpy.matrix учебный класс?

Numpy.matrix.matrix.

Существует подкласс Numpy Array под названием numpy.matrix Отказ Это работает аналогично матрицам, которые мы знаем из математического мира. Если вы создаете некоторые numpy.matrix экземпляры и звонок * Вы будете выполнять умножение матрицы

# Element wise multiplication because they are arrays
>>> np.array([[1, 1], [1, 1]]) * np.array([[1, 2], [3, 4]])
array([[1, 2],
      [3, 4]])

# Matrix multiplication because they are matrices
>>> np.matrix([[1, 1], [1, 1]]) * np.matrix([[1, 2], [3, 4]])
matrix([[4, 6],
        [4, 6]])

Но это вызывает некоторые проблемы.

Например, если у вас есть 20 матриц в вашем коде и 20 массивах, он очень быстро будет запутаться. Вы можете умножить два вместе, ожидая, что один результат, но получить другой. * Оператор перегружен. Это приводит к тому, что код трудно читать полный ошибок.

Мы чувствуем, что это одна из причин, почему Numpy Docs V1.17 Теперь сказать:

Больше не рекомендуется использовать этот класс даже для линейной алгебры. Вместо этого используйте регулярные массивы. Класс может быть удален в будущем.

Вы можете увидеть это рекомендовано в других местах вокруг Интернета. Но, поскольку Numpy больше не рекомендует этому, мы не будем обсуждать его дальше.

Теперь давайте посмотрим на некоторые другие методы.

Другие методы умножения матрицы

Существует 2 метода умножения матрицы, которые включают в себя вызовы функций.

Давайте начнем с того, что мы не рекомендуем

numpy.dot

Как следует из названия, это вычисляет Точечный продукт двух векторов. Требуется два аргумента – массивы, которые вы хотели бы выполнить точечный продукт. Существует третий дополнительный аргумент, который используется для повышения производительности, которые мы не будем охватывать.

>>> vec1 = np.array([1, 2, 3])
>>> vec2 = np.array([3, 2, 1])

# Dot product is (1*3) + (2*2) + (3*1) = 3 + 4 + 3 = 10
>>> np.dot(vec1, vec2)
10

Если вы используете эту функцию с парой 2D векторов, он делает умножение матрицы.

>>> three_by_two = np.ones((3, 2))
>>> two_by_four = np.ones((2, 4))
>>> output = np.dot(three_by_two, two_by_four)

# We expect shape (3,2) x (2,4) = shape (3,4)
>>> output.shape
(3, 4)

# Output as expected from matrix multiplication
>>> output
array([[2., 2., 2., 2.],
      [2., 2., 2., 2.],
      [2., 2., 2., 2.]])

Этот метод работает, но не рекомендуется нами или Numpy Отказ Одна из причин, потому что в математике «Точечный продукт» имеет определенное значение. Это сильно отличается от умножения. Смущает эти математики, чтобы увидеть np.dot () Возвращающие значения, ожидаемые от умножения.

Есть времена, когда вы можете, и должны использовать эту функцию (например, если вы хотите рассчитать точечный продукт), но, для краткости, мы ссылаемся на Официальные документы Отказ

Таким образом, вы не должны использовать эту функцию для умножения матрицы, а как насчет другого?

Numpy.matmul

Это numpy Мат рикс Мул Функция Tiplication. Призывая его двумя матрицами, так как первые и второе аргументы вернут матричный продукт.

>>> three_by_two = np.ones((3, 2))
>>> two_by_four = np.ones((2, 4))
>>> output = np.matmul(three_by_two, two_by_four)

# Shape as expected from matrix multiplication
>>> output.shape
(3, 4)

# Output as expected from matrix multiplication
>>> output
array([[2., 2., 2., 2.],
      [2., 2., 2., 2.],
      [2., 2., 2., 2.]])

Имя функции ясно, и это довольно легко читать. Это огромное улучшение на np.dot () Отказ Даже некоторые расширенные функции, которые вы можете использовать с этой функцией. Но для 90% случаев это должно быть всем, что вам нужно. Проверьте Документы для получения дополнительной информации.

Так что это метод, который мы должны использовать всякий раз, когда мы хотим сделать умножение Numpy Matrix? Нет. Мы сохранили лучшее «до последнего».

Python @ Оператор

@ Оператор был представлен основным синтаксисом Python с 3.5, благодаря Pep 465 Отказ Его единственная цель – решить проблему матричного умножения. Это даже приходит с хорошим мнемоническим – @ это * для м На Слабо.

Одна из главных причин для введения этого было потому, что в сообществе не было консенсуса за то, как правильно написать умножение матрицы. звездочка * Символ соревновался за две операции:

  • элемент мудром умножения, а также
  • Умножение матрицы.

Решения были функционируемыми вызовами, которые работали, но не очень нечитаемыми и трудно для начинающих понять. Плюс исследования предложили, что умножение матрицы было чаще, чем // ( Этаж ) разделение. И все же это имеет свой собственный синтаксис.

Это необычно, что @ Был добавлен к ярудному языку Python, когда он используется только с определенными библиотеками. К счастью, единственное время, которое мы используем @ для Функция декоратора с. Так что вы вряд ли запутались.

Он работает именно так, как вы ожидаете матричных умножения на, поэтому мы не чувствуем особого объяснения.

# Python >= 3.5
# 2x2 arrays where each value is 1.0
>>> A = np.ones((2, 2))
>>> B = np.ones((2, 2))

>>> A @ B
array([[2., 2.],
      [2., 2.]]) 

Одно следует отметить, что, в отличие от математики, Matrix умножения с использованием @ это Оставил ассоциативный.

Если вы привыкли видеть

AZx

Где a и z – это матрицы, а x – это вектор, вы ожидаете, что операция будет выполняться в правом ассоциативной ассоциативной основе I.E.

A(Zx)

Итак, вы выполняете ZX Сначала и тогда A (ZX) Отказ Но все математические операции Python остаются ассоциативной.

>>> a + b + c = (a + b) + c
>>> a / b / c = (a / b) / c
>>> a * b - c = (a * b) - c

Численный пример

# Right associative
>>> 2 * (3 - 4)
-2

# Left associative
>>> (2 * 3) - 4
2

# Python is left associative by default
>>> 2 * 3 - 4
2

Не было консенсуса, как это было лучше. Поскольку все остальное в Python остается ассоциативным, сообщество решило сделать @ Оставил ассоциативность тоже.

Так что вы должны использовать @ Всякий раз, когда вы хотите сделать размножение Numpy Matrix?

Что вы должны выбрать?

В сообществе есть некоторые дебаты, касающиеся того, какой метод лучше. Однако мы считаем, что вы всегда должны использовать @ оператор. Он был введен на язык, чтобы решить точную проблему умножения матрицы. Подробно много причин в Pep 465 Что касается того, почему @ – лучший выбор.

Основная причина, по которой мы оказываем это, состоит в том, что намного проще читать при умножении двух или более матриц вместе. Допустим, мы хотим рассчитать ABCD Отказ У нас есть два варианта

# Very hard to read
>>> np.matmul(np.matmul(np.matmul(A, B), C), D)

# vs

# Very easy to read
>>> A @ B @ C @ D

Этот короткий пример демонстрирует мощность @ оператор. Математические символы напрямую переводят на ваш код, есть меньше символов, чтобы ввести в тип, и гораздо проще читать.

К сожалению, если вы используете старую версию Python, вам придется придерживаться np.matmul () Отказ

Резюме

Теперь вы знаете, как умножить два матрица вместе и почему это так важно для вашего путешествия Python.

Если сомневаюсь, помните, что @ для м На RIX умножение.

Куда пойти отсюда?

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

Хорошее место, чтобы получить тщательное образование Numpy – это всеобъемлющий Tinxter Numpy Tourcial в этом блоге и нашу новую книгу Coffee Break Numpy Numpy.

Проверьте следующие функции для получения дополнительной информации:

  • np.vdot – Комплекс-сопряженный точечный продукт
  • np.tensardot – сумма продуктов над произвольными осями
  • np.einsum – Конвенция о суммировании Эйнштейна

ИСПОЛЬЗОВАННАЯ ЛИТЕРАТУРА

Вы хотите стать Numpy Master? Проверьте нашу интерактивную книгу головоломки Coffe Break Numpy И повысить свои навыки науки о данных! (Ссылка Amazon открывается на новой вкладке.)

Ежедневная научная головоломка данных

[Python] Импорт Numpy как NP

# Графика Данные a = [[1, 1], [1, 0]] Aralay (A)

# растягивающие векторы B = [[2, 0], [0, 2]] b.Array (b) c @ b d.matmul (a, b) print (((c) [0,0]) [/python]

Что такое выход этой головоломки?

Numpy – популярная библиотека Python для науки о данных, ориентируясь на массивы, векторы и матрицы.

Эта головоломка показывает важную область применения Matrix умножения: компьютерная графика.

Мы создаем два матрица A и B. Первая матрица A – это матрица данных (например, состоящая из двух векторов столбцов (1,1) и (1,0) ). Вторая Matrix B – это матрица преобразования, которая преобразует входные данные. В нашей настройке матрица преобразования просто протягивает векторы колонны.

Точнее, два столбец векторы (1,1) и (1,0) растягиваются по фактору 2 до (2,2) и (2,0) Отказ Следовательно, полученная матрица [[2,2], [2,0]] Отказ Доступ к первой строке и второму столбцу.

Мы используем умножение матрицы, чтобы применить это преобразование. Numpy допускает два способа для умножения матрицы: функция Matmul и оператор @ @.

Сравнивая два равномерных массива равных размеров в новом массиве с логическими значениями. Поскольку оба матрица C и D содержат одни и те же данные, результат представляет собой матрицу с только что истинные значения.

Вы мастер-кодер? Проверьте свои навыки сейчас!

Связанное видео.

Решение

2

Expert Writer & Content Creator – наука о науке и машине.

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

Работать со мной, пожалуйста, обратитесь к Upwork
https://tinyurl.com/hire-adam-murphy.