-
Notifications
You must be signed in to change notification settings - Fork 7k
Added symmetric padding mode for Tensors #2373
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
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2373 +/- ##
==========================================
- Coverage 68.59% 68.49% -0.11%
==========================================
Files 93 94 +1
Lines 7713 7770 +57
Branches 1196 1214 +18
==========================================
+ Hits 5291 5322 +31
- Misses 2077 2098 +21
- Partials 345 350 +5
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.
Implementation looks great, thanks a lot @vfdev-5 !
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 also add tests for negative padding?
x_indices = [i for i in range(in_sizes[-1])] # [0, 1, 2, 3, ...] | ||
left_indices = [i for i in range(padding[0] - 1, -1, -1)] # e.g. [3, 2, 1, 0] | ||
right_indices = [-(i + 1) for i in range(padding[1])] # e.g. [-1, -2, -3] |
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.
Actually, this doesn't work as expected if padding
is negative (in which case we crop the image).
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.
Added check and raise an error if padding is negative for symmetric mode
Benchmarking current implementation vs Benchmark 1) Hardware: NVidia 1080Ti %%timeit -r 7 -n 500
torch.nn.functional.pad(img, padding, mode="reflect").sum().item()
> 102 µs ± 3.66 µs per loop (mean ± std. dev. of 7 runs, 500 loops each) %%timeit -r 7 -n 500
pad_symmetric(x, padding).sum().item()
344 µs ± 3.85 µs per loop (mean ± std. dev. of 7 runs, 500 loops each) almost half time is spent in index creation. Benchmark 2) CPU %%timeit -r 7 -n 500
pad_symmetric(x_cpu, padding)
> 1.32 ms ± 106 µs per loop (mean ± std. dev. of 7 runs, 500 loops each) %%timeit -r 7 -n 500
pad(img_pil, padding, padding_mode="symmetric")
726 µs ± 30.2 µs per loop (mean ± std. dev. of 7 runs, 500 loops each) from typing import List, Tuple
import torch
from torch import Tensor
def pad_symmetric(img: Tensor, padding: List[int]) -> Tensor:
# padding is left, right, top, bottom
in_sizes = img.size()
x_indices = [i for i in range(in_sizes[-1])] # [0, 1, 2, 3, ...]
left_indices = [i for i in range(padding[0] - 1, -1, -1)] # e.g. [3, 2, 1, 0]
right_indices = [-(i + 1) for i in range(padding[1])] # e.g. [-1, -2, -3]
x_indices = torch.tensor(left_indices + x_indices + right_indices)
y_indices = [i for i in range(in_sizes[-2])]
top_indices = [i for i in range(padding[2] - 1, -1, -1)]
bottom_indices = [-(i + 1) for i in range(padding[3])]
y_indices = torch.tensor(top_indices + y_indices + bottom_indices)
ndim = img.ndim
if ndim == 3:
return img[:, y_indices[:, None], x_indices[None, :]]
elif ndim == 4:
return img[:, :, y_indices[:, None], x_indices[None, :]]
else:
raise RuntimeError("Symmetric padding of N-D tensors are not supported yet")
device = "cuda"
x = torch.rand(3, 512, 512).to(device)
img = x.unsqueeze(0) As discussed privately with @fmassa, an optimization is possible (copying the idea from numpy/pytorch): out = torch.empty(out_shape)
out[..., i0:i1, j0:j2] = input
out[..., border_y, border_x] = input[..., y, x] This optimization may be done later... |
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!
* [WIP] Added symmetric padding mode * Added check and raise error if padding is negative for symmetric padding mode * Added test check for raising error if negative pad
Fixes #2350
Description:
functional_tensor
This PR is related to #2371 which updates docs and adds more tests with padding mode for class transforms. It is possible to fetch the tests code from that PR and update docs here to the latest state of the API.
Important: Current implementation uses advanced indexing to perform padding. Due to jit limitations (pytorch/pytorch#34837), we can only support 3D and 4D (maybe we should add 2D) tensors.