Recientemente me mudé a Python 3.5 y noté que el nuevo operador de multiplicación de matrices (@) a veces se comporta de manera diferente al operador de puntos numpy . Por ejemplo, para matrices 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)
El @
operador devuelve una matriz de forma:
c.shape
(8, 13, 13)
mientras que la np.dot()
función devuelve:
d.shape
(8, 13, 8, 13)
¿Cómo puedo reproducir el mismo resultado con numpy dot? ¿Existen otras diferencias significativas?
matmul
función hace años?@
como operador infijo es nuevo, pero la función funciona igual de bien sin él.Respuestas:
El
@
operador llama al__matmul__
método de la matriz , nodot
. Este método también está presente en la API como funciónnp.matmul
.De la documentación:
El último punto deja en claro que los métodos
dot
y sematmul
comportan de manera diferente cuando se pasan matrices 3D (o de mayor dimensión). Citando algo más de la documentación:Para
matmul
:Para
np.dot
:fuente
La respuesta de @ajcr explica cómo difieren
dot
ymatmul
(invocados por el@
símbolo). Al observar un ejemplo simple, se ve claramente cómo los dos se comportan de manera diferente cuando operan en "pilas de matrices" o tensores.Para aclarar las diferencias, tome una matriz 4x4 y devuelva el
dot
producto y elmatmul
producto con una 'pila de matrices' o tensor de 3x4x2.Los productos de cada operación aparecen a continuación. Observe cómo es el producto escalar,
y cómo se forma el producto de la matriz al difundir la matriz en conjunto.
fuente
a = np.arange(24).reshape(3, 4, 2)
sería crear una matriz con las dimensiones 3x4x2.Para su información,
@
y sus equivalentes numpydot
ymatmul
son todos más o menos igual de rápido. (Parcela creada con perfplot , un proyecto mío).Código para reproducir la trama:
fuente
En matemáticas, creo que el punto en numpy tiene más sentido
ya que da el producto escalar cuando ayb son vectores, o la multiplicación de matrices cuando ayb son matrices
En cuanto a la operación matmul en numpy, consta de partes del resultado del punto , y se puede definir como
> matmul (a, b) _ {i, j, k, c} =
Entonces, puede ver que matmul (a, b) devuelve una matriz con una forma pequeña, que tiene un menor consumo de memoria y tiene más sentido en las aplicaciones. En particular, combinándolo con la radiodifusión , puede obtener
por ejemplo.
De las dos definiciones anteriores, puede ver los requisitos para utilizar esas dos operaciones. Suponga a.shape = (s1, s2, s3, s4) y b.shape = (t1, t2, t3, t4)
Para usar el punto (a, b) necesitas
Para usar matmul (a, b) necesitas
Utilice el siguiente código para convencerse.
Muestra de código
fuente
np.matmul
también da el producto escalar en vectores y el producto matricial en matrices.Aquí hay una comparación con
np.einsum
para mostrar cómo se proyectan los índicesfuente
Mi experiencia con MATMUL y DOT
Constantemente recibía "ValueError: La forma de los valores pasados es (200, 1), los índices implican (200, 3)" cuando intentaba usar MATMUL. Quería una solución rápida y encontré que DOT ofrecía la misma funcionalidad. No obtengo ningún error al usar DOT. Obtengo la respuesta correcta
con MATMUL
con DOT
fuente