【问题标题】:How to add two torch tensors along given dimension?如何沿给定维度添加两个火炬张量?
【发布时间】:2021-12-30 11:21:51
【问题描述】:

我有一个火炬张量pred,格式为 (B, 2, H, W),我想将两个不同的值 val1val2 与轴 1 上的通道相加。

我设法通过直接访问单个频道以“机械”方式做到这一点,例如:

def thresh_format(pred, val1, val2):
    tr = torch.zeros_like(pred)
    tr[:, 0, :, :] = tr[:, 0, :, :].add(val1)
    tr[:, 1, :, :] = tr[:, 1, :, :].add(val2)
    return pred + tr

但是我想知道是否有“更好”的方法来做到这一点,例如通过利用广播。我对documentation 的理解是广播是从尾随维度发生的,所以在这种情况下,我很困惑如何使它适用于维度 1。 有什么想法吗?

【问题讨论】:

    标签: python torch broadcasting


    【解决方案1】:

    实现这一点的最简单方法是将 val1 和 val2 堆叠在一个张量中,并对其进行整形以匹配 pred 张量沿公共维度的形状。

     pred + torch.tensor([val1, val2]).reshape((1,-1,1,1))
    

    这样,对于加法,torch 会自动沿 pred 具有更高阶的维度广播值。

    这与您将简单的标量值添加到张量时发生的情况非常相似,例如:

    >>> torch.ones((2, 2)) + 3.
    tensor([[4., 4.],
            [4., 4.]])
    

    但不是在加法过程中向张量的每个元素广播一个标量值,在上述情况下,这些值是沿着尚未匹配的维度广播的。

    >>> B=1; W=2; H=2; val1=3; val2=7
    >>> pred = torch.zeros((B,2,W,H))
    >>> val = torch.tensor([val1, val2]).reshape((1,-1,1,1))
    >>> pred
    tensor([[[[0., 0.],
              [0., 0.]],
    
             [[0., 0.],
              [0., 0.]]]])
    >>> val
    tensor([[[[3]],
    
             [[7]]]])
    >>> pred + val
    tensor([[[[3., 3.],
              [3., 3.]],
    
             [[7., 7.],
              [7., 7.]]]])
    

    【讨论】:

    • 非常感谢 :) 你能评论一下-1.reshape 中做什么吗?
    • 是的,它实现的效果与您编写 (1,2,1,1) 的效果相同,但它本质上是告诉 Torch 自己找出正确的尺寸。您在原始张量中有两个值->它们都需要在重塑期间到达某个地方->第二维中的“-1”表示:使用此维度作为值。引用 reshape 文档:“单个维度可能是 -1,在这种情况下,它是从剩余维度和输入中的元素数量推断出来的。” pytorch.org/docs/stable/generated/…
    • 太好了,非常感谢! :D 我会暂时打开它,看看是否会出现其他有趣的东西(我总是惊讶于我可以从其他用户的策略中学到很多我从未想过的东西):)
    猜你喜欢
    • 2021-09-27
    • 2022-07-20
    • 1970-01-01
    • 2020-10-26
    • 2021-08-06
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    相关资源
    最近更新 更多