我目前正在尝试在我的模型中使用预训练的DenseNet。我按照这个教程进行操作:https://pytorch.org/hub/pytorch_vision_densenet/,它运作良好,输入为[1,3,244,244]时,返回一个[1,1000]的张量,完全符合预期。然而,我现在使用以下代码将预训练的Densenet加载到我的模型中,并将其用作“特征提取”模型。这是初始化函数中的代码
base_model = torch.hub.load('pytorch/vision:v0.10.0', 'densenet121', pretrained=True)self.base_model = nn.Sequential(*list(base_model.children())[:-1])
并且在前向函数中使用如下方式
x = self.base_model(x)
然而,使用相同的输入,它返回的张量大小为:([1, 1024, 7, 7])。我无法找出问题所在,我认为这是因为DenseNet将所有层连接在一起,但我不知道如何使用相同的方法使其工作。关于如何在我的模型中使用预训练的DenseNet,有什么建议吗?
回答:
一般来说,nn.Modules
在forward
定义中包含逻辑,这意味着仅仅将模型转换为顺序块是无法访问这些逻辑的。最值得注意的是,你通常可以在CNN和分类层之间发现降采样和/或扁平化操作。这对于DenseNet也是如此。
如果你查看Torchvision的DenseNet前向实现这里,你会看到:
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、自适应平均池化和平坦化处理后,再被送入分类器(最后一层)的。