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()
,转发方法会抱怨mat1
和mat2
之间的尺寸不匹配。
我查看了 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 模型转换为顺序模型,但得到不同的输出的主要内容,如果未能解决你的问题,请参考以下文章