Transfer learning using VGG16

username: Dr_John
cooked: <p>I want to use VGG16 network for transfer learning. Following the <a href="https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html" rel="nofollow noopener">transfer learning tutorial</a>, which is based on the Resnet network, I want to replace the lines:</p>
<pre><code class="lang-auto">model_ft = models.resnet18(pretrained=True)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, 2)
optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)
</code></pre>
<p>with their equivalent for VGG16.</p>
<p>My attempt is:</p>
<pre><code class="lang-auto">model_ft = models.vgg16(pretrained=True)
num_ftrs = model_ft.fc.in_features
model_ft.fc = nn.Linear(num_ftrs, 2)
optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9)
</code></pre>
<p>where, as far as I understand, the two lines in the middle are required in order to replace the classification process (from 10 classes, to 2).  The problem is that the VGG16 class does not contain a “.fc” attribute, so running these lines results in an error.</p>
<p>What is the best way by which I can replace the corresponding lines in the Resnet transfer learning?</p>
<p>Since I am new in Pytorch (and Machine learning in general), any further (relevant) details regarding the structure of the VGG16 class (even details that are not necessarily required for the specific implementation I requested) will be gratefully appreciated.</p>
<p>Thanks!</p>

username: ptrblck
cooked: <p>For VGG16 you would have to use <code>model_ft.classifier</code>. You can find the corresponding code <a href="https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py#L29">here</a>.<br>
Here is a small example how to reset the last layer. Of course you could also replace the whole classifier, if that’s what you wish.</p>
<pre><code class="lang-python">model = models.vgg16(pretrained=False)
model.classifier[-1] = nn.Linear(in_features=4096, out_features=num_classes)
</code></pre>

username: Dr_John
cooked: <p>Many thanks ptrblck! For future reference, I also found this really helpful tutorial:<br>
<a href="https://www.kaggle.com/carloalbertobarbano/vgg16-transfer-learning-pytorch" class="onebox" target="_blank" rel="nofollow noopener">https://www.kaggle.com/carloalbertobarbano/vgg16-transfer-learning-pytorch</a></p>

username: alex_d
cooked: <p>I have a similar question, but for the fcn resnet 101 segmentation model. In my case I am following this <a href="https://pytorch.org/tutorials/beginner/finetuning_torchvision_models_tutorial.html#model-training-and-validation-code" rel="nofollow noopener">tutorial</a> and I am trying to adapt this part of the code to fcn resnet 101.</p>
<p>The code from the tutorial is:</p>
<pre><code class="lang-auto">    if model_name == "resnet":
        """ Resnet18
        """
        model_ft = models.resnet18(pretrained=use_pretrained)
        set_parameter_requires_grad(model_ft, feature_extract)
        num_ftrs = model_ft.fc.in_features
        model_ft.fc = nn.Linear(num_ftrs, num_classes)
        input_size = 224
</code></pre>
<p>and so far I have changed it to:</p>
<pre><code class="lang-auto">if model_name == "resnet":

        """ FCN_resnet101
        """
        model_ft = models.segmentation.fcn_resnet101(pretrained=use_pretrained)
        set_parameter_requires_grad(model_ft, feature_extract)
        num_ftrs = model_ft.fc.in_features
        model_ft.fc = nn.Linear(num_ftrs, num_classes)
        input_size = 768, 1024
</code></pre>
<p>When I do this I get this error: ‘FCN’ object has no attribute ‘fc’</p>
<p>So I was wondering how I can change the two lines below to work with the fcn segmentation model</p>
<pre><code class="lang-auto">        num_ftrs = model_ft.fc.in_features
        model_ft.fc = nn.Linear(num_ftrs, num_classes)
</code></pre>

username: ptrblck
cooked: <p>Since this is a segmentation model, the output layer would be a conv layer instead of a linear one.<br>
If you want to train your model from scratch, you could just use the <code>num_classes</code> argument:</p>
<pre><code class="lang-python">modelA = models.segmentation.fcn_resnet101(
    pretrained=False, num_classes=2)
</code></pre>
<p>On the other hand, if you just want to use the pretrained model and create a new classification layer, you could use:</p>
<pre><code class="lang-python">modelB = models.segmentation.fcn_resnet101(pretrained=True)
modelB.classifier[4] = nn.Conv2d(512, num_classes, 1, 1)
</code></pre>

username: alex_d
cooked: <p>Thanks!</p>
<p>I am fine tuning a pretrained model with my own data, so the second method would work for me.</p>
<p>One follow up question:</p>
<p>Wouldn’t I have to fetch the number of in_channels of the existing pre-trained model, similarly to how  its done in the example with ‘num_ftrs’?</p>
<p>So in the tutorial there is this line before creating a new layer:</p>
<p><code>num_ftrs = model_ft.fc.in_features</code></p>
<p>Would the equivalent for segmentation be the line below?:</p>
<p><code>in_chnls =  modelB.classifier[4].in_channels</code></p>
<p>And then:</p>
<p><code>modelB.classifier[4] = nn.Conv2d(in_chnls, num_classes, 1, 1)</code></p>

username: ptrblck
cooked: <p>Yes, that would be the corresponding code.<br>
You could also get the <code>kernel_size</code> and <code>stride</code> which are set as <code>1</code> in my code example.</p>

username: alex_d
cooked: <p>Thanks! I am getting this part to work now!</p>