Encontrar eficientemente el producto de puntos de dos listas de vectores almacenados como PyTorch tensors & guard backprop
Supongamos que tenía tensores X
y Y
que son ambos (batch_size, d)
dimensional. Me gustaría encontrar el (batch_size x 1)
tensor resultante de [X[0]@Y[0].T, X[1]@Y[1].T, ...]
Hay dos maneras que puedo pensar en hacer esto, ninguna de las cuales es particularmente eficiente.
Camino 1
product = torch.eye(batch_size) * [email protected]
product = torch.sum(product, dim=1)
Esto funciona, pero para grandes matrices hay una LOT de computaciones desperdiciadas
Camino 2
product = torch.cat(
[ X[i]@Y[i].T for i in X.size(0) ],
dim=0
)
Esto es bueno en que no se desperdician ciclos, pero no aprovechará ninguna de las ofertas de antorcha paralelismo incorporadas.
Soy consciente de que numpy tiene un método que hará esto, pero convertir los tensores a los arrays np destruirá la cadena de backpropagation, y esto es para una red neuronal, así que esa no es una opción.
¿Me estoy perdiendo un obvio método de antorcha, o estoy atrapado con estas dos opciones?
Pregunta hecha hace 3 años, 5 meses, 0 días - Por codecraftsman
3 Respuestas:
-
Una manera sería esto. Simplemente utilice la multiplicación de la matriz transmitida sobre vectores de filas re-en forma de
X
and column vectors ofY
.import torch X = X.reshape(batch_size, 1, d) Y = Y.reshape(batch_size, d, 1) product = torch.matmul(X, Y).squeeze(1)
El producto
product
tendrá la forma requerida(batch_size, 1)
con el resultado deseado.Respondida el Dec 16, 2020 a las 20:52 - por scriptsphinx
Votos positivos: 0 | Votos negativos: 0 -
Una forma más eficiente de calcular el producto de puntos de dos listas de vectores almacenados como PyTorch tensors y mantener el backpropagation es utilizando la función
torch.bmm
. Esta función realiza multiplicación de matrices batched. Aquí tienes un ejemplo de cómo se puede utilizar en tu caso:python import torch
Tensor X de shape (batch_size, d)
X = torch.randn(3, 2)Tensor Y de shape (batch_size, d)
Y = torch.randn(3, 2)Calcular el producto de puntos entre X e Y
expandimos Y para que tenga shape (batch_size, d, 1)
Y_expanded = Y.unsqueeze(2)Calculamos el producto de puntos entre X e Y^T
product = torch.bmm(X.unsqueeze(1), Y_expanded).squeeze() print(product)En este código, estamos expandiendo
Y
conunsqueeze(2)
para que tenga la forma(batch_size, d, 1)
, lo que nos permite realizar la multiplicación de matrices batched contorch.bmm
. Finalmente, utilizamossqueeze()
para eliminar la dimensión extra y obtener el resultado deseado.Esta forma es más eficiente ya que aprovecha las optimizaciones de PyTorch y también mantiene la cadena de backpropagation.
Respondida el Dec 17, 2020 a las 20:54 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Hay una forma más eficiente de calcular el producto punto de dos listas de vectores utilizando PyTorch, que aprovecha las operaciones vectoriales y evita bucles explícitos. Aquí tienes el código:
python import torch
Suponiendo que X e Y son tensores de PyTorch con dimensiones (batch_size, d)
X = torch.randn(32, 128) Y = torch.randn(32, 128)Calcular el producto punto usando la multiplicación matricial
product = torch.einsum("bd,bd->b", X, Y)Dar forma al tensor resultante a (batch_size x 1)
product = product.view(-1, 1)Explicación:
La función
torch.einsum()
realiza una operación de Einstein, que es una forma eficiente de realizar sumas sobre índices específicos. En este caso, estamos sumando sobre el índiced
deX
eY
. La forma resultante deproduct
es un tensor de forma(batch_size,)
, que se puede dar forma a(batch_size x 1)
usandoview()
.Esta solución es eficiente, aprovecha las operaciones vectoriales y mantiene la cadena de retropropagación.
Respondida el Dec 17, 2020 a las 20:59 - por Gemini
Votos positivos: 0 | Votos negativos: 0