умножение каждого элемента матрицы на вектор (или массив)

#python-3.x #pytorch

#python-3.x #pytorch

Вопрос:

Допустим, у меня есть входной массив размера (64,100)

 t = torch.randn((64,100))
 

Теперь предположим, что я хочу умножить каждый из 6400 элементов t на 6400 separate vectors каждый из размеров 256 , чтобы получить tensor размер [64, 100, 256] . Это то, что я делаю в настоящее время —

 import copy
def clones(module, N):
    "Produce N identical layers."
    return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])

linears = clones(nn.Linear(1,256, bias=False), 6400)

idx = 0
t_final = []
for i in range(64):
    t_bs = []
    for j in range(100):
        t1 = t[i, j] * linears[idx].weight.view(-1)
        idx  = 1
        t_bs.append(t1)
    t_bs = torch.cat(t_bs).view(1, 100, 256)
    t_final.append(t_bs)
t_final = torch.cat(t_final)
print(t_final.shape)
Output: torch.Size([64, 100, 256])
 

Есть ли более быстрый и чистый способ сделать то же самое? Я пытался torch.matmul , torch.dot но не смог сделать лучше.

Ответ №1:

Кажется broadcast , это то, что вы ищете.

 t = torch.randn((64,100)).view(6400, 1)
weights = torch.randn((6400, 256))

output = (t * weights).view(64, 100, 256)
 

Ответ №2:

На самом деле вам не нужно клонировать свой линейный слой, если вы действительно хотите умножить тенор t на один и тот же вес линейного слоя на 6400 раз. скорее вы можете сделать следующее:

 t = torch.randn((64,100)).unsqueeze(-1)
w = torch.rand((256)).view(1,1,256).repeat(64, 100, 1)
#or
w = torch.stack(6400*[torch.rand((256))]).view(64,100,256)
result = t*w  # shape: [64, 100, 256]
 

Однако, если вы хотите сохранить ту же структуру, что и в настоящее время, вы можете сделать что-то следующее:

 t = torch.randn((64,100)).unsqueeze(-1)
w = torch.stack([linears[i].weight for i in range(len(linears))]).view(64,100,256)
result = t*w  # shape: [64, 100, 256]