Pytorch:将 VGG 模型转换为顺序模型,但得到不同的输出

Posted

技术标签:

【中文标题】Pytorch:将 VGG 模型转换为顺序模型,但得到不同的输出【英文标题】:Pytorch: Converting a VGG model into a sequential model, but getting different outputs 【发布时间】:2021-03-18 09:05:10 【问题描述】:

背景: 我正在研究一种对抗检测器方法,该方法需要访问每个隐藏层的输出。 我从torchvision.models 加载了一个预训练的 VGG16。

为了访问每个隐藏层的输出,我将其放入顺序模型中:

vgg16 = models.vgg16(pretrained=True)

vgg16_seq = nn.Sequential(*(
    list(list(vgg16.children())[0]) + 
    [nn.AdaptiveAvgPool2d((7, 7)), nn.Flatten()] + 
    list(list(vgg16.children())[2])))

没有nn.Flatten(),转发方法会抱怨mat1mat2之间的尺寸不匹配。

我查看了 torchvision VGG 实现,它使用 [feature..., AvgPool, flatten, classifier...] 结构。 由于AdaptiveAvgPool2d 层和Flatten 层没有无参数,我认为这应该可以工作,但我有不同的输出。

output1 = vgg16(X_small)
print(output1.size())
output2 = vgg16_seq(X_small)
print(output2.size())
torch.equal(output1, output2)

问题:它们的维度相同,但输出不同。

torch.Size([32, 1000]) torch.Size([32, 1000]) 假的

我在AdaptiveAvgPool2d 层之后测试了输出,输出是相等的:

output1 = nn.Sequential(*list(vgg16.children())[:2])(X_small)
print(output1.size())
output2 = nn.Sequential(*list(vgg16_seq)[:32])(X_small)
print(output2.size())
torch.equal(output1, output2)

torch.Size([32, 512, 7, 7]) torch.Size([32, 512, 7, 7]) 是的

有人能指出哪里出了问题吗? 谢谢

【问题讨论】:

【参考方案1】:

在进行推理之前,您需要调用 eval 模式。

vgg16.eval()
vgg16_seq.eval()

【讨论】:

谢谢。有用。你能解释一下为什么吗?如果模式错误,为什么nn.Sequential(*list(vgg16.children())[:2])(X_small)nn.Sequential(*list(vgg16_seq)[:32])(X_small) 得到相同的输出? 我认为这很可能是由于 dropout(在第 35 层和第 38 层中),因为默认情况下它在训练模式下启用,但我们不希望它在推理中启用(在评估模式下禁用)。阅读更多here。

以上是关于Pytorch:将 VGG 模型转换为顺序模型,但得到不同的输出的主要内容,如果未能解决你的问题,请参考以下文章

pytorch Vgg网络模型

VGG——CNN经典网络模型(pytorch实现)

VGG16 Keras微调:精度低

pytorch中修改后的模型如何加载预训练模型

PyTorch下载的预训练模型的保存位置(Windows)

如何将自定义 Pytorch 模型转换为 torchscript(pth 到 pt 模型)?