【问题标题】:Shape of pytorch model.parameter is inconsistent with how it's defined in the modelpytorch model.parameter 的形状与模型中的定义不一致
【发布时间】:2019-04-26 23:58:42
【问题描述】:

我正在尝试从 PyTorch 中构建的简单网络中提取权重和偏差。我的整个网络由 nn.Linear 层组成。当我通过调用nn.Linear(in_dim, out_dim) 创建一个层时,我希望通过调用model.parameters() 获得的参数对于该模型具有形状(in_dim, out_dim) 的权重和(out_dim) 的偏差。但是,来自model.parameters() 的权重不是形状(out_dim, in_dim)

我的代码的目的是能够使用矩阵乘法来执行前向传递,只使用 numpy,而不是任何 PyTorch。由于形状不一致,矩阵乘法会引发错误。我该如何解决这个问题?

这是我的确切代码:

class RNN(nn.Module):

    def __init__(self, dim_input, dim_recurrent, dim_output):

        super(RNN, self).__init__()

        self.dim_input = dim_input
        self.dim_recurrent = dim_recurrent
        self.dim_output = dim_output

        self.dense1 = nn.Linear(self.dim_input, self.dim_recurrent)
        self.dense2 = nn.Linear(self.dim_recurrent, self.dim_recurrent, bias = False)
        self.dense3 = nn.Linear(self.dim_input, self.dim_recurrent)
        self.dense4 = nn.Linear(self.dim_recurrent, self.dim_recurrent, bias = False)
        self.dense5 = nn.Linear(self.dim_recurrent, self.dim_output)

#There is a defined forward pass

model = RNN(12, 100, 6)

for i in model.parameters():
    print(i.shape())

输出是:

torch.Size([100, 12])
torch.Size([100])
torch.Size([100, 100])
torch.Size([100, 12])
torch.Size([100])
torch.Size([100, 100])
torch.Size([6, 100])
torch.Size([6])

如果我是正确的,输出应该是:

torch.Size([12, 100])
torch.Size([100])
torch.Size([100, 100])
torch.Size([12, 100])
torch.Size([100])
torch.Size([100, 100])
torch.Size([100, 6])
torch.Size([6])

我的问题是什么?

【问题讨论】:

  • 请分享相关代码并突出显示那里的确切问题

标签: python machine-learning pytorch


【解决方案1】:

你看到的不是 (out_dim, in_dim),它只是权重矩阵的形状。调用print(model)可以看到输入输出特征是正确的:

RNN(
  (dense1): Linear(in_features=12, out_features=100, bias=True)
  (dense2): Linear(in_features=100, out_features=100, bias=False)
  (dense3): Linear(in_features=12, out_features=100, bias=True)
  (dense4): Linear(in_features=100, out_features=100, bias=False)
  (dense5): Linear(in_features=100, out_features=6, bias=True)
)

在调用matmul之前,您可以检查源代码以查看权重实际上是转置


nn.Linear 在这里定义:
https://pytorch.org/docs/stable/_modules/torch/nn/modules/linear.html#Linear

您可以查看forward,它是这样的:

def forward(self, input):
    return F.linear(input, self.weight, self.bias)


F.linear 在这里定义:
https://pytorch.org/docs/stable/_modules/torch/nn/functional.html

权重相乘的相应行是:

output = input.matmul(weight.t())

如上所述,您可以看到 权重 在应用 matmul 之前被转置,因此权重的形状与您预期的不同。

所以如果你想手动进行矩阵乘法,你可以这样做:

# dummy input of length 5
input = torch.rand(5, 12)
# apply layer dense1 (without bias, for bias just add + model.dense1.bias)
output_first_layer = input.matmul(model.dense1.weight.t())
print(output_first_layer.shape)

正如您对dense1 所期望的那样,它会返回:

torch.Size([5, 100])

我希望这可以解释你对形状的观察:)

【讨论】:

  • 权重调换有什么原因吗?
  • @SamuelCarpenter 其实我不知道 :) 我在这里问了一个问题:stackoverflow.com/questions/53465608/…
  • @SamuelCarpenter 找到了答案,您可以在我发布的链接上查看。
猜你喜欢
  • 2021-06-03
  • 2021-12-09
  • 2020-08-15
  • 2018-10-14
  • 2020-09-05
  • 2020-09-09
  • 1970-01-01
  • 2022-06-13
  • 2021-05-11
相关资源
最近更新 更多