Hi Sunil!



 Sunil_Sharma1:

I am trying to minimise the mse loss with constrain loss but constrain was increasing instead of decreasing.then i tried to only minimise constrain then it throw following error.
    self.sobelx=nn.Conv2d(1,1,kernel_size=kernel_size,padding=padding,bias=False)
    self.relu=nn.ReLU()
    self.sobely=nn.Conv2d(1,1,kernel_size=kernel_size,padding=padding,bias=False)
...
    sobelx=self.sobelx.weight.data.squeeze().squeeze()
    sobely=self.sobely.weight.data.squeeze().squeeze()
    loss_constrain=torch.matmul(sobelx,sobely.transpose(0,1)).trace()
...
#Error Message:
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn



Your use of .data “breaks the computation graph,” so that no gradients are
backpropagated through loss_constrain.  Therefore, when you only minimize
loss_constrain you get the reported error.  When you also minimize
loss_mse (assuming that loss() returns total_loss) you do have gradients
that connect total_loss to your model parameters, so the error goes away.
However, loss_constrain is still disconnected from the computation graph,
so its gradients are not calculated and make no contribution to the gradients
calculated for total_loss.  Therefore your gradient-descent optimization
knows nothing about loss_constrain and there will be no tendency for
loss_constrain to be made smaller.
Also note that even if you remove .data, I believe that there is nothing that
prevents loss_constrain (the trace of the product of your two convolution
kernels) from becoming large and negative.  So gradient descent will, roughly
speaking, ultimately drive one kernel off to +inf and the other off to -inf so
that loss_constrain becomes -inf (and dominates total_loss).
I don’t really follow what you are trying to do with loss_constrain, but
something like:
total_loss = loss_mse + wt_constrain * loss_constrain**2

would at least prevent the -inf problem.  (And, yes, I would include the
weighting factor wt_constrain so that you can adjust how strongly
loss_constrain contributes to your overall loss.)
(One final note:  Putting torch.manual_seed(1) in the constructor for
Edge_Detector is not a good idea, as this sets the seed for the “global”
random number generator, affecting any other random-number calls, and
should you construct more than one Edge_Detector, the seed will be
reset.  This could work for your use case, but is likely to become fragile as
you add more code to your system.)
Good luck.
K. Frank