根据长度列表创建一个新的张量

Creating a new tensor according to a list of lengths

我有一个张量 t,暗淡 b x 3 和一个长度列表 len = [l_0, l_1, ..., l_n]len 中的所有条目总和为 b。我想用 dim n x 3 创建一个新的张量,它将条目的平均值存储在 t 中。例如。 t 中的前 l_0 个条目被平均并构建新张量中的第一个元素。以下 l_1 个条目被平均并构建第二个元素,...

感谢您的帮助。

您可以结合使用索引的累积列表作为帮助器和列表理解来构建新数组:

>>> b, lens = 10, [2, 3, 1, 3, 1]

>>> t =  torch.rand(b, 3)
tensor([[0.3567, 0.3998, 0.9396],
        [0.4061, 0.6465, 0.6955],
        [0.3500, 0.4135, 0.5288],
        [0.0726, 0.9575, 0.3785],
        [0.6216, 0.2975, 0.3293],
        [0.3878, 0.0735, 0.8181],
        [0.1694, 0.5446, 0.1179],
        [0.7793, 0.6613, 0.1748],
        [0.0964, 0.9825, 0.1651],
        [0.1421, 0.0994, 0.8086]])

构建指数的累积列表:

>>> c = torch.cumsum(torch.tensor([0] + lens), 0)
tensor([ 0,  2,  5,  6,  9, 10])

两次循环 c,重叠 window。例如 zip(c[:-1], c[1:]) 效果很好。从 ij 的每个选择都在 dim=0 上取平均值。

>>> [t[i:j].sum(0) for i, j in zip(c[:-1], c[1:])]
[tensor([0.7628, 1.0463, 1.6351]),
 tensor([1.0442, 1.6685, 1.2367]),
 tensor([0.3878, 0.0735, 0.8181]),
 tensor([1.0451, 2.1885, 0.4578]),
 tensor([0.1421, 0.0994, 0.8086])]

然后你可以堆叠列表:

>>> torch.stack([t[i:j].sum(0) for i, j in zip(c[:-1], c[1:])])
tensor([[0.7628, 1.0463, 1.6351],
        [1.0442, 1.6685, 1.2367],
        [0.3878, 0.0735, 0.8181],
        [1.0451, 2.1885, 0.4578],
        [0.1421, 0.0994, 0.8086]])