代码之家  ›  专栏  ›  技术社区  ›  MBT Nina Golyandina

了解双线性层

  •  7
  • MBT Nina Golyandina  · 技术社区  · 7 年前

    当在PyTorch中有双线性层时,我无法理解如何计算。

    下面是一个小例子,我试图找出它是如何工作的:

    在:

    import torch.nn as nn
    B = nn.Bilinear(2, 2, 1)
    print(B.weight)
    

    Parameter containing:
    tensor([[[-0.4394, -0.4920],
             [ 0.6137,  0.4174]]], requires_grad=True)
    

    我将通过一个零向量和一个向量。

    在:

    print(B(torch.ones(2), torch.zeros(2)))
    print(B(torch.zeros(2), torch.ones(2)))
    

    输出:

    tensor([0.2175], grad_fn=<ThAddBackward>)
    tensor([0.2175], grad_fn=<ThAddBackward>)
    

    提前谢谢!

    1 回复  |  直到 7 年前
        1
  •  10
  •   benjaminplanche    7 年前

    手术由 nn.Bilinear B(x1, x2) = x1*A*x2 + b (到岸价。 doc )使用:

    • A 储存在 nn.Bilinear.weight
    • b nn.Bilinear.bias

    如果你考虑到(可选的)偏差,你应该得到预期的结果。


    import torch
    import torch.nn as nn
    
    def manual_bilinear(x1, x2, A, b):
        return torch.mm(x1, torch.mm(A, x2)) + b
    
    x_ones = torch.ones(2)
    x_zeros = torch.zeros(2)
    
    # ---------------------------
    # With Bias:
    
    B = nn.Bilinear(2, 2, 1)
    A = B.weight
    print(B.bias)
    # > tensor([-0.6748], requires_grad=True)
    b = B.bias
    
    print(B(x_ones, x_zeros))
    # > tensor([-0.6748], grad_fn=<ThAddBackward>)
    print(manual_bilinear(x_ones.view(1, 2), x_zeros.view(2, 1), A.squeeze(), b))
    # > tensor([[-0.6748]], grad_fn=<ThAddBackward>)
    
    print(B(x_ones, x_ones))
    # > tensor([-1.7684], grad_fn=<ThAddBackward>)
    print(manual_bilinear(x_ones.view(1, 2), x_ones.view(2, 1), A.squeeze(), b))
    # > tensor([[-1.7684]], grad_fn=<ThAddBackward>)
    
    # ---------------------------
    # Without Bias:
    
    B = nn.Bilinear(2, 2, 1, bias=False)
    A = B.weight
    print(B.bias)
    # None
    b = torch.zeros(1)
    
    print(B(x_ones, x_zeros))
    # > tensor([0.], grad_fn=<ThAddBackward>)
    print(manual_bilinear(x_ones.view(1, 2), x_zeros.view(2, 1), A.squeeze(), b))
    # > tensor([0.], grad_fn=<ThAddBackward>)
    
    print(B(x_ones, x_ones))
    # > tensor([-0.7897], grad_fn=<ThAddBackward>)
    print(manual_bilinear(x_ones.view(1, 2), x_ones.view(2, 1), A.squeeze(), b))
    # > tensor([[-0.7897]], grad_fn=<ThAddBackward>)