-
Notifications
You must be signed in to change notification settings - Fork 7.2k
Make crop scriptable #1379
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
Make crop scriptable #1379
Conversation
Fix nightly builds (pytorch#1374)
Relevant pytorch#1375
Codecov Report
@@ 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
Continue to review full report at Codecov.
|
fmassa
left a comment
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 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
|
Hi @fmassa ! Made the changes you requested. |
test/test_functional_tensor.py
Outdated
|
|
||
| max_diff = (img_cropped_GT - img_cropped).abs().max() | ||
|
|
||
| assert max_diff < 5e-3, "Functional crop not working" |
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.
|
|
||
| if not F._is_tensor_image(img_tensor): | ||
| raise TypeError('tensor is not a torch image.') | ||
| raise TypeError('Input image is not a tensor.') |
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.
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 ?
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 link you provided isn't working but I get your concern. It's a valid point and I will revert the change.
|
@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. |
|
@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 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 |
fmassa
left a comment
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 almost good, thanks!
I have only a couple of comments, and then this is good to merge, thanks!
test/test_functional_tensor.py
Outdated
| self.assertTrue(torch.equal(img_tensor, hflipped_img_again)) | ||
|
|
||
| def test_crop(self): | ||
| img_tensor = torch.FloatTensor(3, 16, 16).uniform_(0, 1) |
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 use torch.rand(3, 16, 16) instead? torch.FloatTensor is a legacy API and is deprecated
test/test_functional_tensor.py
Outdated
|
|
||
| max_diff = (img_cropped_GT - img_cropped).abs().max() | ||
|
|
||
| self.assertLess(max_diff, 5e-3, "functional_tensor crop not working") |
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 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?
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.
Done!
|
@fmassa, yes makes sense. |
fmassa
left a comment
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!
This PR makes crop transform scriptable as discussed in #1375.