PyTorch: как умножить элементы в списке, содержащем кортежи целых и тензорных чисел

#python #loops #pytorch #matrix-multiplication

#питон #петли #пыторч #матрица-умножение

Вопрос:

У меня есть следующий список ABC_lst , содержащий кортежи целого числа и тензора.

Код:

 import numpy as np
import torch

A_int = 40
A_tsr = torch.tensor(np.array([[1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]]))
A_tpl = (A_int, A_tsr)

B_int = 42
B_tsr = torch.tensor(np.array([[4,5,6,7,8], [4,5,6,7,8], [4,5,6,7,8], [4,5,6,7,8], [4,5,6,7,8]]))
B_tpl = (B_int, B_tsr)

C_int = 38
C_tsr = torch.tensor(np.array([[7,8,9,10,11], [7,8,9,10,11], [7,8,9,10,11], [7,8,9,10,11], [7,8,9,10,11]]))
C_tpl = (C_int, C_tsr)

ABC_lst = [A_tpl, B_tpl, C_tpl]
ABC_lst
 

Выходной сигнал:

 [(40, tensor([[1, 2, 3, 4, 5],
          [1, 2, 3, 4, 5],
          [1, 2, 3, 4, 5],
          [1, 2, 3, 4, 5],
          [1, 2, 3, 4, 5]])),
 (42, tensor([[4, 5, 6, 7, 8],
          [4, 5, 6, 7, 8],
          [4, 5, 6, 7, 8],
          [4, 5, 6, 7, 8],
          [4, 5, 6, 7, 8]])),
 (38, tensor([[ 7,  8,  9, 10, 11],
          [ 7,  8,  9, 10, 11],
          [ 7,  8,  9, 10, 11],
          [ 7,  8,  9, 10, 11],
          [ 7,  8,  9, 10, 11]]))]
 

Как мне умножить целое число на соответствующий тензор, например. умножить 40 на

 tensor([[1, 2, 3, 4, 5],
          [1, 2, 3, 4, 5],
          [1, 2, 3, 4, 5],
          [1, 2, 3, 4, 5],
          [1, 2, 3, 4, 5]])
 

умножить 42 на

 tensor([[4, 5, 6, 7, 8],
          [4, 5, 6, 7, 8],
          [4, 5, 6, 7, 8],
          [4, 5, 6, 7, 8],
          [4, 5, 6, 7, 8]])
 

и так далее.

Возвращаемый объект должен быть тензором, который выглядит следующим образом:

 tensor([[[ 40.,  80., 120., 160., 200.],
         [ 40.,  80., 120., 160., 200.],
         [ 40.,  80., 120., 160., 200.],
         [ 40.,  80., 120., 160., 200.],
         [ 40.,  80., 120., 160., 200.]],

        [[168., 210., 252., 294., 336.],
         [168., 210., 252., 294., 336.],
         [168., 210., 252., 294., 336.],
         [168., 210., 252., 294., 336.],
         [168., 210., 252., 294., 336.]],

        [[266., 304., 342., 380., 418.],
         [266., 304., 342., 380., 418.],
         [266., 304., 342., 380., 418.],
         [266., 304., 342., 380., 418.],
         [266., 304., 342., 380., 418.]]])
 

В приведенном выше примере у меня есть 3 «набора» целых и тензорных чисел. Как мне обобщить код для приведенного выше умножения для любых произвольных «наборов» целых и тензорных чисел?

Был бы очень признателен, если бы кто-нибудь мог помочь.

РЕДАКТИРОВАТЬ: мне нужно сделать все вышеперечисленное в графическом процессоре, поэтому нужно работать с тензорами.

Ответ №1:

Начиная с двух списков: I списка целых чисел и X списка тензоров:

 I = [torch.tensor(40), torch.tensor(42), torch.tensor(38)]
X = [
    torch.tensor([[1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]]),
    torch.tensor([[4,5,6,7,8], [4,5,6,7,8], [4,5,6,7,8], [4,5,6,7,8], [4,5,6,7,8]]),
    torch.tensor([[7,8,9,10,11], [7,8,9,10,11], [7,8,9,10,11], [7,8,9,10,11], [7,8,9,10,11]]), 
]
 

Вы можете сжать оба и создать список, содержащий все результаты умножения. Затем сложите этот список в один тензор, например:

 torch.stack([i*x for i, x in zip(I, X)])
 

Вы, конечно, можете добавить больше элементов в свои списки.

Комментарии:

1. Спасибо @Ivan. Мне нужно A_tsr , B_tsr и C_tsr быть тензорами (а не массивами, как в вашем примере). Кроме того, я забыл упомянуть, что мне нужно работать в GPU, поэтому np.stack массивы не будут работать (я обновил свой пост об использовании GPU, извините за это).

2. Я обновил свой ответ, дайте мне знать, если это сработает для вас.

3. На самом деле, я думаю, что я заставил это работать, используя torch.stack([s*x for s, x in zip(scalars, X)]) where my scalars = tensor([40., 42., 38.], device='cuda:0', dtype=torch.float64) и X is — это один тензор в cuda формы torch.Size([3, 5, 5])