如何在使用 PyTorch 'nn.Sequential' 时访问网络权重?

问题描述 投票:0回答:6

我正在构建一个神经网络,但我不知道如何访问每一层的模型权重。

我已经尝试过了

model.input_size.weight

代码:

input_size = 784
hidden_sizes = [128, 64]
output_size = 10

# Build a feed-forward network
model = nn.Sequential(nn.Linear(input_size, hidden_sizes[0]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[0], hidden_sizes[1]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[1], output_size),
                      nn.Softmax(dim=1))

我期望得到重量,但我得到了

“顺序”对象没有属性“input_size”

python neural-network pytorch torch
6个回答
19
投票

如果您使用

print(model)
打印模型,您将得到

Sequential(
  (0): Linear(in_features=784, out_features=128, bias=True)
  (1): ReLU()
  (2): Linear(in_features=128, out_features=64, bias=True)
  (3): ReLU()
  (4): Linear(in_features=64, out_features=10, bias=True)
  (5): Softmax(dim=1) )

现在您可以访问所有层的索引,因此您可以通过

model[4].weight
获得(比方说)第二个线性层的权重。


11
投票

根据官方 pytorch 讨论论坛此处,您可以使用

访问
nn.Sequential()

中特定模块的权重
model.layers[0].weight # for accessing weights of first layer wrapped in nn.Sequential()

6
投票

我尝试了很多方法,似乎唯一的方法是通过传递来命名每一层

OrderedDict

from collections import OrderedDict
model = nn.Sequential(OrderedDict([
                  ('fc1', nn.Linear(input_size, hidden_sizes[0])),
                  ('relu1', nn.ReLU()),
                  ('fc2', nn.Linear(hidden_sizes[0], hidden_sizes[1])),
                  ('relu2', nn.ReLU()),
                  ('output', nn.Linear(hidden_sizes[1], output_size)),
                  ('softmax', nn.Softmax(dim=1))]))

因此,要访问每个层的权重,我们需要通过其自己唯一的层名称来调用它。

例如访问第 1 层的权重

model.fc1.weight

Parameter containing:
tensor([[-7.3584e-03, -2.3753e-02, -2.2565e-02,  ...,  2.1965e-02,
      1.0699e-02, -2.8968e-02],
    [ 2.2930e-02, -2.4317e-02,  2.9939e-02,  ...,  1.1536e-02,
      1.9830e-02, -1.4294e-02],
    [ 3.0891e-02,  2.5781e-02, -2.5248e-02,  ..., -1.5813e-02,
      6.1708e-03, -1.8673e-02],
    ...,
    [-1.2596e-03, -1.2320e-05,  1.9106e-02,  ...,  2.1987e-02,
     -3.3817e-02, -9.4880e-03],
    [ 1.4234e-02,  2.1246e-02, -1.0369e-02,  ..., -1.2366e-02,
     -4.7024e-04, -2.5259e-02],
    [ 7.5356e-03,  3.4400e-02, -1.0673e-02,  ...,  2.8880e-02,
     -1.0365e-02, -1.2916e-02]], requires_grad=True)

3
投票

假设您将模型定义为一个类。然后就可以调用 model.parameters() 了。

`# Build a feed-forward network
 class FFN(nn.Module):
     def __init__(self):
         super().__init__()
         self.layer1 = nn.Linear(input_size, hidden_sizes[0])
         self.layer2 = nn.Linear(hidden_sizes[0], hidden_sizes[1])
         self.layer3 = nn.Linear(hidden_sizes[1], output_size)
         self.relu = nn.ReLU()
         self.softmax = nn.Softmax(dim=1)
     def forward(self, x):
         x = self.relu(self.layer1(x))
         x = self.relu(self.layer2(x))
         x = self.softmax(self.layer3(x))
         return x

model = FFN()
print(model.parameters())`

这将打印

<generator object Module.parameters at 0x7f99886d0d58>
,因此您可以立即将其传递给优化器!

但是,如果您想访问特定权重或手动查看它们,您只需转换为列表即可:

print(list(model.parameters()))
。这会输出一个巨大的权重列表。

但是,假设您只想要最后一层,那么您可以执行:

print(list(model.parameters())[-1])
,这将打印:
tensor([-0.0347, -0.0289, -0.0652, -0.1233,  0.1093,  0.1187, -0.0407,  0.0885, -0.0045, -0.1238], requires_grad=True)


2
投票

对于顺序模型和类模型,您可以通过children方法访问层权重:

for layer in model.children():
    if isinstance(layer, nn.Linear):
        print(layer.state_dict())

这会给你这样的输出:

OrderedDict([
('weight', tensor([[-0.0039, -0.0045...]])),
('bias', tensor([[-0.0019, -0.0025...]]))
])

或者像这样:

for layer in model.children():
    if isinstance(layer, nn.Linear):
        print('weight:', layer.weight
        print('bias:', layer.bias

对于基于类的模型,顺序将按照 init 方法中定义的层进行。


1
投票

您可以使用 model[0].weight.grad 显示权重

© www.soinside.com 2019 - 2024. All rights reserved.