【问题标题】:How to apply the torch.inverse() function of PyTorch to every sample in the batch?如何将 PyTorch 的 torch.inverse() 函数应用于批次中的每个样本?
【发布时间】:2018-03-17 15:15:09
【问题描述】:

这似乎是一个基本问题,但我无法解决。

在我的神经网络的正向传递中,我有一个形状为 8x3x3 的输出张量,其中 8 是我的批量大小。我们可以假设每个 3x3 张量是一个非奇异矩阵。我需要找到这些矩阵的逆矩阵。 PyTorch inverse() 函数仅适用于方阵。由于我现在有 8x3x3,如何以可微分的方式将此函数应用于批次中的每个矩阵?

如果我遍历样本并将逆向附加到 python 列表,然后我将其转换为 PyTorch 张量,在反向传播期间是否会出现问题? (我问的是因为将 PyTorch 张量转换为 numpy 以执行某些操作,然后再返回张量不会在此类操作的反向传播期间计算梯度)

当我尝试做类似的事情时,我也会收到以下错误。

a = torch.arange(0,8).view(-1,2,2)
b = [m.inverse() for m in a]
c = torch.FloatTensor(b)

TypeError: 'torch.FloatTensor' 对象不支持索引

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    编辑:

    从 Pytorch 1.0 版开始,torch.inverse 现在支持批量张量。见here。所以你可以简单地使用内置函数torch.inverse

    老答案

    计划很快实施批量逆。有关讨论,请参见例如 issue 7500issue 9102。但是,在撰写本文时,当前的稳定版本(0.4.1)还没有批量逆操作可用。

    话虽如此,最近添加了对torch.gesv 的批量支持。这可以(ab)用于定义您自己的批量逆运算,如下所示:

    def b_inv(b_mat):
        eye = b_mat.new_ones(b_mat.size(-1)).diag().expand_as(b_mat)
        b_inv, _ = torch.gesv(eye, b_mat)
        return b_inv
    

    我发现在 GPU 上运行时,这比 for 循环提供了很好的加速。

    【讨论】:

    • 目前这似乎是最好的选择。谢谢。
    • torch.gesv 的替代方案是什么?好像已经被弃用了。
    • torch.gesv 已在 pytorch-1.2.0 (source) 中替换为 torch.solve
    【解决方案2】:

    您可以使用torch.functional.unbind() 拆分张量,对结果的每个元素应用逆,然后再叠加:

    a = torch.arange(0,8).view(-1,2,2)
    b = [t.inverse() for t in torch.functional.unbind(a)]
    c = torch.functional.stack(b)
    

    【讨论】:

    • 这看起来非常非常慢!
    • 在torch 1.1中unbind已经消失了。可以改用torch.functional.split
    猜你喜欢
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-02-02
    • 2022-11-25
    • 2023-01-10
    相关资源
    最近更新 更多