Использование einsum для транспонирования времен матрицы транспонирования: x@A@x^T

Итак, у меня есть m различных векторов (скажем, x), каждый из которых равен (1,n), сложенных горизонтально, полностью в матрице (m,n), которую мы называем B, и матрицу (A) с размерностью (n, н).

Я хочу вычислить xAx^T для всех векторов x, результат должен быть (m,1)

Как мне написать запрос einsum для данных B и A?

Вот образец без einsum:

    import torch
    m = 30
    n = 4
    B = torch.randn(m, n)
    A = torch.randn(n, n)
    result = torch.zeros(m,1)
    for i in range(m):
        x = B[i].unsqueeze(0)
        result[i] = torch.matmul(x, torch.matmul(A, x.T))

Можете ли вы написать пример желаемого поведения с использованием цикла?

Nick ODell 25.08.2024 01:59

@NickODell Готово.

BiriBora 25.08.2024 02:03
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
2
66
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это эквивалент этого цикла:

result_einsum = torch.einsum('ki,ij,kj->k', B, A, B)[..., None]

Часть [..., None] существует для добавления дополнительного измерения к выводу. Не удалось понять, как это сделать с чистым einsum, хотя дополнительная часть, по крайней мере, не имеет копирования.

С (m,n) и (n,n)

res = np.einsum('ij,jk,lk-il', B,A,B)

должен создать массив (m,m).

'ij,jk,ik->i' должно составить (m,)

С matmul/@ я думаю, это даст

B@A@(B.T) # (m,m)

B[:,None,:]@A@B[:,:,None] # (m,1,1)

Пишу с телефона, поэтому проверить сейчас не могу.

Ответ принят как подходящий

Использование einsum и tensordot:

import torch
import numpy as np

A = torch.tensor([[1.0, 0.0, 0.0, 0.0],
                  [0.0, 2.0, 0.0, 0.0],
                  [0.0, 0.0, 3.0, 0.0],
                  [0.0, 0.0, 0.0, 4.0]])

B = torch.tensor([[1.0, 4.0, 7.0, 10.0],
                  [2.0, 5.0, 8.0, 11.0],
                  [3.0, 6.0, 9.0, 12.0]])

# Using einsum

res_using_einsum = torch.einsum('bi,ij,bj -> b',B,A,B).unsqueeze(dim = -1)
print(res_using_einsum)
'''
tensor([[580.],
        [730.],
        [900.]])
'''

# Using tensordot

BA = torch.tensordot(B, A, dims = ([1],[0]))
'''
BA :
tensor([[ 1.,  8., 21., 40.],
        [ 2., 10., 24., 44.],
        [ 3., 12., 27., 48.]])
'''
res_using_tensordot = torch.tensordot(BA, B, dims =([1],[1]))#.unsqueeze(-1)

'''
res_using_tensordot :

tensor([[580., 650., 720.],
        [650., 730., 810.],
        [720., 810., 900.]])
'''
diagonal_result = torch.diagonal(res_using_tensordot, 0).unsqueeze(1)
'''
tensor([[580.],
        [730.],
        [900.]])

'''

Другие вопросы по теме