Add layers on pretrained model

lattice: <p>I would like to fine-tune by adding layers to the resnet50 pre-trained model.<br>
here’s resnet50 imported</p>
<pre><code class="lang-auto">from torchvision import models

resnet50 = models.resnet50(pretrained = True)
resnet50.fc = nn.Identity()
</code></pre>
<pre><code class="lang-auto">sample = torch.randn(1, 3, 224, 224)
resnet50(sample).size()
</code></pre>
<blockquote>
<p>torch.Size([1, 2048])</p>
</blockquote>
<p>Here are the layers to add.</p>
<pre><code class="lang-auto">class net(nn.Module):
    def __init__(self):
        super(net, self).__init__()
        self.fc = nn.Linear(2048, 128)
        
        self.branch_a1 = nn.Linear(128, 32)
        self.branch_a2 = nn.Linear(32, 1)
        
        self.branch_b1 = nn.Linear(128, 5)
    
    def forward(self, x):
        x = F.leaky_relu(self.fc(x))
        
        # branch a
        a = F.leaky_relu(self.branch_a1(x))
        out1 = self.branch_a2(a)
        
        # branch b
        out2 = self.branch_b1(x)
        
        return out1, out2
</code></pre>
<p>And I tie the two models together with nn.sequential.</p>
<pre><code class="lang-auto">model = nn.Sequential(resnet50, net)
model
</code></pre>
<p>I thought it would work, but I get an error. What should I do?</p>
<pre><code class="lang-auto"> ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
&lt;ipython-input-55-cdc7b18bb3fc&gt; in &lt;module&gt;
----&gt; 1 model = nn.Sequential(resnet50, net)
      2 model

c:\users\kimsunghun\anaconda3\envs\pytorch\lib\site-packages\torch\nn\modules\container.py in __init__(self, *args)
     52         else:
     53             for idx, module in enumerate(args):
---&gt; 54                 self.add_module(str(idx), module)
     55 
     56     def _get_item_by_idx(self, iterator, idx):

c:\users\kimsunghun\anaconda3\envs\pytorch\lib\site-packages\torch\nn\modules\module.py in add_module(self, name, module)
    187         if not isinstance(module, Module) and module is not None:
    188             raise TypeError("{} is not a Module subclass".format(
--&gt; 189                 torch.typename(module)))
    190         elif not isinstance(name, torch._six.string_classes):
    191             raise TypeError("module name should be a string. Got {}".format(

TypeError: __main__.net is not a Module subclass</code></pre>

surya00060: <p>Hi</p>
<p>You can add layers to the pre-trained model by replacing the FC layer if it’s not needed.</p>
<pre><code class="lang-auto">resnet50.fc = net()
</code></pre>

Nikronic: <p>Hi,</p>
<p>I think this post might help you:</p>
<aside class="quote quote-modified" data-post="2" data-topic="88397">
  <div class="title">
    <div class="quote-controls"></div>
    <img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/nikronic/48/71873_2.png" class="avatar">
    <a href="https://discuss.pytorch.org/t/load-only-a-part-of-the-network-with-pretrained-weights/88397/2">Load only a part of the network with pretrained weights</a> 
  </div>
  <blockquote>
    Hi, 
For this, there are different approaches but personally, I would create a class on top of previously defined model which you have weights for. Then add any other layers as another sequential to the new defined model. Something like this: 
pretrained = torchvision.models.alexnet(pretrained=True)
class MyAlexNet(nn.Module):
    def __init__(self, my_pretrained_model):
        super(MyAlexNet, self).__init__()
        self.pretrained = my_pretrained_model
        self.my_new_layers = nn.Sequen…
  </blockquote>
</aside>

<p>Bests</p>

CastleDream: <p>the code has no problem, you just forget to  create an instance of <code>net</code> class. I have tried your code, like this:</p>
<pre><code class="lang-auto">net_add=net()
model = nn.Sequential(resnet50, net_add)
model
</code></pre>
<p>and it’s output  like this:</p>
<pre><code class="lang-auto">  (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=True)
      )
    )
    (avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
    (fc): Identity()
  )
  (1): net(
    (fc): Linear(in_features=2048, out_features=128, bias=True)
    (branch_a1): Linear(in_features=128, out_features=32, bias=True)
    (branch_a2): Linear(in_features=32, out_features=1, bias=True)
    (branch_b1): Linear(in_features=128, out_features=5, bias=True)
  )
)
</code></pre>

CastleDream: <p>you can reference this answer:<a href="https://stackoverflow.com/questions/44406819/pytorch-custom-layer-is-not-a-module-subclass" rel="noopener nofollow ugc">https://stackoverflow.com/questions/44406819/pytorch-custom-layer-is-not-a-module-subclass</a></p>

suresh_thommandru: <p>All of the above are adding the layers at the end of the pre-trained network. But how to add layers in the middle of the pretrained model?</p>

alihamza: <p>when we train the new layers cannot get the weights from pretrained because these are not defined what to do ?</p>