首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从pytorch模块中获取子模块的序列?

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

Stack Overflow用户
提问于 2020-06-15 04:21:11
回答 1查看 2K关注 0票数 3

对于pytorch 模块,我想我可以使用.named_children.named_modules等来获取子模块的列表。不过,我想名单不是按顺序排列的,对吧?举个例子:

代码语言:javascript
复制
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()在上述模型中的阶数为蒸馏器、pre_classifier、分类器和退出。但是,如果检查代码,很明显,dropout发生在classifier之前。那么,如何获得这些子模块的顺序呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-15 05:56:55

在Pytorch中,print(model).named_children()等的结果是根据它们在模型类的__init__中声明的顺序列出的。

案例1

代码语言:javascript
复制
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

更改构造函数中fc1fc2层的顺序。

代码语言:javascript
复制
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']

这就是为什么在构造函数中声明的classifierdropout之前打印的原因:

代码语言:javascript
复制
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()等来处理模型的子模块,但是它们只会按照在__init__中声明的顺序列出。如果只想打印基于forward方法的结构,可以尝试使用火把-摘要

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62381286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档