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 of Y.

    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 con unsqueeze(2) para que tenga la forma (batch_size, d, 1), lo que nos permite realizar la multiplicación de matrices batched con torch.bmm. Finalmente, utilizamos squeeze() 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 índice d de X e Y. La forma resultante de product es un tensor de forma (batch_size,), que se puede dar forma a (batch_size x 1) usando view().

    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