Как умножать матрицы на матрицы? – Обзоры Вики
Как перемножить матрицы 3×2 и 3×3?
тогда можете ли вы перемножить матрицу 2 × 3 и 3 × 3? Умножение матриц 2×3 и 3×3 возможно и результирующая матрица представляет собой матрицу 2×3.
Можно ли перемножить матрицу 3×2 и 2×2? Возможно умножение матриц 3×2 и 2×2, и результирующая матрица представляет собой Матрица 3 × 2.
Как добавить матрицы с переменными?
Как найти количество переменных в матрице? Будучи дополненными матрицами, количество переменных равно количеству столбцов данной матрицы -1. Например, для матрицы из 5 столбцов число переменных равно 5 – 1 = 4, называемых , и . Матрица 1 имеет две точки опоры и 4 переменные. Первый стержень в строке 1, столбце 1; следовательно, является базовой переменной.
Как решить матрицу 2×2 с переменными?
Какой самый быстрый алгоритм умножения матриц? В линейной алгебре алгоритм Штрассена, названный в честь Фолькера Штрассена, представляет собой алгоритм умножения матриц. Это быстрее, чем стандартный алгоритм умножения матриц для больших матриц, с лучшей асимптотической сложностью, хотя наивный алгоритм часто лучше подходит для меньших матриц.
Можно ли перемножить 3 матрицы вместе?
Три матрицы можно очень легко умножить, сначала умножить первые две матрицы, а после этого умножение выполняется между последней матрицей и результирующей матрицей, которая получается в результате умножения первой и второй.
Можно ли перемножать матрицы?
Матрица можно умножить на любую другую матрицу, имеющую столько же строк, сколько столбцов в первой. Т.е. матрицу с двумя столбцами можно умножить на любую матрицу с двумя строками.
Как перемножить матрицы 3×3 и 1×3? Матрица 3×3 не может быть умножена на матрицу 1×3.. Однако его можно умножить на матрицу 3×1, и результатом будет матрица 3×1.
Можно ли перемножить матрицу 2×1 и 2×2?
Умножение 2×2 и возможны матрицы 2×1 и результирующая матрица представляет собой матрицу 2×1.
Как перемножить матрицы 2×3 и 3×2?
Можно ли перемножить матрицы 3×2 и 2×3? Возможно умножение матриц 3×2 и 2×3, и результирующая матрица представляет собой Матрица 3 × 3.
Как умножить матрицу 4 на 4?
Можно ли перемножить матрицу 2×2 и 2×2? Умножение 2×2 и возможны матрицы 2×2 и результирующая матрица представляет собой матрицу 2×2.
Можно ли умножить матрицу 2×2 на 2×1?
Умножение Возможны матрицы 2×2 и 2×1 и результирующая матрица представляет собой матрицу 2×1. Этот калькулятор может мгновенно перемножить две матрицы и показать пошаговое решение.
Как сделать умножение матриц в NumPy
Умножение матриц NumPy — это математическая операция, которая принимает две матрицы и дает одну матрицу путем умножения строк первой матрицы на столбец второй матрицы. Для умножения двух матриц NumPy предоставляет три разные функции.
-
numpy.multiply(arr1, arr2)
— Поэлементное матричное умножение двух массивов -
numpy.matmul(arr1, arr2)
– Матричное произведение двух массивов -
numpy.dot(arr1, arr2)
— Скалярное или скалярное произведение двух массивов
При умножении матриц в NumPy убедитесь, что количество столбцов первой матрицы должно быть равно количеству строк второй матрицы.
Учебники по Python Pandas для начинающих…
Пожалуйста, включите JavaScript
Учебники по Python Pandas для начинающих
1.
Краткие примеры умножения матриц в NumPyЕсли вы спешите, ниже приведены несколько кратких примеров того, как используйте умножение матриц NumPy.
# Ниже приведены краткие примеры # Пример 1: Используйте функцию numpy.mutiply() и # получить умножение матрицы arr2 = np.multiply (arr, arr1) # Пример 2: Получить определенное умножение строк arr2 = np.multiply(arr[0,: 2], arr1[1,: 2]) # Пример 3: Получение скалярного произведения массивов массив = np.массив ([[1, 3], [4, 1]]) обр1 = 2 обр2 = np.dot (обр, обр1) # Пример 4: Использование функции numpy.dot() # Получить произведение двух массивов обр2 = np.dot (обр, обр1) # Пример 5: # Используйте функцию numpy.matmul() # Получить продукт обр2 = np.matmul (обр, обр1)
2. Используйте NumPy.multiply(). Получите поэлементное умножение матриц. Это умножает каждый элемент первой матрицы на эквивалентный элемент второй матрицы, используя поэлементное умножение или произведение Адамара. Убедитесь, что размеры обеих матриц одинаковы для умножения.
импортировать numpy как np # Создаем двумерные массивы numpy массив = np.массив ([[2, 4, 3, 1], [2, 3, 6, 1]]) arr1 = np.массив ([[2, 1, 5, 2], [4, 8, 3, 2]]) # Используйте функцию numpy.mutiply() и # получить умножение матрицы arr2 = np.multiply (arr, arr1) печать (обр2) # Выход : # [[ 4 4 15 2] # [8 24 18 2]]
Чтобы передать определенные строки, столбцы или подматрицы методу numpy.multiply()
и получить умножение определенных строк, столбцов и подматриц. Мы должны следовать тем же размерам строк, столбцов или подматриц, которые мы передаем в качестве наших операндов. Возьмем, к примеру,
. # Получить определенное умножение строк arr2 = np.multiply(arr[0,: 2], arr1[1,: 2]) печать (обр2) # Выход : # [5 12] arr3 = np.multiply (arr [1,: 3], arr1 [0,: 3]) печать (обр3) # Выход : # [ 2 8 18 ]
3. Используйте NumPy.dot() для скалярного умножения.
Простая форма умножения матриц — скалярное умножение, мы можем сделать это с помощью функции NumPy dot(). При скалярном умножении мы можем умножать скаляр на матрицу или умножать матрицу на скаляр. Каждый элемент в матрице умножается на скаляр, который возвращает тот же массив форм, что и исходный массив.
При скалярном умножении порядок не имеет значения. Это возвращает тот же результат, если мы умножаем скаляр на матрицу или матрицу на скаляр.
# Получить скалярное произведение массивов массив = np.массив ([[1, 3], [4, 1]]) обр1 = 2 обр2 = np.dot (обр, обр1) печать (обр2) # Выход : # [[2 6] # [8 2]]
Мы можем умножить двумерную матрицу на другую двумерную матрицу, используя np.dot()
. когда мы умножаем две матрицы, они должны следовать порядку, т. Е. матрица X
, умноженная на матрицу Y, не совпадает с матрицей Y, умноженной на матрицу X. Давайте создадим изображение для лучшего понимания.
# Создаем пустые массивы массив = np.массив([[1, 3], [4, 1]]) arr1 = np. массив([[1, 2], [2, 5]]) # Использовать функцию numpy.dot() # Получить произведение двух массивов обр2 = np.dot (обр, обр1) печать (обр2) # Выход : # [[ 7 17] # [6 13]]
4. Используйте matmul() — умножение двух массивов NumPy
Метод np.matmul()
используется для определения матричного произведения двух массивов. Функция matmul() принимает arr1 и arr2 в качестве аргументов и возвращает матричное произведение входных массивов NumPy. Скаляр создается только тогда, когда и arr1, и arr2 являются одномерными векторами.
# Использовать функцию numpy.matmul() # Получить продукт обр2 = np.matmul (обр, обр1) печать (обр2) # Выход : # [[ 7 17] # [6 13]]
5. Заключение
В этой статье я объяснил концепцию умножения матриц Python NumPy и как ее использовать, используя numpy.multiply()
, numpy.matmul()
и numpy.dot() Функция
с примерами.
Счастливого обучения!!
- Как транспонировать массив NumPy?
- Получить сумму двух массивов
- Как получить значение мощности массива?
- Получить совокупную сумму numpy
- Как удалить столбцы и строки массива NumPy?
- Как преобразовать матрицу NumPy в массив
- Как транспонировать матрицу в NumPy
- Норма NumPy вектора
Ссылки
- https://numpy. org/doc/stable/reference/generated/numpy.matmul.html
Более 20 примеров для умножения матриц NumPy
В этом руководстве мы рассмотрим различные способы выполнения умножения матриц с использованием массивов NumPy. Мы научимся перемножать матрицы разных размеров вместе.
Также мы узнаем, как ускорить процесс умножения с помощью графического процессора и другие горячие темы, так что давайте начнем!
Прежде чем мы двинемся дальше, лучше рассмотреть некоторые основные термины матричной алгебры.
Содержание
1
Основные термины
Вектор: Алгебраически вектор представляет собой набор координат точки в пространстве.
Таким образом, вектор с двумя значениями представляет собой точку в двумерном пространстве. В информатике вектор — это расположение чисел в одном измерении. Он также широко известен как массив, список или кортеж.
Напр. [1,2,3,4]
Матрица: Матрица (множественное число матриц) представляет собой двумерное расположение чисел или набор векторов.
Пример:
[[1,2,3], [4,5,6], [7,8,9]]
Скалярное произведение: Скалярное произведение – это математическая операция между 2 векторами одинаковой длины .
Равен сумме произведений соответствующих элементов векторов.
С четким пониманием этих терминов мы готовы к работе.
Умножение матриц на вектор
Начнем с простой формы умножения матриц — между матрицей и вектором.
Прежде чем мы продолжим, давайте сначала поймем, как создать матрицу с помощью NumPy.
Метод array() NumPy используется для представления векторов, матриц и многомерных тензоров. Давайте определим 5-мерный вектор и матрицу 3 × 3, используя NumPy.
импортировать numpy как np а = np.массив ([1, 3, 5, 7, 9]) б = np.массив([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print("Вектор a:\n", a) Распечатать() print("Матрица b:\n", b)
Вывод:
Давайте теперь посмотрим, как происходит умножение между матрицей и вектором.
При умножении матрицы на вектор следует помнить о следующих моментах:
- Результатом умножения матрицы на вектор является вектор.
- Каждый элемент этого вектора получается путем скалярного произведения между каждой строкой матрицы и умножаемым вектором.
- Количество столбцов в матрице должно быть равно количеству элементов в векторе.
Мы будем использовать метод NumPy matmul() для большинства наших операций умножения матриц.
Давайте определим матрицу 3×3 и умножим ее на вектор длины 3.
импортировать numpy как np а = np.массив([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) б = np.массив ([10, 20, 30]) печать("А=", а) печать("б =", б) печать ("Ab =", np.matmul (а, б))
Вывод:
Обратите внимание, что результатом является вектор длины, равной строкам матрицы множителей.
Умножение на другую матрицу
Теперь мы поняли умножение матрицы на вектор; было бы легко вычислить умножение двух матриц.
Но перед этим повторим самые важные правила умножения матриц:
- Количество столбцов в первой матрице должно быть равно количеству строк во второй матрице.
- Если мы умножаем матрицу размеров m x n на другую матрицу размеров n x p, то в результате получится матрица размеров m x p.
Рассмотрим умножение m x n матрицы A на n x p матрицу B:
Каждый элемент в матрице произведения C является результатом скалярного произведения между вектором-строкой в A и вектором-столбцом в B.
Давайте теперь сделаем матричное умножение двух матриц в Python, используя NumPy.
Мы случайным образом сгенерируем две матрицы размером 3 x 2 и 2 x 4.
Мы будем использовать метод np. random.randint() для генерации чисел.
импортировать numpy как np np.random.seed (42) A = np.random.randint (0, 15, размер = (3,2)) B = np.random.randint (0, 15, размер = (2,4)) print("Матрица А:\n", А) print("форма A =", A.shape) Распечатать() print("Матрица B:\n", B) print("форма B =", B.shape)
Вывод:
Примечание:
мы устанавливаем случайное начальное число, используя ‘np.random.seed()’, чтобы сделать генератор случайных чисел детерминированным.При каждом запуске этого фрагмента кода будут генерироваться одни и те же случайные числа. Этот шаг необходим, если вы хотите воспроизвести результат позже.
Вы можете установить любое другое целое число в качестве начального числа, но я предлагаю установить его на 42 для этого урока, чтобы ваши выходные данные соответствовали показанным на выходных снимках экрана.
Теперь умножим две матрицы, используя np. matmul() метод. Результирующая матрица должна иметь форму 3 x 4.
C = np.matmul(A, B) print("произведение A и B:\n", C) print("shape of product =", C.shape)
Вывод:
Умножение между 3 матрицами
Умножение трех матриц будет состоять из двух операций умножения 2 матриц, и каждая из двух операций будут следовать тем же правилам, которые обсуждались в предыдущем разделе.
Допустим, мы перемножаем три матрицы A, B и C, и произведение равно D = ABC.
Здесь количество столбцов в A должно быть равно количеству строк в B, а количество строк в C должно быть равно количеству столбцов в B.
Результирующая матрица будет иметь строк, равных количеству строк в A и столбцов равно количеству столбцов в C.
Важным свойством операции умножения матриц является то, что является ассоциативным .
При мультиматричном умножении порядок отдельных операций умножения не имеет значения и, следовательно, не дает разных результатов.
Например, в нашем примере умножения трех матриц D = ABC не имеет значения, выполняем ли мы сначала AB или BC.
Оба заказа дадут один и тот же результат. Давайте сделаем пример на Python.
импортировать numpy как np np.random.seed (42) A = np.random.randint (0, 10, размер = (2,2)) B = np.random.randint (0, 10, размер = (2,3)) C = np.random.randint (0, 10, размер = (3,3)) print("Матрица A:\n{}, shape={}\n".format(A, A.shape)) print("Матрица B:\n{}, shape={}\n".format(B, B.shape)) print("Матрица C:\n{}, shape={}\n".format(C, C.shape))
Вывод:
Основываясь на правилах, которые мы обсуждали выше, умножение этих трех матриц должно дать результирующую матрицу формы (2, 3).
Обратите внимание, что метод np.matmul() принимает только две матрицы в качестве входных данных для умножения, поэтому мы будем вызывать метод дважды в том порядке, в котором мы хотим умножить, и передавать результат первого вызова в качестве параметра в второй.
(мы найдем лучший способ справиться с этой проблемой в следующем разделе, когда мы введем оператор @)
Выполним умножение в обоих порядках и проверим свойство ассоциативности.
D = np.matmul(np.matmul(A,B),C) print("Результат умножения в порядке (AB)C:\n\n{},shape={}\n".format(D, D.shape)) D = np.matmul(A, np.matmul(B,C)) print("Результат умножения в порядке A(BC):\n\n{},shape={}".format(D, D.shape))
Вывод:
Как мы видим, результат умножения трех матриц остается тем же, независимо от того, умножаем ли мы сначала А и В или сначала В и С.
Таким образом, свойство ассоциативности подтверждается.
Кроме того, результирующий массив имеет форму (2, 3), что соответствует ожидаемым строкам.
NumPy Умножение трехмерных матриц
Трехмерная матрица — это не что иное, как набор (или стек) множества двумерных матриц, точно так же, как двумерная матрица представляет собой набор/стек множества одномерных векторов.
Таким образом, матричное умножение трехмерных матриц включает в себя многократное умножение двумерных матриц, которое в конечном итоге сводится к скалярному произведению между их векторами строк и столбцов.
Рассмотрим пример матрицы A формы (3,3,2), умноженной на другую трехмерную матрицу B формы (3,2,4).
импортировать numpy как np np.random.seed (42) A = np.random.randint (0, 10, размер = (3,3,2)) B = np.random.randint (0, 10, размер = (3,2,4)) print("A:\n{}, shape={}\nB:\n{}, shape={}".format(A, A.shape,B, B.shape))
Вывод:
Первая матрица представляет собой стопку из трех двумерных матриц, каждая из которых имеет форму (3,2), а вторая матрица представляет собой стопку из трех двумерных матриц, каждая из которых имеет форму (2,4).
Умножение матриц между этими двумя включает три умножения между соответствующими двумерными матрицами A и B, имеющими формы (3,2) и (2,4) соответственно.
В частности, первое умножение будет между A[0] и B[0], второе умножение будет между A[1] и B[1] и, наконец, третье умножение будет между A[2] и БИ 2].
Результат каждого отдельного умножения двумерных матриц будет иметь форму (3,4). Следовательно, конечным продуктом двух трехмерных матриц будет матрица формы (3,3,4).
Давайте реализуем это с помощью кода.
С = np.matmul(A,B) print("Product C:\n{}, shape={}".format(C, C.shape))
Вывод:
Альтернативы np.matmul()
Кроме ‘np.matmul ()’ существует два других способа выполнения матричного умножения — метод np.dot() и оператор ‘@’ , каждый из которых предлагает некоторые различия/гибкость в операциях матричного умножения.
Метод ‘np.dot()’
Вы можете использовать этот метод для нахождения скалярного произведения векторов, но если мы передадим две двумерные матрицы, то он будет вести себя аналогично методу ‘np. matmul()’ и будет возвращать результат матричного умножения две матрицы.
Давайте рассмотрим пример:
импортировать numpy как np # матрица 3x2 A = np.массив([[8, 2, 2], [1, 0, 3]]) # матрица 2x3 B = np.массив([[1, 3], [5, 0], [9, 6]]) # точечный продукт должен возвращать продукт 2x2 С = np.точка (А, В) print("произведение A и B:\n{} shape={}".format(C, C.shape))
Вывод:
Здесь мы определили матрицу 3 × 2, а матрицу 2 × 3 и их скалярное произведение дает результат 2 × 2, который представляет собой матричное умножение двух матриц, 90 129 такое же, как у ‘np.matmul()’ вернулся.
Разница между np.dot() и np.matmul() заключается в их работе с трехмерными матрицами.
В то время как np.matmul() работает с двумя трехмерными матрицами путем вычисления матричного умножения соответствующих пар двумерных матриц (как обсуждалось в последнем разделе), np. dot(), с другой стороны, вычисляет скалярные произведения различных пар векторы-строки и векторы-столбцы из первой и второй матрицы соответственно.
np.dot() для двух трехмерных матриц A и B возвращает произведение суммы по последней оси A и предпоследней оси B.
Это неинтуитивно и нелегко понять .
Итак, если A имеет форму (a, b, c), а B имеет форму (d, c, e), то результат np.dot(A, B) будет иметь форму (a, d, b,e), отдельный элемент которого в позиции (i,j,k,m) определяется как:
dot(A, B)[i,j,k,m] = sum(A[i,j,: ] * B[k,:,m])
Проверим на примере:
импортировать numpy как np np.random.seed (42) A = np.random.randint (0, 10, размер = (2,3,2)) B = np.random.randint (0, 10, размер = (3,2,4)) print("A:\n{}, shape={}\nB:\n{}, shape={}".format(A, A.shape,B, B.shape))
Вывод:
Если теперь мы передадим эти матрицы методу np.dot(), он вернет матрицу формы (2,3,3,4), отдельные элементы которой вычисляются по приведенной выше формуле.
C = np.dot(A,B) print("np.dot(A,B) =\n{}, shape={}".format(C, C.shape))
Вывод:
Другое важное различие между ‘np.matmul()’ и ‘np.dot()’ заключается в том, что ‘np.matmul()’ не допускает умножения на скаляр (мы обсудим в следующем разделе), а ‘np. точка()’ позволяет это.
Оператор «@»
Оператор @, представленный в Python 3.5, выполняет ту же операцию, что и «np.matmul()».
Давайте рассмотрим более ранний пример np.matmul() с использованием оператора @ и увидим тот же результат, что и ранее:
импортировать numpy как np np.random.seed (42) A = np.random.randint (0, 15, размер = (3,2)) B = np.random.randint (0, 15, размер = (2,4)) print("Матрица A:\n{}, shape={}".format(A, A.shape)) print("Матрица B:\n{}, shape={}".format(B, B.shape)) С = А @ В print("произведение A и B:\n{}, shape={}".format(C, C.shape))
Вывод:
Оператор «@» становится удобным, когда мы выполняем матричное умножение более чем двух матриц.
Раньше нам приходилось вызывать np.matmul() несколько раз и передавать их результаты в качестве параметра следующему вызову.
Теперь мы можем выполнить ту же операцию более простым (и более интуитивным) способом:
import numpy as np np.random.seed (42) A = np.random.randint (0, 10, размер = (2,2)) B = np.random.randint (0, 10, размер = (2,3)) C = np.random.randint (0, 10, размер = (3,3)) print("Матрица A:\n{}, shape={}\n".format(A, A.shape)) print("Матрица B:\n{}, shape={}\n".format(B, B.shape)) print("Матрица C:\n{}, shape={}\n".format(C, C.shape)) D = A @ B @ C # ранее np.matmul(np.matmul(A,B),C) print("Продукт ABC:\n\n{}, shape={}\n".format(D, D.shape))
Вывод:
Умножение на скаляр (одно значение)
До сих пор мы выполняли умножение матрицы на вектор или другую матрицу. Но что происходит, когда мы выполняем умножение матриц на скалярное или одно числовое значение?
Результат такой операции получается путем умножения каждого элемента матрицы на скалярное значение. Таким образом, выходная матрица имеет ту же размерность, что и входная матрица.
Обратите внимание, что ‘np.matmul()’ не позволяет умножать матрицу на скаляр. Вы можете добиться этого, используя np.dot() или с помощью оператора ‘*’.
Давайте посмотрим на это на примере кода.
импортировать numpy как np A = np.массив([[1,2,3], [4,5, 6], [7, 8, 9]]) В = А * 10 print("Матрица A:\n{}, shape={}\n".format(A, A.shape)) print("Умножение A на 10:\n{}, shape={}".format(B, B.shape))
Вывод:
Поэлементное матричное умножение
Иногда нам нужно сделать умножение соответствующих элементов двух матриц, имеющих одинаковую форму.
Эта операция также называется продуктом Адамара . Он принимает две матрицы одинакового размера и создает третью матрицу того же размера.
Этого можно добиться, вызвав функцию NumPy, умножить () или используя оператор ‘*’ .
импортировать numpy как np np.random.seed (42) A = np.random.randint (0, 10, размер = (3,3)) B = np.random.randint (0, 10, размер = (3,3)) print("Матрица A:\n{}\n".format(A)) печать ("Матрица B:\n{}\n".format(B)) C = np.multiply(A,B) # или A * B print("Поэлементное умножение A и B:\n{}".format(C))
Вывод:
Единственное правило, которое необходимо учитывать при поэлементном умножении, заключается в том, что две матрицы должны иметь одинаковую форму .
Однако, если одно измерение матрицы отсутствует, NumPy будет транслировать его, чтобы оно соответствовало форме другой матрицы.
На самом деле умножение матриц на скаляр также включает передачу скалярного значения в матрицу формы, равной матричному операнду при умножении.
Это означает, что когда мы умножаем матрицу формы (3,3) на скалярное значение 10, NumPy создаст другую матрицу формы (3,3) с постоянными значениями десять во всех позициях в матрице и выполнит поэлементное умножение между двумя матрицами.
Давайте разберемся с этим на примере:
импортировать numpy как np np.random.seed (42) A = np.random.randint (0, 10, размер = (3,4)) B = np.массив ([[1,2,3,4]]) print("Матрица A:\n{}, shape={}\n".format(A, A.shape)) print("Матрица B:\n{}, shape={}\n".format(B, B.shape)) С = А * В print("Поэлементное умножение A и B:\n{}".format(C))
Вывод:
Обратите внимание, как вторая матрица, имевшая форму (1,4), трансформировалась в матрицу (3,4) путем трансляции, и произошло поэлементное умножение между двумя матрицами.
Матрица, возведенная в степень (возведение матрицы в степень)
Подобно тому, как мы можем возвести скалярное значение в степень, мы можем проделать ту же операцию с матрицами.
Точно так же, как возведение скалярного значения (основания) в степень n равносильно многократному умножению n оснований, та же картина наблюдается при возведении матрицы в степень, которая включает в себя повторяющиеся матричные умножения.
Например, если мы возведем матрицу A в степень n, она будет равна матричному умножению n матриц, каждая из которых будет матрицей A.
Обратите внимание, что для того, чтобы эта операция была возможной, базовая матрица должна быть квадратной .
Это делается для того, чтобы количество столбцов в предыдущей матрице было равно количеству строк в следующей матрице.
Эта операция обеспечивается в Python методом linalg.matrix_power() NumPy, который принимает базовую матрицу и целочисленную степень в качестве параметров.
Давайте посмотрим на пример в Python:
импортировать numpy как np np.random.seed (10) A = np.random.randint (0, 10, размер = (3,3)) A_to_power_3 = np.linalg.matrix_power(A, 3) print("Матрица A:\n{}, shape={}\n".format(A, A.shape)) print("A в степени 3:\n{}, shape={}".format(A_to_power_3,A_to_power_3.shape))
Вывод:
Мы можем проверить этот результат, выполнив обычное умножение матриц с тремя операндами (все они A), используя оператор @:
Б = А @ А @ А print("B = A @ A @ A :\n{}, shape={}". format(B, B.shape))
Вывод:
Как видите, результаты обеих операций совпадают.
В связи с этой операцией возникает важный вопрос: Что происходит, когда мощность равна 0?
Чтобы ответить на этот вопрос, давайте посмотрим, что происходит, когда мы возводим скалярную базу в степень 0.
Мы получаем значение 1, верно? Теперь, что эквивалентно 1 в матричной алгебре? Вы правильно угадали!
Это идентификационная матрица.
Таким образом, возведение матрицы n x n в степень 0 приводит к единичной матрице I формы n x n.
Давайте быстро проверим это на Python, используя нашу предыдущую матрицу A.
C = np.linalg.matrix_power(A, 0) print("A в степени 0:\n{}, shape={}".format(C, C.shape))
Вывод:
Поэлементное возведение в степень
Так же, как мы могли бы сделать element -мудрое умножение матриц, мы также можем выполнить поэлементное возведение в степень, т. powers:\n{}, shape={}\n».format(C, C.shape))
Вывод:
Умножение определенного индекса
Предположим, у нас есть матрица A 5 x 6 и другая матрица B 3 x 3. Очевидно, что мы не можем умножить их вместе из-за несоответствия размеров.
Но что, если бы мы захотели умножить подматрицу 3×3 в матрице A на матрицу B, сохранив при этом другие элементы в A неизменными?
Для лучшего понимания см. следующее изображение:
Вы можете выполнить эту операцию в Python, используя разрезает матрицу для извлечения подматрицы из A, выполняет умножение на B, а затем записывает результат по соответствующему индексу в A.
Давайте посмотрим на это в действии.
импортировать numpy как np np.random.seed (42) A = np.random.randint (0, 10, размер = (5,6)) B = np.random.randint (0, 10, размер = (3,3)) print("Матрица A:\n{}, shape={}\n".format(A, A.shape)) print("Матрица B:\n{}, shape={}\n". format(B, B.shape)) С = А[1:4,2:5] @ В А[1:4,2:5] = С print("Матрица A после умножения подматриц:\n{}, shape={}\n".format(A, A.shape))
Вывод:
Как видите, только элементы с индексами строк с 1 по 3 и индексами столбцов со 2 по 4 были умножены на B, и то же самое было записано обратно в A, в то время как остальные элементы A остались неизменными.
Также нет необходимости перезаписывать исходную матрицу. Мы также можем записать результат в новую матрицу, сначала скопировав исходную матрицу в новую матрицу, а затем записав произведение в позиции подматрицы.
Умножение матриц с использованием графического процессора
Мы знаем, что NumPy ускоряет матричные операции, распараллелив множество вычислений и используя возможности параллельных вычислений нашего ЦП.
Однако современным приложениям нужно нечто большее. ЦП предлагают ограниченные вычислительные возможности, и этого недостаточно для большого количества необходимых нам вычислений, как правило, в таких приложениях, как глубокое обучение.
Именно здесь на сцену выходят графические процессоры. Они предлагают большие вычислительные возможности и превосходную инфраструктуру параллельных вычислений, которая помогает нам сэкономить значительное количество времени, выполняя сотни тысяч операций за доли секунды.
В этом разделе мы рассмотрим, как можно выполнять умножение матриц на графическом процессоре вместо центрального процессора и сэкономить при этом много времени.
NumPy не предлагает функции для умножения матриц на графическом процессоре. Поэтому мы должны установить некоторые дополнительные библиотеки, которые помогут нам достичь нашей цели.
Сначала мы установим библиотеки « scikit-cuda » и « PyCUDA », используя установку pip. Эти библиотеки помогают нам выполнять вычисления на графических процессорах на базе CUDA. Чтобы установить эти библиотеки с вашего терминала, если на вашем компьютере установлен графический процессор.
pip установить pycuda pip install scikit-cuda
Если на вашем компьютере нет графического процессора, вы можете попробовать ноутбуки Google Colab и включить доступ к графическому процессору; это бесплатно для использования. Теперь мы напишем код для генерации двух матриц 1000×1000 и выполнения матричного умножения между ними двумя методами:
Во втором методе мы будем генерировать матрицы на процессоре; затем мы будем хранить их на графическом процессоре (используя PyCUDA’s ‘ gpuarray.to_gpu() ‘метод) перед выполнением умножения между ними. Мы будем использовать модуль « time » для вычисления времени вычислений в обоих случаях.
Использование ЦП
импортировать numpy как np время импорта # генерация матриц 1000 x 1000 np.random.seed (42) x = np.random.randint(0,256, размер=(1000,1000)).astype("float64") y = np.random.randint(0,256, размер=(1000,1000)).astype("float64") # вычисление времени умножения на CPU тик = время.время() г = np.matmul (х, у) ток = время.время() time_taken = toc - тик #время в секундах print("Время, затрачиваемое ЦП (в мс) = {}". format(time_taken*1000))
Вывод:
На некоторых старых аппаратных системах вы можете получить ошибку памяти, но если вам повезет, это будет работать в течение длительного времени (зависит от вашей системы).
Теперь давайте выполним то же самое умножение на графическом процессоре и посмотрим, как отличается время вычислений между ними.
Использование GPU
#вычисление времени умножения на GPU linalg.init() # хранение массивов на GPU x_gpu = gpuarray.to_gpu(x) y_gpu = gpuarray.to_gpu(y) тик = время.время() #выполнение умножения z_gpu = linalg.mdot(x_gpu, y_gpu) ток = время.время() time_taken = toc - тик #время в секундах print("Время, затраченное на GPU (в мс) = {}".format(time_taken*1000))
Вывод:
Как мы видим, выполнение той же операции на GPU дает нам ускорение в 70 раз по сравнению с CPU.
Это было еще небольшое вычисление. Для крупномасштабных вычислений графические процессоры дают нам ускорение на несколько порядков.
Заключение
В этом уроке мы рассмотрели, как происходит умножение двух матриц, управляющие им правила и как их реализовать в Python.
Мы также рассмотрели различные варианты стандартного умножения матриц (и их реализацию в NumPy), такие как умножение более двух матриц, умножение только на определенный индекс или степень матрицы.
Мы также рассмотрели поэлементные вычисления в матрицах, такие как поэлементное матричное умножение или поэлементное возведение в степень.
Наконец, мы рассмотрели, как можно ускорить процесс умножения матриц, выполняя их на графическом процессоре.
Мохтар Эбрахим
Мохтар — основатель LikeGeeks.com. Он работает системным администратором Linux с 2010 года. Он отвечает за обслуживание, защиту и устранение неполадок серверов Linux для нескольких клиентов по всему миру. Он любит писать сценарии оболочки и Python для автоматизации своей работы.