Optimizer dont update weights

kiru883: <p>Hello, thank for attention I ran into the following problem, the weights before and after did not change, here is the code:</p>
<p>class fastRCNN(torch.nn.Module):</p>
<pre><code>def __init__(self, params):

    super(fastRCNN, self).__init__()

    # roi pooling size

    self.rsize = params['roi']['output_size']

    ###########################   model architecture

    ###########################   CNN BLOCK

    self.cnn_block = layer.Sequential(

        layer.Conv2d(**params['cnn11']),

        layer.Conv2d(**params['cnn12']),

        layer.AvgPool2d(**params['pool1']),

        ##################################

        layer.Conv2d(**params['cnn21']),

        layer.Conv2d(**params['cnn22']),

        layer.AvgPool2d(**params['pool2']),

        ##################################

        layer.Conv2d(**params['cnn31']),

        layer.Conv2d(**params['cnn32']),

        layer.Conv2d(**params['cnn33']),

        layer.AvgPool2d(**params['pool3']),

        ##################################

        layer.Conv2d(**params['cnn41']),

        layer.Conv2d(**params['cnn42']),

        layer.Conv2d(**params['cnn43']),

        layer.AvgPool2d(**params['pool4']),

    )

    ########### **ROI LAYER** ##########

    ###########################   FC

    self.fc_block = layer.Sequential(

        layer.Linear(**params['dense11']),

        layer.Linear(**params['dense12'])

    )

    ###########################   CLASSIFIER OUTPUT

    self.classifier_output = layer.Sequential(

        layer.Linear(**params['denseclf'])

        #layer.Softmax()

    )

    ###########################   REGRESSOR OUTPUT

    self.regressor_output = layer.Linear(**params['densereg'])

def forward(self, Ximg, Xroi):

    cnn_inp = self.cnn_block(Ximg)

    ###########################

    roi_inp = roi_pool(cnn_inp, Xroi, self.rsize)

    ###########################

    inp = roi_inp.view(383, 512*7*7)

    inp = self.fc_block(inp)

    ###########################

    classif_out = self.classifier_output(inp)

    ###########################

    regress_out = self.regressor_output(inp)

    return torch.cat((classif_out, regress_out), dim=1)
</code></pre>
<p>params = {</p>
<pre><code>            "cnn11": {"in_channels":3, "out_channels":64, "kernel_size":3},

            "cnn12": {"in_channels": 64, "out_channels":64,"kernel_size": 3},

            "pool1": {"kernel_size": 3},

            "cnn21": {"in_channels": 64, "out_channels":128, "kernel_size": 3},

            "cnn22": {"in_channels": 128, "out_channels":128, "kernel_size": 3},

            "pool2": {"kernel_size": 3},

            "cnn31": {"in_channels": 128, "out_channels":256, "kernel_size": 3},

            "cnn32": {"in_channels": 256, "out_channels":256 ,"kernel_size": 3},

            "cnn33": {"in_channels": 256, "out_channels":256, "kernel_size": 3},

            "pool3": {"kernel_size": 3},

            "cnn41": {"in_channels": 256, "out_channels":512, "kernel_size": 3},

            "cnn42": {"in_channels": 512, "out_channels":512, "kernel_size": 3},

            "cnn43": {"in_channels": 512, "out_channels":512, "kernel_size": 3},

            "pool4": {"kernel_size": 2},

            "roi": {"output_size": [7, 7]},

            "dense11": {"in_features":512*7*7, "out_features":4096},

            "dense12": {"in_features":4096, "out_features":4096},

            "denseclf": {"in_features":4096, "out_features": 1},

            "densereg": {"in_features":4096, "out_features": 4}

        }
</code></pre>
<p>model = fastRCNN(params)</p>
<p>Code for training model:</p>
<p>def lossf(tPred, tTrue):</p>
<pre><code>p = torch.autograd.Variable(tPred[0].data, requires_grad=True)

print("test", p)

b = torch.autograd.Variable(tPred[1:].data, requires_grad=True)

a = torch.autograd.Variable(tTrue[1:].data, requires_grad=True) 

print("test", a)

return torch.sum(torch.abs(b-a)) - torch.log(p)
</code></pre>
<p>optimizer.zero_grad()</p>
<p>labels = torch.from_numpy(out[0])</p>
<p>outputs = model(torch.from_numpy(rgb_matr), torch.from_numpy(np.insert(one_img[1], 0, np.arange(one_img[1].shape[0]), axis=1)))</p>
<p>for ypred, ytrue in zip(outputs, labels):</p>
<pre><code>loss = lossf(ypred, ytrue)

loss.backward(retain_graph=True)

optimizer.step()</code></pre>

ptrblck: <p>You are detaching the tensor(s) from the computation graph by creating new <code>Variables</code>:</p>
<pre><code class="lang-python">p = torch.autograd.Variable(tPred[0].data, requires_grad=True)
...
</code></pre>
<p>Instead of recreating these tensors, you should directly calculate the loss.</p>
<p>Also, <code>Variables</code> are deprecated since <code>PyTorch</code> 0.4<code>so you can use tensors in newer versions. The usage of the</code>.data` attribute is also not recommended, as it might have unwanted side effects.</p>

kiru883: <p>Thank you very much for your reply! I was forced to use p = torch.autograd.Variable(tPred[0].data, requires_grad=True) due to an error one of the variables needed for gradient computation has been modified by an inplace operation… how i can use yPred with clices in my custom loss as torch.log(tPred[0]) + torch.sum(torch.abs(tPred[1:] - tTrue[1:])) ?</p>

ptrblck: <p>This loss calculation seems to work for this code snippet:</p>
<pre><code class="lang-python">model = models.resnet50()
out = model(torch.randn(2, 3, 224, 224))
target = torch.zeros(2)

# Clip output, otherwise you might get NaNs
out = torch.clamp(out, 1e-6, out.max().item())
loss = torch.log(out[0]) + torch.sum(torch.abs(out[1:] - target[1:]))
loss.mean().backward()
</code></pre>
<p>Note that I had to clamp the output, as I would get NaN values from the log of negative numbers.</p>

kiru883: <p>Thank, and last 2 questions,</p>
<ol>
<li>How fix “one of the variables needed for gradient computation has been modified by an inplace operation…”, what is inplace operations in torch?</li>
<li>Does backpropagation pass through the function roi_pool from torchvision.ops?</li>
</ol>

ptrblck: <ol>
<li>
<p>Inplace operation manipulate the data in the tensor directly without creating a new return tensor. Such operations would have an underscore such as <code>tensor.sigmoid_()</code>. If you index a tensor and assign a value to it, this error might also be raised, so you should instead create a new tensor using the return values.</p>
</li>
<li>
<p>Yes, the <code>ROIPool</code> layer has a backward method and thus Autograd can compute the gradient and pass the gradient to the previous layers.</p>
</li>
</ol>

kiru883: <p>Thank for your answers, I will solve the problem.</p>

kiru883: <p>Hello, I used the ready-made loss function from torch.nn, but error “one of the variables needed for gradient computation has been modified by an inplace operation: [torch.FloatTensor [4096, 1]]” everything is also there, maybe there is a problem in forward method? The model has 2 inputs and two outputs, I do not know what to do.</p>
<p>def forward(self, Ximg, Xroi):<br>
cnn_inp = self.cnn_block(Ximg)<br>
###########################<br>
roi_inp = roi_pool(cnn_inp, Xroi, self.rsize)<br>
###########################<br>
inp = roi_inp.view(500, 512<em>7</em>7)<br>
fc_inp = self.fc_block(inp)<br>
###########################<br>
classif_out = self.classifier_output(fc_inp)<br>
###########################<br>
regress_out = self.regressor_output(fc_inp)<br>
output = torch.cat((classif_out, regress_out), dim=1)<br>
return classif_out, regress_out</p>
<p>By the way, the model output has a dimension example (500, 5) and therefore the back propagation should find the gradient and update the weights for each of the output vectors with a dimension (5,) maybe this has some kind of error? Also sometimes an error appears “Function ‘AddmmBackward’ returned nan values in its 2th output”</p>

kiru883: <p>Therefore, if im summarize and group information:</p>
<ol>
<li>
<p>I get loss from my outputs, loss return scalar:<br>
loss1 = lossf1(clf_output[0], label_clf[0])<br>
loss2 = lossf2(reg_output[0], label_reg[0])<br>
loss = loss1 + loss2<br>
*where clf_output[0] or reg_output[0] vectors<br>
and i get error “Function ‘AddmmBackward’ returned nan values in its 2th output.”</p>
</li>
<li>
<p>Before as i get error, i place loss scalar in tensor with argument (loss = torch.tensor([loss1+loss2], requires_grad=True))</p>
</li>
<li>
<p>I return to where I came from, model weights are not updated.</p>
</li>
</ol>

ptrblck: <ol>
<li>
<p>Have you checked the input to <code>torch.log</code>? As mentioned before, negative inputs will give you Nan outputs.</p>
</li>
<li>
<p>This will also detach your tensors and your model won’t get valid gradients. You should not recreate tensors, but use them directly.</p>
</li>
<li>
<p>See 2.</p>
</li>
</ol>