I performed some neural network training and produced a 50x50 SPD matrix called X which I compared to another SPD Y (ground truth), by putting both of them into Tangent space and computing a standard MSELoss between them. After some successful iterations during which the loss decreased, I decided to transform X back to "normal space" using untangent_space = SPDUnTangentSpace(unvectorize=False)
. I found that the result of untangent_space(X)
is very different from the true Y. To check again, I then performed the back conversion by taking scipy.linalg.expm(X)
instead of applying untangent_space
, and then the result was very close to the true Y, as expected.
I looked at spd.py, and the forward
function for SPDUnTangentSpace
seems ok... nothing suspicious.
Another interesting thing - when I applied scipy.linalg.logm
to the result of untangent_space(X)
, I obtained a version of X in which all the signs were flipped, as if scipy.linalg.logm(untangent_space(X)) = -X
. Very puzzling. As if it was a different leaf or something.
I cannot give you the exact matrices now for experimenting, but I'll try to come up with a more simple example (say, a 5x5 matrix). Maybe it has something to do with numerical stability of the SVD, or there's something in tangent_space in utils.py?.. I'll look to it, but meanwhile will refrain from using SPDUnTangentSpace.
UPD: Basically, X has nothing to do with the problem. It boils down to two observations:
untangent_space(tangent_space(Y)) != Y
scipy.linalg.logm(untangent_space(tangent_space(Y)) = -scipy.linalg.logm(Y)
By the way, you are using the SVD of a matrix and its diagonal part for computing the log_ and the exp_, while the original paper by Huang and Van Gool used the eigendecomposition. Is it equivalent?