0Pricing
Pandas & NumPy Academy · Lekcja

Mnożenie macierzy za pomocą np.matmul i @

Prawidłowo mnoż macierze za pomocą np.matmul i operatora @ oraz odróżniaj mnożenie element po elemencie (*) od właściwego mnożenia macierzy.

Mnożenie macierzy za pomocą np.matmul i @ to bezpłatna lekcja Pandas & NumPy Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Pandas & NumPy Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.

Dlaczego mnożenie macierzy ma znaczenie

Mnożenie macierzy jest podstawą analityki danych i uczenia maszynowego. Stanowi fundament sieci neuronowych, redukcji wymiarowości i transformacji liniowych. W Pythonie NumPy udostępnia dwa wygodne sposoby mnożenia macierzy: funkcję np.matmul() oraz operator @ wprowadzony w Pythonie 3.5. Oba rozwiązania są szybkie, zwektoryzowane i znacznie wydajniejsze niż zagnieżdżone pętle Pythona.

Zasady mnożenia macierzy

Dla dwóch macierzy A i B iloczyn A @ B jest prawidłowy tylko wtedy, gdy liczba kolumn macierzy A jest równa liczbie wierszy macierzy B. Jeśli A ma kształt (m, n), a B kształt (n, k), wynik ma kształt (m, k). Zasada ta jest nazywana ograniczeniem wymiarów wewnętrznych i obowiązuje niezależnie od użytej funkcji NumPy.

import numpy as np
A = np.array([[1, 2], [3, 4]])   # shape (2, 2)
B = np.array([[5, 6], [7, 8]])   # shape (2, 2)
C = A @ B
print(C)  # [[19 22] [43 50]]

np.matmul a operator @

np.matmul(A, B) i A @ B dają identyczne wyniki dla tablic 2D. Operator @ jest po prostu cukrem składniowym — w tle wywołuje __matmul__, które NumPy implementuje za pomocą tej samej procedury BLAS na poziomie C. W codziennym kodzie używaj @ ze względu na czytelność; używaj np.matmul, gdy chcesz przekazać funkcję jako obiekt wywoływalny lub jawnie obsłużyć przypadki brzegowe.

import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(np.matmul(A, B))   # same as A @ B
print(A @ B)             # same result

Odróżnianie @ od * i np.dot

NumPy ma trzy funkcje mnożenia, które łatwo pomylić. A * B oznacza mnożenie element po elemencie (iloczyn Hadamarda). np.dot(A, B) działa jak np.matmul dla tablic 2D, ale dla większej liczby wymiarów ma inną semantykę. A @ B oznacza ściśle mnożenie macierzy i dokładnie odpowiada definicji matematycznej — w przypadku pracy z macierzami wybieraj je zamiast np.dot.

import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print('element-wise:', A * B)    # [[5 12] [21 32]]
print('matmul:', A @ B)          # [[19 22] [43 50]]

Mnożenie macierzy nie jest przemienne

W przeciwieństwie do mnożenia skalarów mnożenie macierzy nie jest przemienne: A @ B na ogół różni się od B @ A. Kształty macierzy mogą nawet nie być zgodne w obu kierunkach. Ma to znaczenie podczas zapisywania transformacji — kolejność działań zmienia wynik. Zawsze kontroluj, która macierz znajduje się po lewej, a która po prawej stronie.

import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[0, 1], [1, 0]])
print('A @ B:', A @ B)   # [[2 1] [4 3]]
print('B @ A:', B @ A)   # [[3 4] [1 2]]  -- different!

Mnożenie macierzy w partiach

Gdy tablice mają więcej niż dwa wymiary, np.matmul i @ traktują dodatkowe wymiary początkowe jako wymiary partii i mnożą macierze równolegle. Na przykład pomnożenie tablicy o kształcie (32, 3, 4) przez tablicę o kształcie (32, 4, 5) daje wynik o kształcie (32, 3, 5) — jednocześnie wykonywanych jest 32 niezależnych mnożeń 3×4 @ 4×5. W ten sposób frameworki uczenia głębokiego wydajnie przetwarzają mini partie.

import numpy as np
batch_A = np.random.rand(32, 3, 4)
batch_B = np.random.rand(32, 4, 5)
result = batch_A @ batch_B
print(result.shape)  # (32, 3, 5)

Mnożenie macierzy przez wektor

Typowym przypadkiem szczególnym jest mnożenie macierzy przez wektor. Jeśli A ma kształt (m, n), a v jest tablicą 1D o długości n, wówczas A @ v daje tablicę 1D o długości m. NumPy automatycznie dopasowuje kształty — nie trzeba przekształcać v w wektor kolumnowy. Ten wzorzec występuje wszędzie: przy stosowaniu wag w regresji liniowej, rzutowaniu cech oraz jednoczesnym obliczaniu iloczynów skalarnych dla każdego wiersza.

import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6]])  # (2, 3)
v = np.array([1, 0, -1])              # (3,)
print(A @ v)   # [1-3, 4-6] = [-2, -2]

Wydajność: @ a pętle Pythona

Mnożenie macierzy w NumPy korzysta ze zoptymalizowanych procedur BLAS/LAPACK i wykonuje się w skompilowanym kodzie C. Zagnieżdżona pętla napisana wyłącznie w Pythonie, implementująca tę samą operację, jest zazwyczaj 100–1000 razy wolniejsza dla dużych macierzy. Gdy w potoku danych potrzebujesz wielokrotnie mnożyć macierze — na przykład podczas transformacji cech, rzutowań PCA czy aktualizacji wag — zawsze używaj @ lub np.matmul i nigdy nie implementuj samodzielnie pętli wewnętrznej.

import numpy as np, time
A = np.random.rand(500, 500)
B = np.random.rand(500, 500)
t0 = time.time()
C = A @ B
print(f'NumPy: {(time.time()-t0)*1000:.1f} ms')  # single-digit ms

Łączenie wielu iloczynów macierzy

Możesz łączyć wiele operacji @ w jednym wyrażeniu: A @ B @ C jest obliczane od lewej do prawej. NumPy nie optymalizuje automatycznie kolejności mnożenia (w przeciwieństwie do MATLAB-owego mtimes), więc jeśli macierze mają bardzo różne rozmiary, kolejność może wpływać na szybkość działania. W przypadku trzech lub większej liczby macierzy rozważ użycie np.linalg.multi_dot([A, B, C]), które automatycznie wybiera najbardziej wydajne parowanie.

import numpy as np
A = np.random.rand(100, 20)
B = np.random.rand(20, 50)
C = np.random.rand(50, 10)
result = np.linalg.multi_dot([A, B, C])
print(result.shape)  # (100, 10)

Typowe błędy kształtu i sposoby ich naprawy

Najczęstszym błędem podczas mnożenia macierzy jest niezgodność kształtów: ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0. Aby go naprawić, należy sprawdzić kształty za pomocą A.shape i upewnić się, że wymiary wewnętrzne są zgodne. Jeśli mają Państwo wektor wierszowy o kształcie (n,), który powinien być traktowany jako wektor kolumnowy o kształcie (n, 1), należy użyć v.reshape(-1, 1). Jeśli potrzebna jest transpozycja, należy użyć A.T.

import numpy as np
A = np.ones((3, 4))
B = np.ones((3, 4))  # wrong -- inner dims 4 != 3
try:
    A @ B
except ValueError as e:
    print('Error:', e)
print('Fix:', (A @ B.T).shape)  # (3, 3)

Praktyczny przykład: transformacja cech

Typowy przypadek użycia w data science: mają Państwo zbiór danych X o kształcie (n_samples, n_features) oraz macierz wag W o kształcie (n_features, n_outputs). Iloczyn macierzy X @ W stosuje transformację liniową jednocześnie do każdej próbki, uzyskując kształt (n_samples, n_outputs). Jest to podstawowe działanie warstwy liniowej w sieci neuronowej oraz predykcji regresji liniowej.

import numpy as np
n_samples, n_features, n_outputs = 200, 10, 3
X = np.random.rand(n_samples, n_features)
W = np.random.rand(n_features, n_outputs)
b = np.zeros(n_outputs)
predictions = X @ W + b   # shape (200, 3)
print(predictions.shape)

Szybki test

Sprawdźcie Państwo swoją wiedzę na temat mnożenia macierzy w NumPy.

Podsumowanie lekcji

W tej lekcji nauczyli się Państwo, że: np.matmul i @ implementują właściwe mnożenie macierzy (a nie mnożenie element po elemencie), wymiary wewnętrzne obu macierzy muszą być zgodne, a @ obsługuje mnożenie wsadowe w wymiarach wiodących. Następnie omówimy wyznaczniki, macierze odwrotne i transpozycje — operacje, które informują, czy macierz można „odwrócić”.

Często zadawane pytania

Czy lekcja „Mnożenie macierzy za pomocą np.matmul i @” jest bezpłatna?

Tak — pełny tekst „Mnożenie macierzy za pomocą np.matmul i @” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Pandas & NumPy Academy, przejdź na CoddyKit PRO. Kurs Pandas & NumPy Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Mnożenie macierzy za pomocą np.matmul i @”?

Prawidłowo mnoż macierze za pomocą np.matmul i operatora @ oraz odróżniaj mnożenie element po elemencie (*) od właściwego mnożenia macierzy. Ćwiczysz Pandas & NumPy Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Pandas & NumPy Academy?

Nie wymagamy żadnego doświadczenia. Pandas & NumPy Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Mnożenie macierzy za pomocą np.matmul i @”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Pandas & NumPy Academy?

Tak. Każda lekcja Pandas & NumPy Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Mnożenie macierzy za pomocą np.matmul i @
  2. Wyznaczniki, macierze odwrotne i transpozycje
  3. Rozwiązywanie układów równań liniowych
  4. Wartości własne i przegląd SVD
← Powrót do Pandas & NumPy Academy