-
Notifications
You must be signed in to change notification settings - Fork 7k
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
Fixes F.affine and F.rotate to support rectangular tensor images #2553
Conversation
- updated F.affine tests
…-5/issue-2292-rotate
torchvision/transforms/functional.py
Outdated
|
||
matrix = _get_inverse_affine_matrix([0, 0], angle, translate, scale, shear) | ||
matrix = _get_inverse_affine_matrix([0, 0], angle, translate_f, scale, shear) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, I do not like that depending on if image is square or not matrice's translation part is normalized or not...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just make everything follow the same code-path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that in case of square image we use affine_grid
and it requires rescaled translation part, so we compute matrix
here with rescaled translate_f
. In case of rectangular images, we use custom affine grid implementation _gen_affine_grid
where coords normalization is applied a posteriori and we need to deal with matrix
where translation part is not normalized. Online normalization,denormalization of matrix
is not evident neither. That's why there are two pathes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't we just use _gen_affine_grid
everywhere?
pts = torch.stack([x, y, torch.ones_like(x)], dim=-1) | ||
output_grid = torch.matmul(pts, theta.t()) | ||
|
||
output_grid = output_grid / torch.tensor([0.5 * w, 0.5 * h]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the principal difference to affine_grid
-like implementation. In affine_grid
-lik implementation it would be
x = (torch.arange(ow) + d - ow * 0.5) / (0.5 * w)
y = (torch.arange(oh) + d - oh * 0.5) / (0.5 * h)
instead of output_grid
scaling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing this!
I have a few questions, let me know what you think
if shape[-2] == shape[-1]: | ||
# here we need normalized translation part of theta | ||
grid = affine_grid(theta, size=(1, shape[-3], shape[-2], shape[-1]), align_corners=False) | ||
else: | ||
# here we need denormalized translation part of theta | ||
grid = _gen_affine_grid(theta[0, :, :], w=shape[-1], h=shape[-2], ow=shape[-1], oh=shape[-2]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you replace everything to use _gen_affine_grid
, and make a comment on why affine_grid
is not suited for this use-case? I even wonder if we shouldn't open an issue in PyTorch about this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't benchmarked both methods to compare the performances, I assumed that affine_grid
is better optimized that manual _gen_affine_grid
. That's why I've chosen to split here. Do you mean to wrap everything with _gen_affine_grid
and split inside this method ?
About an issue in PyTorch, I think pytorch/pytorch#24870 and pytorch/pytorch#36107 already speak about absolute pixel coords. Probably, they are related to this problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean to just dispatch to _gen_affine_grid
, and not use nn.functional.affine_grid
. The difference in speed should be very small I think, I'm not sure we dispatch to a cudnn-optimized affine_grid
so it would be basically the same operations but called from C++
torchvision/transforms/functional.py
Outdated
|
||
matrix = _get_inverse_affine_matrix([0, 0], angle, translate, scale, shear) | ||
matrix = _get_inverse_affine_matrix([0, 0], angle, translate_f, scale, shear) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just make everything follow the same code-path?
…ffine-rect-imgs
- due to bad merge
@fmassa PR is ready to review. What is done:
|
Codecov Report
@@ Coverage Diff @@
## master #2553 +/- ##
=======================================
Coverage 71.81% 71.81%
=======================================
Files 94 94
Lines 8079 8080 +1
Branches 1283 1282 -1
=======================================
+ Hits 5802 5803 +1
Misses 1868 1868
Partials 409 409
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks a lot!
…orch#2553) * Added code for F_t.rotate with test - updated F.affine tests * Rotate test tolerance to 2% * Fixes failing test * Optimized _expanded_affine_grid with a single matmul op * Recoded _compute_output_size * [WIP] recoded F_t.rotate internal methods * [WIP] Fixed F.affine to support rectangular images * Recoded _gen_affine_grid to optimized version ~ affine_grid - Fixes flake8 * [WIP] Use _gen_affine_grid for affine and rotate * Fixed tests on square / rectangular images for affine and rotate ops * Removed redefinition of F.rotate - due to bad merge
Description:
Currently,
F.affine
does not work correctly on rectangular tensor images due to normalized output ofaffine_grid
.In this PR there is an attempt to fix the issue. Code is not nice due to dispatch in two part of implementations.
EDIT: Same is for
F.rotate
.F.affine
andF.rotate