如何将 PyTorch 的 torch.inverse() 函数应用于批次中的每个样本?

Posted

技术标签:

【中文标题】如何将 PyTorch 的 torch.inverse() 函数应用于批次中的每个样本?【英文标题】:How to apply the torch.inverse() function of PyTorch to every sample in the batch? 【发布时间】: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' 对象不支持索引

【问题讨论】:

【参考方案1】:

编辑:

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

老答案

计划很快实施批量逆。有关讨论,请参见例如 issue 7500 或 issue 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

以上是关于如何将 PyTorch 的 torch.inverse() 函数应用于批次中的每个样本?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 AMD GPU 用于 fastai/pytorch?

如何将 Pytorch 模型导入 MATLAB

如何使用 Pytorch 将增强图像添加到原始数据集中?

如何将 caffe prototxt 转换为 pytorch 模型?

如何将pytorch中的标签转换为onehot

如何将PyTorch张量转换为Numpy ndarray