【问题标题】:''Boolean value of Tensor with more than one value is ambiguous'' when broadcasting torch Tensor广播火炬张量时,“具有多个值的张量的布尔值不明确”
【发布时间】:2021-12-07 00:38:57
【问题描述】:

我的目标是提取 pytorch 张量的维度,其索引不在给定列表中。我想使用广播来做到这一点,如下所示:

Sim = torch.rand((5, 5))
samples_idx = [0]  # the index of dim that I don't want to extract
a = torch.arange(Sim.size(0)) not in samples_idx
result = Sim[a]

我假设 a 将是一个具有 True/Flase 且维度为 5 的张量。但我收到错误 RuntimeError: Boolean value of Tensor with more than one value is ambiguous。谁能帮我指出哪里出错了?谢谢。

【问题讨论】:

  • 不清楚你所说的“提取维度”是什么意思,能否提供一个你想要的输入输出示例?
  • 以给出的代码为例。我想提取张量 Sim 的第 1-4 行(不包括 0)以形成子张量。我不想提取的维度索引将添加到列表中。它可能包含几个不连续的索引。所以我需要获取一个布尔Tensor来显示我是否需要对应的维度。

标签: python pytorch tensor broadcast


【解决方案1】:

也许这有点失焦,但您也可以尝试使用布尔索引。

>>> Sim = torch.rand((5, 5))
tensor([[0.8128, 0.2024, 0.3673, 0.2038, 0.3549],
        [0.4652, 0.4304, 0.4987, 0.2378, 0.2803],
        [0.2227, 0.1466, 0.6736, 0.0929, 0.3635],
        [0.2218, 0.9078, 0.2633, 0.3935, 0.2199],
        [0.7007, 0.9650, 0.4192, 0.4781, 0.9864]])

>>> samples_idx = [0]
>>> a = torch.ones(Sim.size(0))
>>> a[samples_idx] = 0
>>> result = Sim[a.bool(), :]
tensor([[0.4652, 0.4304, 0.4987, 0.2378, 0.2803],
        [0.2227, 0.1466, 0.6736, 0.0929, 0.3635],
        [0.2218, 0.9078, 0.2633, 0.3935, 0.2199],
        [0.7007, 0.9650, 0.4192, 0.4781, 0.9864]])

这样您就不必遍历所有 samples_idx 列表来检查是否包含。

【讨论】:

    【解决方案2】:

    在“维度”和“索引”的概念之间存在误解。您想要过滤 Sim 并仅保留索引与给定规则匹配的行(第 0 维)。

    你可以这样做:

    Sim = torch.rand((5, 5))
    samples_idx = [0]  # the index of dim that I don't want to extract
    a = [v for v in range(Sim.size(0)) if v not in samples_idx]
    result = Sim[a]
    

    a 不是布尔张量,而是要保留的索引列表。然后,您可以使用它在第 0 维(行)上为 Sim 编制索引。

    not in 不是可以广播的操作,您应该使用常规的 Python 理解列表。

    【讨论】:

    • 感谢您的回答和澄清。这真的很有帮助:)
    【解决方案3】:

    您可以通过从包含所有索引的集合中减去 samples_idx 来创建包含所需索引的集合:

    >>> Sim = torch.rand(5, 5)
    tensor([[0.9069, 0.3323, 0.8358, 0.3738, 0.3516],
            [0.1894, 0.5747, 0.0763, 0.8526, 0.2351],
            [0.0304, 0.7631, 0.3799, 0.9968, 0.6143],
            [0.0647, 0.2307, 0.4061, 0.9648, 0.0212],
            [0.8479, 0.6400, 0.0195, 0.2901, 0.4026]])
    
    >>> samples_idx = [0]
    

    以下内容基本上充当您的torch.arange not in sample_idx

    >>> idx = set(range(len(Sim))) - set(samples_idx)
    {1, 2, 3, 4}
    

    然后用idx进行索引:

    >>> Sim[tuple(idx),:]
    tensor([[0.1894, 0.5747, 0.0763, 0.8526, 0.2351],
            [0.0304, 0.7631, 0.3799, 0.9968, 0.6143],
            [0.0647, 0.2307, 0.4061, 0.9648, 0.0212],
            [0.8479, 0.6400, 0.0195, 0.2901, 0.4026]])
    

    【讨论】:

    • 感谢您的回答,@Ivan。这有助于实现我的功能。但是我还是想知道torch.arange not in sample_idx这个错误背后的原因。为什么我不能使用not in list进行广播?
    猜你喜欢
    • 2022-01-12
    • 1970-01-01
    • 2019-11-14
    • 2019-06-08
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    相关资源
    最近更新 更多