Je suis récemment passé à Python 3.5 et j'ai remarqué que le nouvel opérateur de multiplication matricielle (@) se comporte parfois différemment de l' opérateur numpy dot . Par exemple, pour les tableaux 3D:
import numpy as np
a = np.random.rand(8,13,13)
b = np.random.rand(8,13,13)
c = a @ b # Python 3.5+
d = np.dot(a, b)
L' @
opérateur renvoie un tableau de forme:
c.shape
(8, 13, 13)
tandis que la np.dot()
fonction renvoie:
d.shape
(8, 13, 8, 13)
Comment puis-je reproduire le même résultat avec numpy dot? Y a-t-il d'autres différences significatives?
matmul
fonction il y a des années?@
en tant qu'opérateur infixe est nouveau, mais la fonction fonctionne aussi bien sans lui.Réponses:
L'
@
opérateur appelle la__matmul__
méthode du tableau , nondot
. Cette méthode est également présente dans l'API en tant que fonctionnp.matmul
.De la documentation:
Le dernier point montre clairement que
dot
etmatmul
méthodes se comportent différemment lorsqu'elles sont transmises à des tableaux 3D (ou de dimension supérieure). Citant un peu plus la documentation:Pour
matmul
:Pour
np.dot
:la source
La réponse de @ajcr explique comment le
dot
etmatmul
(invoqué par le@
symbole) diffèrent. En regardant un exemple simple, on voit clairement comment les deux se comportent différemment lorsqu'ils fonctionnent sur des «piles de matrices» ou tenseurs.Pour clarifier les différences, prenez un tableau 4x4 et retournez le
dot
produit et lematmul
produit avec une «pile de matrices» ou tenseur 3x4x2.Les produits de chaque opération apparaissent ci-dessous. Remarquez comment le produit scalaire est,
et comment le produit matriciel est formé en diffusant la matrice ensemble.
la source
a = np.arange(24).reshape(3, 4, 2)
créer un tableau avec les dimensions 3x4x2.Juste
@
pour info , et ses équivalents numpydot
etmatmul
sont tous à peu près également rapides. (Terrain créé avec perfplot , un de mes projets.)Code pour reproduire le tracé:
la source
En mathématiques, je pense que le point dans numpy a plus de sens
puisqu'elle donne le produit scalaire lorsque a et b sont des vecteurs, ou la multiplication matricielle lorsque a et b sont des matrices
Quant à l' opération matmul dans numpy, elle se compose de parties de résultat de point et peut être définie comme
> matmul (a, b) _ {i, j, k, c} =
Ainsi, vous pouvez voir que matmul (a, b) renvoie un tableau avec une petite forme, qui consomme moins de mémoire et qui a plus de sens dans les applications. En particulier, en combinant avec la diffusion , vous pouvez obtenir
par exemple.
À partir des deux définitions ci-dessus, vous pouvez voir les conditions requises pour utiliser ces deux opérations. Supposons que a.shape = (s1, s2, s3, s4) et b.shape = (t1, t2, t3, t4)
Pour utiliser le point (a, b), vous avez besoin
Pour utiliser matmul (a, b), vous avez besoin
Utilisez le morceau de code suivant pour vous convaincre.
Exemple de code
la source
np.matmul
donne également le produit scalaire sur les vecteurs et le produit matriciel sur les matrices.Voici une comparaison avec
np.einsum
pour montrer comment les indices sont projetésla source
Mon expérience avec MATMUL et DOT
J'obtenais constamment "ValueError: la forme des valeurs passées est (200, 1), les indices impliquent (200, 3)" en essayant d'utiliser MATMUL. Je voulais une solution de contournement rapide et j'ai trouvé que DOT offrait la même fonctionnalité. Je n'obtiens aucune erreur en utilisant DOT. J'ai la bonne réponse
avec MATMUL
avec DOT
la source