-
Notifications
You must be signed in to change notification settings - Fork 22.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unexpected behaviour for affine_grid and grid_sample with 3D inputs #35775
Comments
I'm not an expert on affine transformations so I can't tell exactly what the error is, but I would guess that the math for the 3d case is wrong somewhere. Perhaps someone on the forums would know. |
Thanks! I'll try to post on the forums. |
I've just tested this on GPU and the CUDA function also has the exact same problem. This is the setup:
|
Thanks for reporting this issue, @EmilienDupont. We you able to find a resolution on the forums, or have you been able to identify what you think is going on? |
Hi @mruberry, The problem ended up being that grid_sample performs an inverse warping, which means that passing an affine_grid for the matrix A actually corresponds to the transformation A^(-1). So in my example above, the transformation with B followed by A actually corresponds to A^(-1)B^(-1) = (BA)^(-1), which means I should use C = BA and not C = AB as would be the case if the original matrix was used by grid_sample. The reason why it worked in 2D and not 3D is because 2D rotation matrices commute whereas 3D rotation matrices do not. In addition to this, it seems like the order of the coordinates is also inverted, i.e. for an (N, C, D, H, W) tensor, the (D, H, W) dimensions correspond to (z, y, x) instead of (x, y, z). I'm not sure exactly why this is. There's also some discussion on the forums. Thank you! |
Thanks for the update, @EmilienDupont. What you're saying makes a lot of sense. Would you be interested in helping improve our documentation so there's less confusion in the future? |
🐛 Bug
When performing affine transformations on 3D tensors I’ve noticed some unexpected behaviour which does not occur for 2D tensors.
Specifically, suppose we perform two 3D rotations with two rotation matrices
A
andB
. Given a 3D input tensorx
, we can first rotate it withB
to get the rotated tensorx_B
. We can then further rotatex_B
byA
to get the rotation corresponding toB
followed byA
, i.e. to the rotation matrixAB
. We can denote this resulting tensor byx_AB
.Alternatively, we could have directly taken the matrix product
C = AB
and transformed the tensor withC
, to obtainx_C
. Nowx_AB
andx_C
should be approximately equal up to sampling errors. However in practice this is not the case. As an example:Clearly, the cube rotated by
B
followed byA
is not the same as the one rotated byC=AB
. Note that this does not happen in 2D. If we perform similar transformations to a 2D input, we obtain:As can be seen, the transformations by
AB
andC
are roughly the same (AB
has more sampling noise since it corresponds to two affine transformations and two grid_samples), so the error does not occur in 2D.Any idea why the difference in 3D might be occurring? Thank you!
To Reproduce
Expected behavior
Rotating a tensor by
B
followed byA
should be approximately the same as rotating byAB
.Environment
conda
,pip
, source): pipcc @albanD @mruberry
The text was updated successfully, but these errors were encountered: