【问题标题】:How to apply a custom function to specific columns in a matrix in PyTorch如何将自定义函数应用于 PyTorch 中矩阵中的特定列
【发布时间】:2018-10-09 23:26:35
【问题描述】:

我有一个大小为 [150, 182, 91] 的张量,第一部分只是批量大小,而我感兴趣的矩阵是 182x91 的。

我需要在 182x91 矩阵上分别为 50 个维度中的每一个运行一个函数。

我需要得到一个182x91矩阵的对角矩阵条纹,我使用的函数如下(基于我之前的问题:Getting diagonal matrix stripe automatically in numpy or pytorch):

 def stripe(a):

    i, j = a.size()
    assert (i >= j)

    out = torch.zeros((i - j + 1, j))
    for diag in range(0, i - j + 1):
        out[diag] = torch.diag(a, -diag)
    return out

stripe 函数需要一个大小为 IxJ 的矩阵,无法处理第 3 维。

所以当我运行这个时:

some_matrix = x # <class 'torch.autograd.variable.Variable'> torch.Size([150, 182, 91])
get_diag = stripe(some_matrix)

我收到此错误:ValueError: too many values to unpack (expected 2)

如果我只是尝试通过 x, i, j = a.size() 跳过第一个维度, 我明白了:RuntimeError: invalid argument 1: expected a matrix or a vector at

我仍在使用 PyTorch 0.3.1。任何帮助表示赞赏!

【问题讨论】:

    标签: python matrix neural-network pytorch tensor


    【解决方案1】:

    您可以使用torch.unbind as 将条带函数映射到张量的第一维上

    In [1]: import torch
    
    In [2]: def strip(a):
       ...:     i, j = a.size()
       ...:     assert(i >= j)
       ...:     out = torch.zeros((i - j + 1, j))
       ...:     for diag in range(0, i - j + 1):
       ...:         out[diag] = torch.diag(a, -diag)
       ...:     return out
       ...: 
       ...: 
    
    In [3]: a = torch.randn((182, 91)).cuda()
    
    In [5]: output = strip(a)
    
    In [6]: output.size()
    Out[6]: torch.Size([92, 91])
    
    In [7]: a = torch.randn((150, 182, 91))
    
    In [8]: output = list(map(strip, torch.unbind(a, 0)))
    
    In [9]: output = torch.stack(output, 0)
    
    In [10]: output.size()
    Out[10]: torch.Size([150, 92, 91])
    

    【讨论】:

    • 谢谢,我收到以下错误RuntimeError: copy from Variable to torch.FloatTensor isn't implemented,因为我说过我的输入是变量而不是张量,有没有快速更改类型的方法?看起来迁移到 0.4 可以得到回报。
    • 是的,它可以立即在0.4.1 中使用。但是,如果你想在0.3.1 上运行它,错误必须由out[diag] = torch.diag(a, -diag) 行引入。您可以将out 的创建与Variable 包装为out = Variable(torch.zeros(i - j + 1, j)))
    • 谢谢,效果很好。顺便说一句,由于某种原因,当我在您的解决方案中执行 j + 1 时,我总是得到一个元素太多的输出长度。如果我不使用+1,它似乎可以正常工作并输出正确数量的元素。你能详细说明你为什么要+1吗?
    • 考虑矩阵为n X n的情况。如果你计算(i - j),那么它将是0,并且不会选择矩阵的对角线。
    • 添加代码后,在 epoch 迭代结束时,我总是在 torch.autograd.backward 中收到 RuntimeError: The size of tensor a (181) must match the size of tensor b (180) at non-singleton dimension 1 错误,是代码中的任何内容向模型添加了一些额外的参数,我必须跟踪?
    【解决方案2】:

    这是一种不使用stackunbind 的方法,直接在批处理矩阵上计算对角线:

    def batch_stripe(a):
        b, i, j = a.size()
        assert i > j
        b_s, k, l = a.stride()
        return torch.as_strided(a, (b, i - j, j), (b_s, k, k+1))
    

    更多信息请参考: https://discuss.pytorch.org/t/optimizing-diagonal-stripe-code/17777/5

    【讨论】:

      猜你喜欢
      • 2017-03-11
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多