我正在使用PyTorch中的ResNet152模型。我想从该模型中删除最后一个全连接层。以下是我的代码:
from torchvision import datasets, transforms, models
model = models.resnet152(pretrained=True)
print(model)
当我打印模型时,最后几行看起来像这样:<\p> (2): Bottleneck(
(conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
)
)
(avgpool): AvgPool2d(kernel_size=7, stride=1, padding=0)
(fc): Linear(in_features=2048, out_features=1000, bias=True)
)
我想从模型中删除最后一个fc层。
我在这里找到了答案(如何将预训练的FC层转换为Pytorch中的CONV层),在那里mexmex似乎提供了我正在寻找的答案:
list(model.modules()) # to inspect the modules of your model
my_model = nn.Sequential(*list(model.modules())[:-1]) # strips off last linear layer
所以我像这样向我的代码添加了这些行:
model = models.resnet152(pretrained=True)
list(model.modules()) # to inspect the modules of your model
my_model = nn.Sequential(*list(model.modules())[:-1]) # strips off last linear layer
print(my_model)
但是这段代码并没有像宣传的那样工作 - 至少对我来说不是。本文的其余部分将详细解释为什么该答案无效,以便此问题不会被关闭为重复。
首先,打印的模型比以前大近5倍。我看到了与以前相同的模型,但后面似乎跟着一个重复的模型,但可能是压平的。
(2): Bottleneck(
(conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace)
)
)
(avgpool): AvgPool2d(kernel_size=7, stride=1, padding=0)
(fc): Linear(in_features=2048, out_features=1000, bias=True)
)
(1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
(2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(3): ReLU(inplace)
(4): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
(5): Sequential(
. . . this goes on for ~1600 more lines . . .
(415): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(416): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(417): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(418): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)
(419): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(420): ReLU(inplace)
(421): AvgPool2d(kernel_size=7, stride=1, padding=0)
)
第二,全连接层仍然存在。在它后面的Conv2D层看起来就像ResNet152的第一层。
第三,如果我尝试调用my_model.forward()
,PyTorch会报告一个大小不匹配的错误。它期望大小为[1, 3, 224, 224],但输入是[1, 1000]。因此,看起来整个模型(减去fc层)的副本正在附加到原始模型上。
总之,我在SO上找到的唯一答案实际上并不起作用。
del(model['fc'])
。你可以试一下吗? - Parthapratim Neog