Loss.backward() : RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

Fatemeh_Behrad: <p>Hello,<br>
when I call loss.backward() I face the following problem:<br>
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn<br>
In my project (cloned from <a href="https://github.com/geomagical/lama-with-refiner" class="inline-onebox" rel="noopener nofollow ugc">GitHub - geomagical/lama-with-refiner: 🦙 LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WACV 2022</a>), I want to optimize an intermediate feature map while all network parameters remain unchanged (my network is pretrained).</p>
<p>This is my _infere function:</p>
<pre><code class="lang-auto">    masked_image = image * (1 - mask)
    masked_image = torch.cat([masked_image, mask], dim=1)
    mask = mask.repeat(1, 3, 1, 1)

    if ref_lower_res is not None:
        ref_lower_res = ref_lower_res.detach()
    with torch.no_grad():
        z1, z2 = forward_front(masked_image)
    # Inference
    mask = mask.to(device)
    ekernel = torch.from_numpy(cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15)).astype(bool)).float()
    ekernel = ekernel.to(device)
    image = image.to(device)
    z1, z2 = z1.detach().to(device), z2.detach().to(device)
    z1.requires_grad, z2.requires_grad = True, True
    loss_fn = nn.L1Loss(size_average=None, reduce=None, reduction='mean')
    optimizer = Adam([z1, z2], lr=lr)
    pbar = tqdm(range(n_iters), leave=False)
    for idi in pbar:
        optimizer.zero_grad()
        input_feat =(z1, z2)
        pred = forward_rear(input_feat)

        if ref_lower_res is None:
            break
        # losses = {}
        # ------------------------- multi-scale -------------------------
        # scaled loss with downsampler
        pred_downscaled = _pyrdown(pred[:, :, :orig_shape[0], :orig_shape[1]])
        mask_downscaled = _pyrdown_mask(mask[:, :1, :orig_shape[0], :orig_shape[1]], blur_mask=False, round_up=False)
        mask_downscaled = _erode_mask(mask_downscaled, ekernel=ekernel)
        mask_downscaled = mask_downscaled.repeat(1, 3, 1, 1)

        loss = loss_fn(pred[mask &lt; 1e-8], image[mask &lt; 1e-8]) + \
               loss_fn(pred_downscaled[mask_downscaled &gt;= 1e-8], ref_lower_res[mask_downscaled &gt;= 1e-8])

        pbar.set_description(
            "Refining scale {} using scale {} ...current loss: {:.4f}".format(scale_ind + 1, scale_ind, loss.item()))
        if idi &lt; n_iters - 1:
            loss.backward()
            optimizer.step()  # to optimize z
            del pred_downscaled
            del loss
            del pred

    # "pred" is the prediction after Plug-n-Play module
    inpainted = mask * pred + image * (1 - mask)
    inpainted = inpainted.detach().cpu()
    return inpainted
</code></pre>
<p>when I write loss.requires_grad = True before loss.backward, loss remains constant. I have checked other topics, but none of them were helpful.<br>
What is the problem?<br>
As I’ve noticed loss.backward calculates the gradient of all parameters for which we set required_grad= True. So is there any way to check which parameters have required_grad= True?</p>

ptrblck: <p>You are most likely detaching the loss from the computation graph e.g. by using a non-differentiable operation in the model or the loss calculation. Could you post a minimal, executable code snippet which would reproduce the issue, please?</p>
<aside class="quote no-group" data-username="Fatemeh_Behrad" data-post="1" data-topic="157705">
<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/fatemeh_behrad/48/51845_2.png" class="avatar"> Fatemeh_Behrad:</div>
<blockquote>
<p>when I write loss.requires_grad = True before loss.backward, loss remains constant.</p>
</blockquote>
</aside>
<p>Yes, this is expected as setting <code>requires_grad=True</code> on the <code>loss</code> would fix the runtime error, but will not fix the underlying error (detached computation graph).</p>
<aside class="quote no-group" data-username="Fatemeh_Behrad" data-post="1" data-topic="157705">
<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/fatemeh_behrad/48/51845_2.png" class="avatar"> Fatemeh_Behrad:</div>
<blockquote>
<p>So is there any way to check which parameters have required_grad= True?</p>
</blockquote>
</aside>
<p>Yes, you can iterate all parameters and check their attributes via:</p>
<pre data-code-wrap="python"><code class="lang-python">for param in model.parameters():
    print(param.requires_grad)
</code></pre>

Fatemeh_Behrad: <p>Thank you so much for your quick response.<br>
As the project is very complicated, I cannot reproduce the problem with a few lines. Therefore, I have debugged my code to show you the problem. This is the result. When I make prediction, the output is detached by default. Then when I use this output for calculating loss, the grad_fn of loss is None again.<br>
Is there any way to attach a parameter manually?<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/2/5/2520af75344276a3d8d9d16dbb89ff6264cd7c45.png" data-download-href="https://discuss.pytorch.org/uploads/default/2520af75344276a3d8d9d16dbb89ff6264cd7c45" title="1"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/2/5/2520af75344276a3d8d9d16dbb89ff6264cd7c45_2_690x431.png" alt="1" data-base62-sha1="5irH3IlnEHepkfsrlW1CDT5Gg8R" width="690" height="431" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/2/5/2520af75344276a3d8d9d16dbb89ff6264cd7c45_2_690x431.png, https://discuss.pytorch.org/uploads/default/optimized/3X/2/5/2520af75344276a3d8d9d16dbb89ff6264cd7c45_2_1035x646.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/2/5/2520af75344276a3d8d9d16dbb89ff6264cd7c45_2_1380x862.png 2x" data-dominant-color="393B3D"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">1</span><span class="informations">1920×1200 215 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/2/a/2af20fdec49aa5fd63c2f4c456900dbd91018991.png" data-download-href="https://discuss.pytorch.org/uploads/default/2af20fdec49aa5fd63c2f4c456900dbd91018991" title="2"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/2/a/2af20fdec49aa5fd63c2f4c456900dbd91018991_2_690x431.png" alt="2" data-base62-sha1="67UFulXUZxxUfwHRdqnGfTYvq25" width="690" height="431" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/2/a/2af20fdec49aa5fd63c2f4c456900dbd91018991_2_690x431.png, https://discuss.pytorch.org/uploads/default/optimized/3X/2/a/2af20fdec49aa5fd63c2f4c456900dbd91018991_2_1035x646.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/2/a/2af20fdec49aa5fd63c2f4c456900dbd91018991_2_1380x862.png 2x" data-dominant-color="393B3E"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">2</span><span class="informations">1920×1200 234 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/3/2/3209296305b0609efc3a8f12903572dbf1e96ab9.png" data-download-href="https://discuss.pytorch.org/uploads/default/3209296305b0609efc3a8f12903572dbf1e96ab9" title="3"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/3/2/3209296305b0609efc3a8f12903572dbf1e96ab9_2_690x431.png" alt="3" data-base62-sha1="78Dv8R5w2fdXepeMd0azXYGJsGB" width="690" height="431" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/3/2/3209296305b0609efc3a8f12903572dbf1e96ab9_2_690x431.png, https://discuss.pytorch.org/uploads/default/optimized/3X/3/2/3209296305b0609efc3a8f12903572dbf1e96ab9_2_1035x646.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/3/2/3209296305b0609efc3a8f12903572dbf1e96ab9_2_1380x862.png 2x" data-dominant-color="393C3F"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">3</span><span class="informations">1920×1200 219 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>Note: In this network , z is optimized.</p>

Fatemeh_Behrad: <p>As I feel the problem is caused by my model I send you the output of the debugging of my model. Here, we split our model into two parts, and use them form prediction.<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/b/6/b64b88ea095f4b9e393360d4ee564b602178d2f6.png" data-download-href="https://discuss.pytorch.org/uploads/default/b64b88ea095f4b9e393360d4ee564b602178d2f6" title="4"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/b/6/b64b88ea095f4b9e393360d4ee564b602178d2f6_2_690x431.png" alt="4" data-base62-sha1="q0EJoGODYaG6vPWkSJSnQs91AAC" width="690" height="431" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/b/6/b64b88ea095f4b9e393360d4ee564b602178d2f6_2_690x431.png, https://discuss.pytorch.org/uploads/default/optimized/3X/b/6/b64b88ea095f4b9e393360d4ee564b602178d2f6_2_1035x646.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/b/6/b64b88ea095f4b9e393360d4ee564b602178d2f6_2_1380x862.png 2x" data-dominant-color="424345"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">4</span><span class="informations">1920×1200 264 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/2/5/2523bd6c619adaeda977a93cd1f63dfa8a705e77.png" data-download-href="https://discuss.pytorch.org/uploads/default/2523bd6c619adaeda977a93cd1f63dfa8a705e77" title="6"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/2/5/2523bd6c619adaeda977a93cd1f63dfa8a705e77_2_690x431.png" alt="6" data-base62-sha1="5iyeOc2gXqiRW82UYaxQbbf94Xl" width="690" height="431" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/2/5/2523bd6c619adaeda977a93cd1f63dfa8a705e77_2_690x431.png, https://discuss.pytorch.org/uploads/default/optimized/3X/2/5/2523bd6c619adaeda977a93cd1f63dfa8a705e77_2_1035x646.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/2/5/2523bd6c619adaeda977a93cd1f63dfa8a705e77_2_1380x862.png 2x" data-dominant-color="414445"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">6</span><span class="informations">1920×1200 266 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>

ptrblck: <aside class="quote no-group" data-username="Fatemeh_Behrad" data-post="3" data-topic="157705">
<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/fatemeh_behrad/48/51845_2.png" class="avatar"> Fatemeh_Behrad:</div>
<blockquote>
<p>Is there any way to attach a parameter manually?</p>
</blockquote>
</aside>
<p>No, that’s not possible. Once you’ve detached a tensor from the computation graph you could create a new graph but cannot reattach it.</p>
<p>In one of your screenshots you are explicitly executing the forward pass in a <code>no_grad()</code> context which would not create a computation graph at all, so you won’t be able to use <code>backward()</code> on this output or any resulting tensor created by this output.</p>
<p>You can post code snippets by wrapping them into three backticks ```, which would allow me to debug the issue as the screenshots are not really helpful in trying to isolate the error.</p>

Fatemeh_Behrad: <p>Thank you so much for your time and quick response.<br>
I did not know with torch.no_grad the computation graph would not be created at all.<br>
You helped me a lot. Thank you.</p>