# ReEig Layer
def cal_rect_cov(features):
# features=features.detach().cpu()
result=[]
# features=torch.tensor(features,requires_grad=True)
for i in range(features.shape[0]):
s_f,v_f=torch.eig(features[i], eigenvectors=True)
s_f_convert=[]
for i in range(len(s_f)):
s_f_convert.append(s_f[i][0])
s_f_convert = torch.stack(s_f_convert)
s_f2=torch.clamp(s_f_convert,0.0001,10000)
s_f2=torch.diag(s_f2)
features_t=torch.matmul(torch.matmul(v_f,s_f2),v_f.t())
result.append(features_t)
result = torch.stack(result)
# result=result.cuda()
return result
Gradients (âbackward passâ) are not implemented for torch.eig(). If your features matrix is symmetric
(or can naturally be made symmetric), you can use torch.symeig(), otherwise you will have to rethink
your loss function.
Extra care needs to be taken when backward through
outputs. Such operation is really only stable when
all eigenvalues are distinct. Otherwise, NaN can
appear as the gradients are not properly defined.
Let me just say that there is nothing fundamentally improper
about using eigenvalues (or eigenvectors) as ingredients in
your loss function, but eigenvalues can be a little tricky, both
in terms of how they depend mathematically on your inputs,
and sometimes the numerical stability of the algorithms used
to calculate them. So you should think through carefully how
and why youâre using them.
It sounds like you are trying to translate the âCovariance Poolingâ
algorithm from tensorflow to pytorch. This might well involve
some amount of work, but I would expect it to be doable.
And a question:
It sounds like you are saying that symeig is giving you ânoneâ for
the value of its gradient. Is this the issue you are asking about?
(I should note that I havenât ever used symeig.)
Could you try to isolate this problem and post a small, complete,
runnable pytorch script where you evaluate symeig on some
inputs, call backward(), and then print out the gradients you
get?
If we start with something simple like that, we can try to analyze
your gradient issue.
Well, if youâre getting ânoneâ gradients during training, thereâs
almost certainly a bug somewhere, more likely in your code,
but possibly, though less likely, in pytorch.
If you donât find the bug fairly quickly just looking through your
code, then more orderly debugging is called for. A common
approach is to break thing up into pieces to try and isolate the
bug.
As I suggested in my previous post, you might try just seeing
if you can get a gradient out of symeig. My suggestion would
be that you post a short, complete, runnable pytorch script
that pumps a tensor (with requires_grad set) through symeig and somehow calculates a scalar (single number)
from that. Then call backward() on that scalar and see if
your input tensor has good gradients or just ânoneâ.
If you post the script and your results, forum participants can
not only look at it, but run it for themselves, and maybe they
will see something or have ideas about what is going on.