Gradient flow stopped on a combined model

username: ruanheng
cooked: <p>Hi, I meet with a problem that the gradient cannot backpropagate on a combined network. I checked lots of answers but cannot find a relevant solution to this problem. I would appreciate it so much if we can solve this.</p>
<p>I wanted to calculate the gradient for input data in this code:<br>
‘’’<br>
for i, (input, target, impath) in tqdm(enumerate(data_loader)):<br>
# print(‘input.shape:’, input.shape)<br>
input = Variable(input.cuda(), requires_grad=True)<br>
output = model(input)<br>
loss = criterion(output, target.cuda())<br>
loss = Variable(loss, requires_grad=True)<br>
loss.backward()<br>
print(‘input:’, input.grad.data)<br>
‘’’<br>
but I got errror:<br>
‘’’<br>
print(‘input:’, input.grad.data)<br>
AttributeError: ‘NoneType’ object has no attribute ‘data’<br>
‘’’<br>
and my model is a combined model that I loaded the parameters from two pretrained models.<br>
I checked the requires_grad state-dict of model weights, it is true, however, the gradient of the model weights is None.<br>
Is it because I load the state-dict that caused the gradient block?</p>
<p>How can I deal with this problem?</p>
<p>The model structure is attached below:<br>
‘’’<br>
class resnet_model(nn.Module):<br>
def <strong>init</strong>(self, opt):<br>
super(resnet_model, self).<strong>init</strong>()</p>
<pre><code>    resnet = models.resnet101()
    num_ftrs = resnet.fc.in_features
    resnet.fc = nn.Linear(num_ftrs, 1000)

    if opt.resnet_path != None:
        state_dict = torch.load(opt.resnet_path)
        resnet.load_state_dict(state_dict)
        print("resnet load state dict from {}".format(opt.resnet_path))

    self.model1 = torch.nn.Sequential()

    for chd in resnet.named_children():
        if chd[0] != 'fc':
            self.model1.add_module(chd[0], chd[1])

    self.model2 = torch.nn.Sequential()

    self.classifier = LINEAR_LOGSOFTMAX(input_dim=2048, nclass=200)
    if opt.pretrained != None:
        self.classifier_state_dict = torch.load('../checkpoint/{}_cls.pth'.format(opt.pretrained))
        print("classifier load state dict from ../checkpoint/{}_cls.pth".format(opt.pretrained))
    self.classifier.load_state_dict(self.classifier_state_dict)

    for chd in self.classifier.named_children():
        self.model2.add_module(chd[0], chd[1])

def forward(self, x):
    x = self.model1(x)

    x = x.view(-1, 2048)

    x = self.model2(x)
    return x
</code></pre>
<p>‘’’</p>

username: albanD
cooked: <p>Hi,</p>
<p>Why do you have this line: <code>loss = Variable(loss, requires_grad=True)</code> ?<br>
<code>Variable</code> should not be used anymore.<br>
So the line above should be deleted and to mark a Tensor for which you want gradients, you can use:<br>
<code>input = input.cuda().requires_grad_()</code>.</p>

username: ptrblck
cooked: <p>Sorry for nitpicking: the <code>input</code> should be handled as suggested by <a class="mention" href="/u/alband">@albanD</a>, while the <code>loss</code> should not be rewrapped, as this will detach the computation graph.</p>

username: ruanheng
cooked: <p>Thanks! The problem is solved with the advice!</p>
<p>I should learn more about the pytorch sturcture.</p>
<p>Thanks again！</p>