# Transfer learning using VGG16

**URL:** <https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653>\
**Category:** vision\
**Created:** [July 3, 2018, 4:28pm UTC](https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653 "2018-07-03T16:28:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dr\_John](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/d/a9adbd/32.png) [@Dr\_John](https://discuss.pytorch.org/u/Dr_John)\
**Post date:** [July 3, 2018, 4:28pm UTC](https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653/1 "2018-07-03T16:28:11Z")

</div>

I want to use VGG16 network for transfer learning. Following the [transfer learning tutorial](https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html), which is based on the Resnet network, I want to replace the lines:

```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)

```

with their equivalent for VGG16.

My attempt is:

```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)

```

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.

What is the best way by which I can replace the corresponding lines in the Resnet transfer learning?

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.

Thanks!

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [July 3, 2018, 6:14pm UTC](https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653/2 "2018-07-03T18:14:56Z")

</div>

For VGG16 you would have to use `model_ft.classifier`. You can find the corresponding code [here](https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py#L29).  
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.

```python
model = models.vgg16(pretrained=False)
model.classifier[-1] = nn.Linear(in_features=4096, out_features=num_classes)

```

---

<div class="post-metadata">

**Author:** ![Dr\_John](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/d/a9adbd/32.png) [@Dr\_John](https://discuss.pytorch.org/u/Dr_John)\
**Post date:** [July 3, 2018, 6:35pm UTC](https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653/3 "2018-07-03T18:35:13Z")

</div>

Many thanks ptrblck! For future reference, I also found this really helpful tutorial:  
[https://www.kaggle.com/carloalbertobarbano/vgg16-transfer-learning-pytorch](https://www.kaggle.com/carloalbertobarbano/vgg16-transfer-learning-pytorch)

---

<div class="post-metadata">

**Author:** ![alex\_d](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/a/f0a364/32.png) [@alex\_d](https://discuss.pytorch.org/u/alex_d)\
**Post date:** [January 18, 2020, 5:57pm UTC](https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653/4 "2020-01-18T17:57:25Z")

</div>

I have a similar question, but for the fcn resnet 101 segmentation model. In my case I am following this [tutorial](https://pytorch.org/tutorials/beginner/finetuning_torchvision_models_tutorial.html#model-training-and-validation-code) and I am trying to adapt this part of the code to fcn resnet 101.

The code from the tutorial is:

```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

```

and so far I have changed it to:

```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

```

When I do this I get this error: ‘FCN’ object has no attribute ‘fc’

So I was wondering how I can change the two lines below to work with the fcn segmentation model

```auto
        num_ftrs = model_ft.fc.in_features
        model_ft.fc = nn.Linear(num_ftrs, num_classes)

```

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [January 18, 2020, 7:00pm UTC](https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653/5 "2020-01-18T19:00:49Z")

</div>

Since this is a segmentation model, the output layer would be a conv layer instead of a linear one.  
If you want to train your model from scratch, you could just use the `num_classes` argument:

```python
modelA = models.segmentation.fcn_resnet101(
    pretrained=False, num_classes=2)

```

On the other hand, if you just want to use the pretrained model and create a new classification layer, you could use:

```python
modelB = models.segmentation.fcn_resnet101(pretrained=True)
modelB.classifier[4] = nn.Conv2d(512, num_classes, 1, 1)

```

---

<div class="post-metadata">

**Author:** ![alex\_d](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/a/f0a364/32.png) [@alex\_d](https://discuss.pytorch.org/u/alex_d)\
**Post date:** [January 18, 2020, 8:29pm UTC](https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653/6 "2020-01-18T20:29:28Z")

</div>

Thanks!

I am fine tuning a pretrained model with my own data, so the second method would work for me.

One follow up question:

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’?

So in the tutorial there is this line before creating a new layer:

`num_ftrs = model_ft.fc.in_features`

Would the equivalent for segmentation be the line below?:

`in_chnls = modelB.classifier[4].in_channels`

And then:

`modelB.classifier[4] = nn.Conv2d(in_chnls, num_classes, 1, 1)`

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [January 18, 2020, 11:01pm UTC](https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653/7 "2020-01-18T23:01:52Z")

</div>

Yes, that would be the corresponding code.  
You could also get the `kernel_size` and `stride` which are set as `1` in my code example.

---

<div class="post-metadata">

**Author:** ![alex\_d](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/a/f0a364/32.png) [@alex\_d](https://discuss.pytorch.org/u/alex_d)\
**Post date:** [January 18, 2020, 11:09pm UTC](https://discuss.pytorch.org/t/transfer-learning-using-vgg16/20653/8 "2020-01-18T23:09:02Z")

</div>

Thanks! I am getting this part to work now!
