PyTorch模型参数的形状与模型定义不一致

我试图从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)#有一个定义的正向传播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])

我的问题是什么?


回答:

你看到的并不是(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之前是转置的,因此权重的形状与你预期的不同。

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

# 长度为5的虚拟输入input = torch.rand(5, 12)# 应用dense1层(不包括偏置,如果需要偏置只需加上model.dense1.bias)output_first_layer = input.matmul(model.dense1.weight.t())print(output_first_layer.shape)

正如你对dense1的预期,它返回:

torch.Size([5, 100])

我希望这能解释你对形状的观察 🙂

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注