title: what is the difference between do output.backward(gradient=df) and loss.backward()?
body: <p>I am currently testing an open source repository(<a href="https://github.com/jzengust/RGBD2Normal" rel="nofollow noreferrer">https://github.com/jzengust/RGBD2Normal</a>) for surface normal estimation, the following function is used as the surface normal loss function:</p>
  <pre><code>def l1norm(input, label, mask, train=True):
      # input: bs*ch*h*w
      # label: bs*h*w*ch
      # mask: bs*h*w
      bz, ch, h, w = input.size()
      
      # normalization
      input = input.permute(0,2,3,1).contiguous().view(-1,ch)
      input_v = F.normalize(input,p=2)
      label_v = label.contiguous().view(-1,ch)
      target = torch.ones([input.size(0),], dtype=torch.float).cuda()
      mask_t = mask.contiguous().view(-1,1)
      mask_t = torch.squeeze(mask_t)
      target[torch.eq(mask_t,0)] = -1
      
      if(train == True): # use mask from surface normal
          loss = F.l1_loss(input_v, label_v, reduce=False)#compute inner product
          loss[torch.eq(mask_t,0)] = 0 #rm the masked pixels 
          loss = torch.mean(loss)
          df = torch.autograd.grad(loss,input_v,only_inputs=True)
          df = df[0]
          df = torch.autograd.grad(input_v,input,grad_outputs=df,only_inputs=True)
          df = df[0]
          mask = mask.contiguous().view(-1,1).expand_as(df)
          df[torch.eq(mask,0)] = 0
          df = df.view(-1, h, w, ch)
          df = df.permute(0,3,1,2).contiguous()
      else:  # use mask from depth valid
          loss = F.l1_loss(input_v, label_v, reduce=False)
          loss[torch.eq(mask_t, 0)] = 0
          loss = torch.mean(loss)
          df = None
      return loss, df
  </code></pre>
  <p>Then in the training process the gradient is back propagated by calling output.backward(gradient=df) instead of loss.backward(), the second one seems more common for me.
  My question is for which situation should we calculate the gradient with torch.autograd.grad() function and what is the benefits by doing this? Can i replace it with loss.backward()?</p>
  <p>Thank you for your help in advance!</p>