使用 Pytorch 的 *list、.children() 和 nn.sequential 创建的模型会产生不同的输出张量
Posted
技术标签:
【中文标题】使用 Pytorch 的 *list、.children() 和 nn.sequential 创建的模型会产生不同的输出张量【英文标题】:Model Created With Pytorch's *list, .children(), and nn.sequential Produces Different Output Tensors 【发布时间】:2021-12-10 01:26:51 【问题描述】:我目前正在尝试在我的模型中使用预训练的 DenseNet。我正在关注本教程:https://pytorch.org/hub/pytorch_vision_densenet/,它运行良好,输入为 [1,3,244,244],它返回一个 [1,1000] 张量,完全符合预期。 但是,目前我正在使用此代码将预训练的 Densenet 加载到我的模型中,并将其用作“特征提取”模型。这是init函数中的代码
base_model = torch.hub.load('pytorch/vision:v0.10.0', 'densenet121', pretrained=True)
self.base_model = nn.Sequential(*list(base_model.children())[:-1])
并且在 forward 函数中就是这样使用的
x = self.base_model(x)
然而,这采用相同的输入,返回一个大小为:([1, 1024, 7, 7]) 的张量。我不知道是什么不工作,我认为这是由于 DenseNet 将所有层连接在一起,但我不知道如何让它以相同的方法工作。关于如何在我自己的模型中使用预训练 DenseNet 的任何提示?
【问题讨论】:
【参考方案1】:通常nn.Modules
在forward
定义中包含逻辑,这意味着仅将模型转换为顺序块就无法访问它。最值得注意的是,您通常会发现 CNN 和网络的分类器层之间发生了下采样和/或扁平化。这是 DenseNet 的。
如果您查看 Torchvision 对 DenseNet here 的前向实现,您会看到:
def forward(self, x: Tensor) -> Tensor:
features = self.features(x)
out = F.relu(features, inplace=True)
out = F.adaptive_avg_pool2d(out, (1, 1))
out = torch.flatten(out, 1)
out = self.classifier(out)
return out
您可以看到 CNN self.features
(形状为 (*, 1024, 7, 7)
)输出的张量如何通过 ReLU、自适应平均池进行处理,并在馈送到分类器(最后一层)之前进行展平。
【讨论】:
以上是关于使用 Pytorch 的 *list、.children() 和 nn.sequential 创建的模型会产生不同的输出张量的主要内容,如果未能解决你的问题,请参考以下文章