Skip to content
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

Unified inputs for F.rotate #2495

Merged
merged 6 commits into from
Aug 5, 2020

Conversation

vfdev-5
Copy link
Collaborator

@vfdev-5 vfdev-5 commented Jul 21, 2020

Related to #2292

Description:

  • Added code for F_t.rotate with test
  • updated F.affine tests

@codecov
Copy link

codecov bot commented Jul 21, 2020

Codecov Report

Merging #2495 into master will increase coverage by 0.07%.
The diff coverage is 84.37%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2495      +/-   ##
==========================================
+ Coverage   70.73%   70.80%   +0.07%     
==========================================
  Files          94       94              
  Lines        8029     8077      +48     
  Branches     1275     1283       +8     
==========================================
+ Hits         5679     5719      +40     
- Misses       1946     1950       +4     
- Partials      404      408       +4     
Impacted Files Coverage Δ
torchvision/transforms/functional.py 80.11% <71.42%> (-0.72%) ⬇️
torchvision/transforms/functional_tensor.py 67.39% <86.36%> (+2.48%) ⬆️
torchvision/transforms/functional_pil.py 65.02% <100.00%> (+1.18%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update df6a796...a249f77. Read the comment docs.


point = torch.tensor([0.0, 0.0, 1.0])
for i in range(oh):
for j in range(ow):
Copy link
Collaborator Author

@vfdev-5 vfdev-5 Jul 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, we should optimize grid computation, e.g. matrix of points by theta matrix multiplication.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should optimize this otherwise the performance will be very bad.

Can't we do something like (untested and probably has bugs)

i = (torch.arange(oh) + d - oh * 0.5) / (0.5 * h)
j = (torch.arange(ow) + d - ow * 0.5) / (0.5 * w)
ii, jj = torch.meshgrid(i, j)
coords = torch.stack([j, i], dim=-1)
output_grid = torch.matmul(coords, theta.T)

Note that I removed the 3rd coordinate of point, it might be that it's necessary and we should put it back but this gives the gist of it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the code snippet. Yes, it is something like that, I was trying to implement it from my side too :)

Copy link
Member

@fmassa fmassa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the PR!

I have a few questions and comments that I think would make the code a bit simpler and faster, let me know what you think.

We can do it in two ways -- we can either merge this and then have an immediate follow-up task to optimize this function, or do it here. We can do as you prefer.


point = torch.tensor([0.0, 0.0, 1.0])
for i in range(oh):
for j in range(ow):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should optimize this otherwise the performance will be very bad.

Can't we do something like (untested and probably has bugs)

i = (torch.arange(oh) + d - oh * 0.5) / (0.5 * h)
j = (torch.arange(ow) + d - ow * 0.5) / (0.5 * w)
ii, jj = torch.meshgrid(i, j)
coords = torch.stack([j, i], dim=-1)
output_grid = torch.matmul(coords, theta.T)

Note that I removed the 3rd coordinate of point, it might be that it's necessary and we should put it back but this gives the gist of it

torchvision/transforms/functional.py Show resolved Hide resolved
return _apply_grid_transform(img, grid, mode)


def _compute_output_size(theta: Tensor, w: int, h: int) -> Tuple[int, int]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this (relatively expensive) function for calculating the output size? I think we can get it in constant time.

From some quick analysis, we might be able to get the height/width of the new image via something like

h_new = h * sin(alpha) + w * cos(alpha)
w_new = h * cos(alpha) + w * sin(alpha)

(but math should be verified, and angles might be off)
20200729_112911

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Analytical approach can be nice :)
Here there matrix computations for just 4 points, so it is not that expensive. Let me check if I can provide an analytical computation with the same result as PIL.

@@ -418,21 +418,21 @@ def test_affine(self):
test_configs = [
(45, [5, 6], 1.0, [0.0, 0.0]),
(33, (5, -4), 1.0, [0.0, 0.0]),
(45, [5, 4], 1.2, [0.0, 0.0]),
(33, (4, 8), 2.0, [0.0, 0.0]),
(45, [-5, 4], 1.2, [0.0, 0.0]),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason why we are changing those values?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests were missing negative transpose values, so added just them.

Copy link
Collaborator Author

@vfdev-5 vfdev-5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comments Francisco ! I'll update the PR and ping you once it is ready

@@ -418,21 +418,21 @@ def test_affine(self):
test_configs = [
(45, [5, 6], 1.0, [0.0, 0.0]),
(33, (5, -4), 1.0, [0.0, 0.0]),
(45, [5, 4], 1.2, [0.0, 0.0]),
(33, (4, 8), 2.0, [0.0, 0.0]),
(45, [-5, 4], 1.2, [0.0, 0.0]),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests were missing negative transpose values, so added just them.

torchvision/transforms/functional.py Show resolved Hide resolved
return _apply_grid_transform(img, grid, mode)


def _compute_output_size(theta: Tensor, w: int, h: int) -> Tuple[int, int]:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Analytical approach can be nice :)
Here there matrix computations for just 4 points, so it is not that expensive. Let me check if I can provide an analytical computation with the same result as PIL.


point = torch.tensor([0.0, 0.0, 1.0])
for i in range(oh):
for j in range(ow):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the code snippet. Yes, it is something like that, I was trying to implement it from my side too :)

@vfdev-5 vfdev-5 requested a review from fmassa August 3, 2020 16:10
Copy link
Member

@fmassa fmassa left a 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!

return int(size[0]), int(size[1])


def _expanded_affine_grid(theta: Tensor, w: int, h: int, expand: bool = False) -> Tensor:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given that we will be using our own _gen_affine_grid, I think it can be part of this function maybe?

@fmassa fmassa merged commit 7666252 into pytorch:master Aug 5, 2020
@vfdev-5 vfdev-5 mentioned this pull request Aug 7, 2020
16 tasks
bryant1410 pushed a commit to bryant1410/vision-1 that referenced this pull request Nov 22, 2020
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants