如何从pytorch模块中获取子模块序列?

如何从pytorch模块中获取子模块序列?,pytorch,huggingface-transformers,Pytorch,Huggingface Transformers,对于pytorch,我想我可以使用.named_children,.named_modules等来获得子模块的列表。但是,我想这个列表没有按顺序排列,对吗?例如: In [19]: import transformers In [20]: model = transformers.DistilBertForSequenceClassification.from_pretrained('distilb ...: ert-base-cased') In [21]: [name for n

对于pytorch,我想我可以使用
.named_children
.named_modules
等来获得子模块的列表。但是,我想这个列表没有按顺序排列,对吗?例如:

In [19]: import transformers

In [20]: model = transformers.DistilBertForSequenceClassification.from_pretrained('distilb
    ...: ert-base-cased')

In [21]: [name for name, _ in model.named_children()]
Out[21]: ['distilbert', 'pre_classifier', 'classifier', 'dropout']

上述模型中
.named_children()
的顺序为distilbert、pre_分类器、分类器和dropout。但是,如果检查,很明显,
退出
发生在
分类器
之前。那么如何得到这些子模块的顺序呢

在Pytorch中,
print(model)
.named_children()
等的结果根据它们在模型类的
\uuuu init\uuu
中声明的顺序列出,例如

案例1

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.fc1 = nn.Linear(320, 50)
        self.fc2 = nn.Linear(50, 10)
        self.conv2_drop = nn.Dropout2d()

    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = F.dropout(x, p=0.6)
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

model = Model()
print(model)
[name for name, _ in model.named_children()]
# output
['conv1', 'conv2', 'fc1', 'fc2', 'conv2_drop']
案例2

更改了构造函数中
fc1
fc2
层的顺序

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
        self.fc2 = nn.Linear(50, 10)
        self.fc1 = nn.Linear(320, 50)
        self.conv2_drop = nn.Dropout2d()

    def forward(self, x):
        x = F.relu(F.max_pool2d(self.conv1(x), 2))
        x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
        x = x.view(-1, 320)
        x = F.relu(self.fc1(x))
        x = F.dropout(x, p=0.6)
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

model = Model()
print(model)
[name for name, _ in model.named_children()]
# output
['conv1', 'conv2', 'fc2', 'fc1', 'conv2_drop']

这就是为什么
分类器
退出
之前打印,正如构造函数中声明的那样:

class DistilBertForSequenceClassification(DistilBertPreTrainedModel):
        ...
        self.distilbert = DistilBertModel(config)
        self.pre_classifier = nn.Linear(config.dim, config.dim)
        self.classifier = nn.Linear(config.dim, config.num_labels)
        self.dropout = nn.Dropout(config.seq_classif_dropout)


不过,您可以使用
.modules()
等来处理模型的子模块,但它们将仅按照在
\uuuu init\uuuu
中声明的顺序列出。如果您只想打印基于
forward
方法的结构,您可以尝试使用。

除了以方法
.forward
的形式外,流似乎没有显式保存在模块对象中。我想如果我想要流,我可以检查
.forward
方法。在ipython中,运行
model.forward???
就可以了。是的,您可能需要使用钩子或其他东西,就像在pytorch摘要包中一样。