Cách nhân ba ma trận trong Python

Hàng đầu tiên có thể được chọn là X[0]. Và, phần tử ở hàng đầu tiên, cột đầu tiên có thể được chọn là X[0][0]

Phép nhân hai ma trận X và Y chỉ được xác định nếu số cột trong X bằng số hàng Y

Nếu X là ma trận n x m và Y là ma trận m x l thì XY được xác định và có thứ nguyên là n x l (nhưng YX không được xác định). Dưới đây là một số cách để triển khai phép nhân ma trận trong Python

Mã nguồn. Phép nhân ma trận bằng vòng lặp lồng nhau

# Program to multiply two matrices using nested loops

# 3x3 matrix
X = [[12,7,3],
    [4 ,5,6],
    [7 ,8,9]]
# 3x4 matrix
Y = [[5,8,1,2],
    [6,7,3,0],
    [4,5,9,1]]
# result is 3x4
result = [[0,0,0,0],
         [0,0,0,0],
         [0,0,0,0]]

# iterate through rows of X
for i in range(len(X)):
   # iterate through columns of Y
   for j in range(len(Y[0])):
       # iterate through rows of Y
       for k in range(len(Y)):
           result[i][j] += X[i][k] * Y[k][j]

for r in result:
   print(r)

đầu ra

[114, 160, 60, 27]
[74, 97, 73, 14]
[119, 157, 112, 23]

Trong chương trình này, chúng tôi đã sử dụng các vòng lặp

[114, 160, 60, 27]
[74, 97, 73, 14]
[119, 157, 112, 23]
0 lồng nhau để lặp qua từng hàng và từng cột. Chúng tôi tích lũy tổng sản phẩm trong kết quả

Kỹ thuật này đơn giản nhưng tốn kém về mặt tính toán khi chúng ta tăng bậc của ma trận

Đối với các hoạt động ma trận lớn hơn, chúng tôi khuyên dùng các gói phần mềm được tối ưu hóa như NumPy, nhanh hơn vài lần (theo thứ tự 1000) lần so với mã trên

Mã nguồn. Phép nhân ma trận bằng cách sử dụng danh sách lồng nhau

# Program to multiply two matrices using list comprehension

# 3x3 matrix
X = [[12,7,3],
    [4 ,5,6],
    [7 ,8,9]]

# 3x4 matrix
Y = [[5,8,1,2],
    [6,7,3,0],
    [4,5,9,1]]

# result is 3x4
result = [[sum(a*b for a,b in zip(X_row,Y_col)) for Y_col in zip(*Y)] for X_row in X]

for r in result:
   print(r)

Đầu ra của chương trình này giống như trên. Để hiểu đoạn mã trên, trước tiên chúng ta phải biết về và sử dụng toán tử *

Chúng tôi đã sử dụng khả năng hiểu danh sách lồng nhau để lặp qua từng phần tử trong ma trận. Lúc đầu, mã có vẻ phức tạp và không thể đọc được. Nhưng một khi bạn hiểu rõ về danh sách, có thể bạn sẽ không quay lại các vòng lặp lồng nhau

# Chương trình nhân hai ma trận bằng vòng lặp lồng nhau

X = [ [1,2],[3,4],[4,5] ]

kết quả = [ [0,0,0],[0,0,0],[0,0,0] ]

# lặp hàng của ma trận X

cho tôi trong phạm vi ( len(X) )

# lặp cột của ma trận Y

cho j trong phạm vi(len(Y[0]))

# lặp các hàng của ma trận Y

kết quả[i][j] += X[i][k] * Y[k][j]

Tính toán tích vô hướng của hai hoặc nhiều mảng trong một lần gọi hàm, đồng thời tự động chọn thứ tự đánh giá nhanh nhất

chuỗi và sử dụng dấu ngoặc đơn tối ưu của ma trận. Tùy thuộc vào hình dạng của ma trận, điều này có thể tăng tốc độ nhân lên rất nhiều

Nếu đối số đầu tiên là 1-D thì nó được coi là một vectơ hàng. Nếu đối số cuối cùng là 1-D thì nó được coi là một vectơ cột. Các đối số khác phải là 2-D

Hãy coi như

def multi_dot(arrays): return functools.reduce(np.dot, arrays)

Thông số . mảng trình tự của array_like

Nếu đối số đầu tiên là 1-D thì nó được coi là vectơ hàng. Nếu đối số cuối cùng là 1-D thì nó được coi là vectơ cột. Các đối số khác phải là 2-D

ra ndarray, tùy chọn

đối số đầu ra. Điều này phải có loại chính xác sẽ được trả lại nếu nó không được sử dụng. Đặc biệt, nó phải đúng loại, phải là C-concessory, và dtype của nó phải là dtype sẽ được trả về cho dot(a, b). Đây là một tính năng hiệu suất. Do đó, nếu các điều kiện này không được đáp ứng, một ngoại lệ sẽ được đưa ra, thay vì cố gắng linh hoạt

Trong hướng dẫn này, chúng ta sẽ xem xét nhiều cách khác nhau để thực hiện phép nhân ma trận bằng cách sử dụng mảng NumPy. Chúng ta sẽ học cách nhân các ma trận có kích thước khác nhau với nhau

Ngoài ra, chúng ta sẽ tìm hiểu cách tăng tốc quá trình nhân lên bằng GPU và các chủ đề nóng khác, vì vậy hãy bắt đầu

Trước khi chúng ta tiếp tục, tốt hơn là nên xem lại một số thuật ngữ cơ bản của Đại số ma trận

 

Mục lục

1

 

thuật ngữ cơ bản

véc tơ. Về mặt đại số, vectơ là tập hợp tọa độ của một điểm trong không gian
Do đó, một vectơ có hai giá trị đại diện cho một điểm trong không gian 2 chiều. Trong Khoa học Máy tính, vectơ là sự sắp xếp các số dọc theo một chiều. Nó cũng thường được gọi là một mảng hoặc một danh sách hoặc một bộ
Ví dụ. [1,2,3,4]

ma trận. Ma trận (ma trận số nhiều) là sự sắp xếp 2 chiều của các số hoặc tập hợp các vectơ
Bán tại

[[1,2,3],
[4,5,6],
[7,8,9]]

chấm sản phẩm. Tích vô hướng là một phép toán giữa 2 vectơ có độ dài bằng nhau
Nó bằng tổng các tích của các phần tử tương ứng của các vectơ

Cách nhân ba ma trận trong Python

Với sự hiểu biết rõ ràng về các thuật ngữ này, chúng ta đã sẵn sàng

 

Phép nhân ma trận với một vectơ

Hãy bắt đầu với một dạng phép nhân ma trận đơn giản – giữa ma trận và vectơ

Trước khi chúng tôi tiếp tục, trước tiên hãy hiểu cách tạo ma trận bằng NumPy

Phương thức array() của NumPy được sử dụng để biểu diễn các vectơ, ma trận và các tenxơ chiều cao hơn. Hãy xác định một vectơ 5 chiều và ma trận 3 × 3 bằng NumPy

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)

đầu ra

Cách nhân ba ma trận trong Python

Bây giờ chúng ta hãy xem phép nhân giữa ma trận và vectơ diễn ra như thế nào

Đối với phép nhân vectơ-ma trận, bạn nên ghi nhớ các điểm sau

  1. Kết quả của phép nhân ma trận-vector là một vectơ
  2. Mỗi phần tử của vectơ này có được bằng cách thực hiện tích vô hướng giữa mỗi hàng của ma trận và vectơ được nhân
  3. Số cột trong ma trận phải bằng số phần tử trong vectơ

Cách nhân ba ma trận trong Python

Chúng ta sẽ sử dụng phương thức matmul() NumPy cho hầu hết các hoạt động nhân ma trận của mình
Hãy xác định ma trận 3×3 và nhân nó với một vectơ có độ dài 3

import numpy as np
a = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
b= np.array([10, 20, 30])
print("A =", a)
print("b =", b)
print("Ab =",np.matmul(a,b))

đầu ra

Cách nhân ba ma trận trong Python

Lưu ý cách kết quả là một vectơ có độ dài bằng các hàng của ma trận nhân

Nhân với một ma trận khác

Bây giờ,  chúng ta đã hiểu phép nhân của một ma trận với một vectơ;
Nhưng, trước đó, hãy xem lại các quy tắc quan trọng nhất của phép nhân ma trận

  1. Số cột trong ma trận thứ nhất phải bằng số hàng trong ma trận thứ hai
  2. Nếu chúng ta nhân một ma trận có kích thước m x ​​n với một ma trận có kích thước n x p khác, thì kết quả sẽ là một ma trận có kích thước m x ​​p

Chúng ta hãy xem xét phép nhân của ma trận A m x n với ma trận n x p B.

Cách nhân ba ma trận trong Python
Cách nhân ba ma trận trong Python

Tích của hai ma trận C = AB sẽ có m hàng và p cột.
Mỗi phần tử trong ma trận tích C là kết quả của một tích vô hướng giữa vectơ hàng trong A và vectơ cột trong B

Cách nhân ba ma trận trong Python

Bây giờ chúng ta hãy thực hiện phép nhân ma trận của 2 ma trận trong Python, sử dụng NumPy
Chúng tôi sẽ tạo ngẫu nhiên hai ma trận có kích thước 3 x 2 và 2 x 4
Chúng tôi sẽ sử dụng np. ngẫu nhiên. randint() để tạo số

________số 8_______

đầu ra

Cách nhân ba ma trận trong Python

Ghi chú. chúng tôi đang đặt một hạt giống ngẫu nhiên bằng cách sử dụng 'np. ngẫu nhiên. seed()’ để làm cho trình tạo số ngẫu nhiên trở nên xác định
Điều này sẽ tạo ra các số ngẫu nhiên giống nhau mỗi khi bạn chạy đoạn mã này. Bước này là cần thiết nếu bạn muốn tái tạo kết quả của mình sau này

Bạn có thể đặt bất kỳ số nguyên nào khác làm hạt giống, nhưng tôi khuyên bạn nên đặt nó thành 42 cho hướng dẫn này để đầu ra của bạn khớp với số được hiển thị trong ảnh chụp màn hình đầu ra

Bây giờ chúng ta hãy nhân hai ma trận bằng cách sử dụng np. phương thức matmul(). Ma trận kết quả phải có dạng 3 x 4

C = np.matmul(A, B)
print("product of A and B:\n", C)
print("shape of product =", C.shape)

đầu ra

Cách nhân ba ma trận trong Python

Phép nhân giữa 3 ma trận

Phép nhân ba ma trận sẽ bao gồm hai phép toán nhân 2 ma trận và mỗi phép tính trong hai phép toán sẽ tuân theo các quy tắc tương tự như đã thảo luận trong phần trước

Giả sử chúng ta đang nhân ba ma trận A, B và C, và tích là D = ABC
Ở đây, số cột trong A phải bằng số hàng trong B và số hàng trong C phải bằng số cột trong B

Ma trận thu được sẽ có số hàng bằng số hàng của A và số cột bằng số cột của C

Một thuộc tính quan trọng của phép toán nhân ma trận là nó có tính Liên kết
Với phép nhân đa ma trận, thứ tự của các phép toán nhân riêng lẻ không quan trọng và do đó không mang lại các kết quả khác nhau

Chẳng hạn, trong ví dụ của chúng ta về phép nhân 3 ma trận D = ABC, không quan trọng chúng ta thực hiện AB trước hay BC trước

Cách nhân ba ma trận trong Python

Cả hai thứ tự sẽ mang lại kết quả như nhau. Hãy để chúng tôi làm một ví dụ trong Python

import numpy as np
np.random.seed(42)
A = np.random.randint(0, 10, size=(2,2))
B = np.random.randint(0, 10, size=(2,3))
C = np.random.randint(0, 10, size=(3,3))
print("Matrix A:\n{}, shape={}\n".format(A, A.shape))
print("Matrix B:\n{}, shape={}\n".format(B, B.shape))
print("Matrix C:\n{}, shape={}\n".format(C, C.shape))

đầu ra

Cách nhân ba ma trận trong Python

Dựa trên các quy tắc mà chúng ta đã thảo luận ở trên, phép nhân của ba ma trận này sẽ mang lại một ma trận kết quả có dạng (2, 3)
Lưu ý rằng phương pháp np. matmul() chỉ chấp nhận hai ma trận làm đầu vào cho phép nhân, vì vậy chúng ta sẽ gọi phương thức này hai lần theo thứ tự mà chúng ta muốn nhân và chuyển kết quả của lệnh gọi đầu tiên làm tham số cho lệnh gọi thứ hai
(Chúng ta sẽ tìm ra cách tốt hơn để giải quyết vấn đề này trong phần sau khi chúng ta giới thiệu toán tử '@')

Hãy thực hiện phép nhân theo cả hai thứ tự và xác thực thuộc tính của tính kết hợp

D = np.matmul(np.matmul(A,B), C)
print("Result of multiplication in the order (AB)C:\n\n{},shape={}\n".format(D, D.shape))
D = np.matmul(A, np.matmul(B,C))
print("Result of multiplication in the order A(BC):\n\n{},shape={}".format(D, D.shape))

đầu ra

Cách nhân ba ma trận trong Python

Như chúng ta có thể thấy, kết quả của phép nhân ba ma trận không thay đổi cho dù chúng ta nhân A và B trước hay B và C trước
Do đó, thuộc tính của tính kết hợp được xác nhận
Ngoài ra, hình dạng của mảng kết quả là (2, 3), nằm trên các dòng dự kiến

 

Phép nhân ma trận 3D NumPy

Ma trận 3D không là gì ngoài một tập hợp (hoặc một ngăn xếp) của nhiều ma trận 2D, giống như cách ma trận 2D là một tập hợp/ngăn xếp của nhiều vectơ 1D

Vì vậy, phép nhân ma trận của ma trận 3D liên quan đến nhiều phép nhân của ma trận 2D, cuối cùng quy về tích vô hướng giữa các vectơ hàng/cột của chúng

Chúng ta hãy xem xét một ma trận ví dụ A có hình dạng (3,3,2) nhân với một ma trận 3D khác B có hình dạng (3,2,4)

import numpy as np
np.random.seed(42)
A  = np.random.randint(0, 10, size=(3,3,2))
B  = np.random.randint(0, 10, size=(3,2,4))
print("A:\n{}, shape={}\nB:\n{}, shape={}".format(A, A.shape,B, B.shape))

đầu ra

Cách nhân ba ma trận trong Python

Ma trận đầu tiên là một chồng ba ma trận 2D, mỗi ma trận có hình dạng (3,2) và ma trận thứ hai là một chồng 3 ma trận 2D, mỗi ma trận có hình dạng (2,4)

Phép nhân ma trận giữa hai ma trận này sẽ liên quan đến ba phép nhân giữa các ma trận 2D tương ứng của A và B có hình dạng (3,2) và (2,4) tương ứng

Cụ thể, phép nhân đầu tiên sẽ nằm trong khoảng từ A[0] đến B[0], phép nhân thứ hai sẽ nằm trong khoảng từ A[1] đến B[1] và cuối cùng, phép nhân thứ ba sẽ nằm trong khoảng từ A[2] đến B[

Kết quả của mỗi phép nhân riêng lẻ của ma trận 2D sẽ có dạng (3,4). Do đó, tích cuối cùng của hai ma trận 3D sẽ là một ma trận có dạng (3,3,4)

Hãy nhận ra điều này bằng cách sử dụng mã

C = np.matmul(A,B)
print("Product C:\n{}, shape={}".format(C, C.shape))

đầu ra

Cách nhân ba ma trận trong Python

Các lựa chọn thay thế cho np. matmul()

Ngoài ‘np. matmul()’, có hai cách khác để thực hiện phép nhân ma trận – np. dot() và toán tử ‘@’, mỗi phương thức cung cấp một số điểm khác biệt/tính linh hoạt trong phép toán nhân ma trận

'np. phương pháp dấu chấm ()'

Bạn có thể sử dụng phương pháp này để tìm tích vô hướng của các vectơ, nhưng nếu chúng ta chuyển hai ma trận 2 chiều, thì nó sẽ hoạt động tương tự như 'np. matmul()’ và sẽ trả về kết quả phép nhân ma trận của hai ma trận

Chúng ta hãy xem xét một ví dụ

import numpy as np
# a 3x2 matrix
A = np.array([[8, 2, 2],
             [1, 0, 3]]) 
# a 2x3 matrix
B = np.array([[1, 3],
             [5, 0],
             [9, 6]])
# dot product should return a 2x2 product
C = np.dot(A, B)
print("product of A and B:\n{} shape={}".format(C, C.shape))

đầu ra

Cách nhân ba ma trận trong Python

Ở đây, chúng tôi đã xác định ma trận 3×2 và ma trận 2×3 và tích vô hướng của chúng mang lại kết quả 2×2 là phép nhân ma trận của hai ma trận,
giống như những gì 'np. matmul()’ sẽ trở lại

Sự khác biệt giữa np. dấu chấm () và np. matmul() đang hoạt động trên ma trận 3D
Trong khi 'np. matmul()’ hoạt động trên hai ma trận 3D bằng cách tính toán phép nhân ma trận của các cặp ma trận 2D tương ứng (như đã thảo luận trong phần trước), np. mặt khác, dot() tính toán các tích vô hướng của các cặp vectơ hàng và vectơ cột khác nhau từ ma trận thứ nhất và thứ hai tương ứng

np. dot() trên hai ma trận 3D A và B trả về một tích tổng trên trục cuối cùng của A và trục thứ hai đến cuối cùng của B
Điều này là không trực quan và không dễ hiểu

Vì vậy, nếu A có dạng (a, b, c) và B có dạng (d, c, e), thì kết quả của np. dot(A, B) sẽ có hình dạng (a,d,b,e) có phần tử riêng lẻ tại vị trí (i,j,k,m) được cho bởi

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
0

Hãy kiểm tra một ví dụ

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
1

đầu ra

Cách nhân ba ma trận trong Python

Nếu bây giờ chúng ta chuyển các ma trận này cho 'np. dot()’, nó sẽ trả về một ma trận có hình dạng (2,3,3,4) có các phần tử riêng lẻ được tính bằng công thức đã cho ở trên

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
2

đầu ra

Cách nhân ba ma trận trong Python

Một sự khác biệt quan trọng khác giữa 'np. matmul()’ và ‘np. dấu chấm ()' là 'np. matmul()’ không cho phép nhân với số vô hướng (chúng ta sẽ thảo luận trong phần tiếp theo), trong khi ‘np. dấu chấm ()' cho phép nó

Toán tử '@'

Toán tử @ được giới thiệu trong Python 3. 5, nó thực hiện thao tác tương tự như ‘np. matmul()’

Hãy chạy qua một ví dụ trước đó về 'np. matmul()’ sử dụng @ toán tử và sẽ thấy kết quả tương tự như được trả về trước đó

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
3

đầu ra

Cách nhân ba ma trận trong Python

Toán tử '@' trở nên tiện dụng khi chúng ta thực hiện phép nhân ma trận của hai ma trận

Trước đó, chúng ta phải gọi 'np. matmul()’ nhiều lần và chuyển kết quả của chúng dưới dạng tham số cho lần gọi tiếp theo
Giờ đây, chúng ta có thể thực hiện thao tác tương tự theo cách đơn giản hơn (và trực quan hơn)

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
4

đầu ra

Cách nhân ba ma trận trong Python

 

Nhân với một vô hướng (Một giá trị)

Cho đến giờ, chúng ta đã thực hiện phép nhân của một ma trận với một vectơ hoặc một ma trận khác. Nhưng điều gì xảy ra khi chúng ta thực hiện phép nhân ma trận với một giá trị vô hướng hoặc một số?

Kết quả của phép toán như vậy có được bằng cách nhân từng phần tử trong ma trận với giá trị vô hướng. Do đó, ma trận đầu ra có cùng kích thước với ma trận đầu vào

Lưu ý rằng 'np. matmul()’ không cho phép nhân ma trận với đại lượng vô hướng. Bạn có thể đạt được điều này bằng cách sử dụng np. dot() hoặc sử dụng toán tử ‘*’

Hãy xem điều này trong một ví dụ mã

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
5

đầu ra

Cách nhân ba ma trận trong Python

 

Phép nhân ma trận từng phần tử

Đôi khi ta muốn thực hiện phép nhân các phần tử tương ứng của hai ma trận có cùng dạng

Cách nhân ba ma trận trong Python

Thao tác này còn được gọi là Sản phẩm Hadamard. Nó chấp nhận hai ma trận có cùng kích thước và tạo ra ma trận thứ ba có cùng kích thước

Bạn có thể đạt được điều này bằng cách gọi hàm multi() của NumPy hoặc sử dụng toán tử '*'

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
6

đầu ra

Cách nhân ba ma trận trong Python

Quy tắc duy nhất mà bạn cần lưu ý khi thực hiện phép nhân theo nguyên tố là hai ma trận phải có cùng hình dạng
Tuy nhiên, nếu một thứ nguyên của ma trận bị thiếu, NumPy sẽ phát nó để khớp với hình dạng của ma trận khác

Trên thực tế, phép nhân ma trận với một đại lượng vô hướng cũng liên quan đến việc truyền giá trị vô hướng tới một ma trận có dạng bằng toán hạng ma trận trong phép nhân.

Điều đó có nghĩa là khi chúng ta nhân một ma trận có hình dạng (3,3) với giá trị vô hướng 10, NumPy sẽ tạo một ma trận có hình dạng khác (3,3) với các giá trị không đổi 10 tại tất cả các vị trí trong ma trận và thực hiện phép nhân theo từng phần tử giữa

Hãy hiểu điều này thông qua một ví dụ

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
7

đầu ra

Cách nhân ba ma trận trong Python

Lưu ý cách ma trận thứ hai, có hình dạng (1,4) được chuyển đổi thành ma trận (3,4) thông qua phát sóng và phép nhân phần tử khôn ngoan giữa hai ma trận diễn ra

 

Ma trận lũy thừa (Lũy thừa ma trận)

Giống như cách chúng ta có thể nâng một giá trị vô hướng lên một số mũ, chúng ta có thể thực hiện thao tác tương tự với ma trận
Giống như việc tăng một giá trị vô hướng (cơ số) lên số mũ n bằng với việc nhân n cơ số lặp đi lặp lại, mô hình tương tự cũng được quan sát thấy khi nâng ma trận thành lũy thừa, bao gồm phép nhân ma trận lặp đi lặp lại

Chẳng hạn, nếu chúng ta nâng ma trận A lên lũy thừa n, thì nó bằng phép nhân ma trận của n ma trận, tất cả sẽ là ma trận A

Cách nhân ba ma trận trong Python

Lưu ý rằng để có thể thực hiện thao tác này, ma trận cơ sở phải là hình vuông
Điều này là để đảm bảo số cột trong ma trận trước = số hàng trong ma trận tiếp theo

Hoạt động này được cung cấp trong Python bởi NumPy's linalg. matrix_power() phương thức này chấp nhận ma trận cơ sở và một lũy thừa nguyên làm tham số của nó

Chúng ta hãy xem một ví dụ trong Python

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
8

đầu ra

Cách nhân ba ma trận trong Python

Chúng ta có thể xác thực kết quả này bằng cách thực hiện phép nhân ma trận thông thường với ba toán hạng (tất cả đều là A), sử dụng toán tử '@'

import numpy as np
a = np.array([1, 3, 5, 7, 9])
b = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
print("Vector a:\n", a)
print()
print("Matrix b:\n", b)
9

đầu ra

Cách nhân ba ma trận trong Python

Như bạn có thể thấy, kết quả từ cả hai thao tác đều khớp

Một câu hỏi quan trọng nảy sinh từ thao tác này là – Điều gì xảy ra khi công suất bằng 0?
Để trả lời câu hỏi này, chúng ta hãy xem lại điều gì xảy ra khi chúng ta nâng một cơ số vô hướng lên lũy thừa 0
Chúng tôi nhận được giá trị 1, phải không?

Đó là ma trận nhận dạng

Vì vậy, nâng ma trận n x n lên lũy thừa 0 dẫn đến ma trận đơn vị I có dạng n x n

Hãy nhanh chóng kiểm tra điều này bằng Python, sử dụng ma trận A trước đây của chúng tôi

import numpy as np
a = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
b= np.array([10, 20, 30])
print("A =", a)
print("b =", b)
print("Ab =",np.matmul(a,b))
0

đầu ra

Cách nhân ba ma trận trong Python

lũy thừa theo nguyên tố

Giống như cách chúng ta có thể thực hiện phép nhân ma trận theo phần tử, chúng ta cũng có thể thực hiện phép lũy thừa theo phần tử i. e. , nâng từng phần tử riêng lẻ của ma trận lên một số lũy thừa

Điều này có thể đạt được trong Python bằng cách sử dụng toán tử số mũ tiêu chuẩn '**' – một ví dụ về nạp chồng toán tử

Một lần nữa, chúng ta có thể cung cấp một lũy thừa duy nhất cho tất cả các phần tử trong ma trận hoặc một ma trận lũy thừa cho từng phần tử trong ma trận cơ sở

Hãy xem các ví dụ về cả hai trong Python

import numpy as np
a = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
b= np.array([10, 20, 30])
print("A =", a)
print("b =", b)
print("Ab =",np.matmul(a,b))
1

đầu ra

Cách nhân ba ma trận trong Python

Nhân từ một chỉ số cụ thể

Giả sử chúng ta có ma trận A 5 x 6 và một ma trận B 3 x 3 khác. Rõ ràng, chúng ta không thể nhân hai cái này với nhau, vì sự không nhất quán về chiều

Nhưng nếu chúng ta muốn nhân một ma trận con 3x3 trong ma trận A với ma trận B trong khi giữ nguyên các phần tử khác trong A thì sao?
Để hiểu rõ hơn, tham khảo hình ảnh sau

Cách nhân ba ma trận trong Python

Bạn có thể đạt được thao tác này trong Python bằng cách sử dụng phép cắt ma trận để trích xuất ma trận con từ A, thực hiện phép nhân với B, sau đó viết lại kết quả tại chỉ mục có liên quan trong A

Hãy xem điều này trong hành động

import numpy as np
a = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
b= np.array([10, 20, 30])
print("A =", a)
print("b =", b)
print("Ab =",np.matmul(a,b))
2

đầu ra

Cách nhân ba ma trận trong Python

Như bạn có thể thấy, chỉ các phần tử ở chỉ số hàng từ 1 đến 3 và chỉ số cột từ 2 đến 4 được nhân với B và phần tử tương tự được viết lại trong A, trong khi các phần tử còn lại của A không thay đổi

Ngoài ra, không cần thiết phải ghi đè lên ma trận gốc. Chúng ta cũng có thể viết kết quả vào một ma trận mới bằng cách sao chép ma trận ban đầu vào một ma trận mới và sau đó viết tích vào vị trí của ma trận con

 

Nhân ma trận bằng GPU

Chúng tôi biết rằng NumPy tăng tốc các hoạt động của ma trận bằng cách song song hóa nhiều phép tính và sử dụng khả năng tính toán song song của CPU của chúng tôi

Tuy nhiên, các ứng dụng thời hiện đại cần nhiều hơn thế. CPU cung cấp khả năng tính toán hạn chế và không đủ cho số lượng lớn tính toán mà chúng ta cần, thường là trong các ứng dụng như học sâu

Đó là nơi GPU xuất hiện. Chúng cung cấp khả năng tính toán lớn và cơ sở hạ tầng tính toán song song xuất sắc, giúp chúng tôi tiết kiệm một lượng thời gian đáng kể bằng cách thực hiện hàng trăm nghìn thao tác trong vài giây

Trong phần này, chúng ta sẽ xem xét cách chúng ta có thể thực hiện phép nhân ma trận trên GPU thay vì CPU và tiết kiệm rất nhiều thời gian khi thực hiện việc này

NumPy không cung cấp chức năng thực hiện phép nhân ma trận trên GPU. Vì vậy, chúng tôi phải cài đặt một số thư viện bổ sung giúp chúng tôi đạt được mục tiêu của mình

Đầu tiên chúng ta sẽ cài đặt thư viện ‘scikit-cuda‘ và ‘PyCUDA‘. Các thư viện này giúp chúng tôi thực hiện tính toán trên GPU dựa trên CUDA. Để cài đặt các thư viện này từ thiết bị đầu cuối của bạn, nếu bạn đã cài đặt GPU trên máy của mình

import numpy as np
a = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
b= np.array([10, 20, 30])
print("A =", a)
print("b =", b)
print("Ab =",np.matmul(a,b))
3

Nếu không có GPU trên máy của mình, bạn có thể dùng thử Google Colab máy tính xách tay và bật quyền truy cập GPU; . Bây giờ chúng ta sẽ viết mã để tạo hai ma trận 1000×1000 và thực hiện phép nhân ma trận giữa chúng bằng hai phương thức

  1. Sử dụng phương thức 'matmul()' của NumPy trên CPU
  2. Sử dụng 'linalg' của scikit-cuda. mdot()' trên GPU

Trong phương pháp thứ hai, chúng tôi sẽ tạo ma trận trên CPU; . to_gpu()‘) trước khi thực hiện phép nhân giữa chúng. Chúng tôi sẽ sử dụng mô-đun 'thời gian' để tính toán thời gian tính toán trong cả hai trường hợp

Sử dụng CPU

import numpy as np
a = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
b= np.array([10, 20, 30])
print("A =", a)
print("b =", b)
print("Ab =",np.matmul(a,b))
4

đầu ra

Cách nhân ba ma trận trong Python

Trên một số hệ thống phần cứng cũ, bạn có thể gặp lỗi bộ nhớ, nhưng nếu may mắn, nó sẽ hoạt động trong một thời gian dài (tùy thuộc vào hệ thống của bạn)

Bây giờ, chúng ta hãy thực hiện phép nhân tương tự trên GPU và xem thời gian tính toán giữa hai loại này khác nhau như thế nào

Sử dụng GPU

import numpy as np
a = np.array([[1, 2, 3],
             [4, 5, 6],
             [7, 8, 9]])
b= np.array([10, 20, 30])
print("A =", a)
print("b =", b)
print("Ab =",np.matmul(a,b))
5

đầu ra

Cách nhân ba ma trận trong Python

Như chúng ta có thể thấy, thực hiện cùng một thao tác trên GPU sẽ cho chúng ta tốc độ tăng gấp 70 lần so với trên CPU
Đây vẫn là một tính toán nhỏ. Đối với các tính toán quy mô lớn, GPU giúp chúng tôi tăng tốc một vài bậc độ lớn

 

Phần kết luận

Trong hướng dẫn này, chúng ta đã xem xét cách phép nhân của hai ma trận diễn ra, các quy tắc chi phối chúng và cách triển khai chúng trong Python
Chúng tôi cũng đã xem xét các biến thể khác nhau của phép nhân ma trận tiêu chuẩn (và cách triển khai chúng trong NumPy) như phép nhân trên hai ma trận, chỉ phép nhân ở một chỉ số cụ thể hoặc lũy thừa của ma trận

Chúng tôi cũng đã xem xét các tính toán theo phần tử trong ma trận, chẳng hạn như phép nhân ma trận theo phần tử hoặc lũy thừa theo phần tử

Cuối cùng, chúng tôi đã xem xét cách chúng tôi có thể tăng tốc quá trình nhân ma trận bằng cách thực hiện chúng trên GPU

  • Chia sẻ trên facebook
  • Tweet trên Twitter

Mokhtar Ebrahim

Mokhtar là người sáng lập LikeGeek. com. Anh ấy làm quản trị viên hệ thống Linux từ năm 2010. Ông chịu trách nhiệm duy trì, bảo mật và khắc phục sự cố máy chủ Linux cho nhiều khách hàng trên khắp thế giới. Anh ấy thích viết các tập lệnh shell và Python để tự động hóa công việc của mình

Làm cách nào để nhân ma trận trong Python?

Ví dụ: nếu ma trận 1 có kích thước a * N và ma trận 2 có kích thước N * b, thì ma trận kết quả có kích thước a * b. Để nhân hai ma trận hãy sử dụng hàm dot() của NumPy . Chỉ cần 2 đối số và trả về tích của hai ma trận.

Bạn có thể nhân 3 ma trận có kích thước khác nhau không?

Bạn có thể nhân bao nhiêu ma trận tùy thích, miễn là thứ tự phép nhân và kích thước của ma trận sao cho phép nhân luôn được xác định rõ ràng .