Put a new top on ResNet
I’m trying to replace the last layer of an imagenet trained model. <SCODE>model_imagenet = models.resnet18(pretrained=True)
model_imagenet

class ResNetNewTop(nn.Module):
    def __init__(self, old_model, num_classes=2):
        super(ResNetNewTop, self).__init__()
        self.bottom = nn.Sequential(*list(old_model.children())[:-1])
        self.top = nn.Linear(512, num_classes)  # TODO: input size (512) from bottom

    def forward(self, x):
        x = self.bottom(x)
        x = self.top(x)  # <<< Errors here
        return x

model = ResNetNewTop(model_imagenet, num_classes=2)
model.cuda()
model
<ECODE> This is throwing RuntimeError: matrix and matrix expected at [snip] /torch/lib/THC/generic/THCTensorMathBlas.cu:235 Can I put Sequential() into a new model directly? Or do I have to loop through the layers and build up the model that way?
telesphore
Additionally, in case of ResNet, you could just replace the final layer with a new one and it should work I think: <SCODE>model_imagenet.fc = nn.Linear(512, num_classes)
<ECODE>
apaszke
I do this: <SCODE>model = models.__dict__[opt.arch](pretrained=True) #pretrained=False if you don't want to use pre-trained weights.
model.fc = nn.Linear(512, num_classes)<ECODE>
avijit_dasgupta
apaszke
Yes. It will only work for ResNets. Your answer is more generalized.
avijit_dasgupta
Thank you! The diagnosis was spot on. I like the shortcut too; it helped me realize how loosely coupled all of the layers are.
telesphore
<SCODE>feat = nn.Sequential(*list(resnet.children())[:-1])
fc1 = nn.Linear(a, b)
fc1 = nn.Linear(b, c)

<ECODE> the layer names in feat are lost.
drcege