Факел суммы подмножеств тензора - PullRequest
0 голосов
/ 04 августа 2020

если тензор имеет форму [20, 5], то мне нужно взять 10 за раз и просуммировать их, поэтому результат будет [2,5].

например: shape [20,5] -> shape [2, 5] (сумма 10 за раз) shape [100, 20] -> shape [10,20] (сумма 10 за раз)

Есть ли более быстрый / оптимальный способ сделать это?

например: [[1, 1], [1, 2], [3, 4], [1,2]] я хочу [[2, 3], [4, 6]], взяв сумму из 2 строк.

Ответы [ 2 ]

2 голосов
/ 04 августа 2020

Это не совсем понятно, но я не могу использовать для этого комментарий, поэтому

Для первого случая у вас есть:

t1 = torch.tensor([[1., 1.], [1., 2.], [3., 4.], [1.,2.]])
t1.shape #=> torch.Size([4, 2])
t1
tensor([[1., 1.],
        [1., 2.],
        [3., 4.],
        [1., 2.]])

Чтобы получить желаемый результат, вы должны изменить форму :

tr1 = t1.reshape([2, 2, 2])
res1 = torch.sum(tr1, axis = 1)
res1.shape #=> torch.Size([2, 2])
res1
tensor([[2., 3.],
        [4., 6.]])

Давайте возьмем тензор со всеми единичными элементами ( torch.ones ) для второго случая.

t2 = torch.ones((20, 5))
t2.shape #=> torch.Size([20, 5])
t2
tensor([[1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.],
        [1., 1., 1., 1., 1.]])

Итак, преобразование в получите требуемый (?) результат:

tr2 = tensor.reshape((10, 2, 5))
res2 = torch.sum(tr2, axis = 0)
res2.shape #=> torch.Size([2, 5])
res2
tensor([[10., 10., 10., 10., 10.],
        [10., 10., 10., 10., 10.]])

Это то, что вы ищете?

0 голосов
/ 04 августа 2020

Мне не известно о каком-либо готовом решении для этого.

Если среднего достаточно, вы можете использовать nn.AvgPool1d https://pytorch.org/docs/stable/generated/torch.nn.AvgPool1d.html#avgpool1d:

import torch, torch.nn as nn

input = torch.rand(batch_size, channels, lenght)
pool = nn.AvgPool1D(kernel_size=10, stride=10)

avg = pool(input)

Используя это решение, просто убедитесь, что вы усредняете правильное измерение.

Вы также можете просто написать свою собственную функцию, которая будет выполнять суммирование за вас:

import torch

def SumWindow(input, window_size, dim):
    input_split = torch.split(input, window_size, dim)
    input_sum = [v.sum(dim=dim), for v in input_split] # may be expensive if there are too many tensors
    out = torch.cat(inptu_sum, dim=dim)
    return dim
...