Skip to content

Conversation

@ekagra-ranjan
Copy link
Contributor

@ekagra-ranjan ekagra-ranjan commented Sep 26, 2019

This PR makes crop transform scriptable as discussed in #1375.

@codecov-io
Copy link

codecov-io commented Sep 26, 2019

Codecov Report

Merging #1379 into master will decrease coverage by 0.03%.
The diff coverage is 50%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1379      +/-   ##
==========================================
- Coverage   64.46%   64.42%   -0.04%     
==========================================
  Files          83       83              
  Lines        6421     6428       +7     
  Branches      982      984       +2     
==========================================
+ Hits         4139     4141       +2     
- Misses       1992     1995       +3     
- Partials      290      292       +2
Impacted Files Coverage Δ
torchvision/transforms/functional_tensor.py 57.14% <50%> (-2.86%) ⬇️
torchvision/models/detection/roi_heads.py 55.3% <0%> (-0.47%) ⬇️
torchvision/models/detection/transform.py 66.92% <0%> (ø) ⬆️

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 53b062c...4e16aec. Read the comment docs.

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 @ekagra-ranjan !

I think that in order to support torchscript, we will need two (three?) functions for crop, one which only supports Tensor, the current one that supports PIL (and will be marked with a @torch.jit.ignore, and a glue function which will dispatch to one or the other, depending on the type of the input.

I'm not 100% clear on the approach yet, but I think it might make sense to create a new file containing only the scriptable transforms, first, and then we discuss at later steps how to better integrate them with the current set of transforms so that everything is as seamless as possible.

Also, once you have that, can you add tests that checks that the behavior for the different crop implementations is the same? Basically comparing the existing crop with the crop you've just implemented

@ekagra-ranjan
Copy link
Contributor Author

Hi @fmassa ! Made the changes you requested.


max_diff = (img_cropped_GT - img_cropped).abs().max()

assert max_diff < 5e-3, "Functional crop not working"
Copy link
Contributor

@surgan12 surgan12 Oct 17, 2019

Choose a reason for hiding this comment

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

As pointed out by @fmassa here in #1465 and also #1483 , let's change to self.assertTrue instead of normal assert.


if not F._is_tensor_image(img_tensor):
raise TypeError('tensor is not a torch image.')
raise TypeError('Input image is not a tensor.')
Copy link
Contributor

Choose a reason for hiding this comment

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

This message was the same as supplied here https://github.com/pytorch/vision/blob/53b062ca58932bbf387b96f2dd3397c4495b735b/torchvision/transforms/functional.py#L209 which already works on input tensor.
The above message would be confusing for the cases in which you supply a grayscale img tensor of the form HxW to the function. In this case the image is a tensor but not an accepted torch image but the error msg seem to mislead the user.
@ekagra-ranjan thoughts ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The link you provided isn't working but I get your concern. It's a valid point and I will revert the change.

@surgan12
Copy link
Contributor

@ekagra-ranjan @fmassa, since the transforms are happening on the tensors and we would ideally don't want them to be in-place by default, should we add a boolean like we have in normalize ?

If not, I think then we should add an in-place checking test to prevent any such behaviour due to some sneaky code-err.

@fmassa
Copy link
Member

fmassa commented Oct 18, 2019

@surgan12 the indexing that we perform in here indeed shares memory with the original tensors, but that's the same behavior that we already have in PIL.Image.crop, so I think this is fine.

import numpy as np, PIL

a = (np.random.rand(2, 2) > 0.5).astype(np.uint8)
i = PIL.Image.fromarray(a)
j = i.crop((0, 0, 1, 1))
aa = np.asarray(j)

print(a.flags.owndata)  # True
print(aa.flags.owndata)  # False, is a view

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 almost good, thanks!

I have only a couple of comments, and then this is good to merge, thanks!

self.assertTrue(torch.equal(img_tensor, hflipped_img_again))

def test_crop(self):
img_tensor = torch.FloatTensor(3, 16, 16).uniform_(0, 1)
Copy link
Member

Choose a reason for hiding this comment

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

Can you use torch.rand(3, 16, 16) instead? torch.FloatTensor is a legacy API and is deprecated


max_diff = (img_cropped_GT - img_cropped).abs().max()

self.assertLess(max_diff, 5e-3, "functional_tensor crop not working")
Copy link
Member

Choose a reason for hiding this comment

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

Can't we make the difference 0? Is this because we need to perform casting between types, which gives some accuracy differences?
In that case, can't you directly make img_tensor be a uint8 tensor with values from 0-255?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

@surgan12
Copy link
Contributor

@fmassa, yes makes sense.

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!

@fmassa fmassa merged commit d194082 into pytorch:master Oct 18, 2019
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.

4 participants