Remove FC of 2 models and torch cat

Giuseppe: <p>Hy guys, I have two model.<br>
The first is a compound model with fan_resnet50 and a reset ad hoc with 4 basicBlock.<br>
The second model is a resnet50 pretrained.</p>
<p>I must remove the FC layer of these models and do a torch.cat of this 2 model.</p>
<pre><code class="lang-auto">&gt; class Identity(nn.Module):
&gt;     def __init__(self):
&gt;         super().__init__()
&gt; 
&gt;     def forward(self, x):
&gt;         return x
&gt; class Compound_Model_final(nn.Module):
&gt;     def __init__(self):
&gt;         super().__init__()
&gt;         self.model1 = fcn_resnet50(num_classes=9)
&gt;         self.model2= _resnet_shallow(pretrained=False)
&gt;         self.model3 = models.resnet50(pretrained=False)
&gt;         self.model3.load_state_dict(torch.load("Regressione_ResNet50_cartesian_angle_M95.pth"))
&gt;     def forward(self, x):
&gt;         dist = self.model1(x)['out']
&gt;         #dist = torch.softmax(dist.view(dist.shape[0],-1), dim =1).view(dist.shape)
&gt;         n_features_x = self.model2.fc.in_features
&gt;         n_features_y =self.model3.fc.in_features
&gt;         self.model2.fc = Identity()
&gt;         self.model3.fc = Identity()
&gt; 
&gt;         z = torch.cat([self.model2.fc, self.model3.fc ],1)
&gt;         xyuv=nn.Linear((128*(n_features_x + n_features_y)), 4)
&gt; 
&gt; 
&gt; 
&gt; 
&gt;         return dist, xyuv
</code></pre>
<p>i do this wrapper class. Is it right for you?</p>

albanD: <p>You can use triple backticks ` like in github to format your code <img src="https://discuss.pytorch.org/images/emoji/apple/wink.png?v=9" title=":wink:" class="emoji" alt=":wink:"></p>
<p>It looks suspicious to me that your create a brand new Linear layer in the forward pass and return it, is that a typo?</p>

Giuseppe: <p>Thanks for the reply.<br>
Yes, the return line is:</p>
<pre><code class="lang-auto">return dist, xyuv(z)
</code></pre>
<p>But semantically is correct for my purpose?</p>

albanD: <p>So the problem is that because you create this linear during the forward, it will have new random weights at each forward and it’s weights are not passed to the optimizer when you do model.parameters().<br>
Maybe that is what you want.</p>
<p>If you don’t want that and want the Linear to be learnt, you need to push its creation to the <code>__init__</code> function and have a <code>self.fc = nn.Linear((128*(n_features_x + n_features_y)), 4)</code> and change your forward to do <code>self.fc(z)</code>.</p>

Giuseppe: <pre><code class="lang-auto">class Compound_Model_final(nn.Module):

    def __init__(self):
        super().__init__()

        self.model1 = fcn_resnet50(num_classes=9)
        self.model2= _resnet_shallow(pretrained=False)

        self.model3 = models.resnet50(pretrained=False)

        self.model3.load_state_dict(torch.load("Regressione_ResNet50_cartesian_angle_M95.pth"))

        n_features_x = self.model2.fc.in_features
        n_features_y = self.model3.fc.in_features

        self.fc = nn.Linear((128 * (n_features_x + n_features_y)), 4)

    def forward(self, x):

        dist = self.model1(x)['out']
        #dist = torch.softmax(dist.view(dist.shape[0],-1), dim =1).view(dist.shape)

        
        self.model2.fc = Identity()


        self.model3.fc = Identity()

        z = torch.cat([self.model2.fc, self.model3.fc ],1)
        




        return dist, self.fc(z)
</code></pre>
<p>Like this?</p>

albanD: <p>You should keep in mind that the forward method in pytorch is actually executing this code every time you do a forward with a given input.<br>
So setting the fc models to identity can be done only once in the <code>__init__</code> as well.<br>
The <code>cat</code> operation takes Tensors as input, not layers.<br>
I think you meant something like, assuming x is the input for both model 2 and 3:</p>
<pre><code class="lang-auto">model2_out = self.model2(x)
model3_out = self.model3(x)

z = torch.cat([model2_out, model3_out], 1)

return dist, self.fc(z)
</code></pre>

Giuseppe: <aside class="quote no-group" data-username="albanD" data-post="6" data-topic="57250">
<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/alband/48/215_2.png" class="avatar"> albanD:</div>
<blockquote>
<p>model2_out = self.model2(x) model3_out = self.model3(x) z = torch.cat([model2_out, model3_out], 1)</p>
</blockquote>
</aside>
<p>Thanks a lot  <img src="https://discuss.pytorch.org/images/emoji/apple/slight_smile.png?v=12" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"><br>
I passed the identity layers in the init functions and in the forward I accepted your suggestion .</p>