Skip to content

Commit e860498

Browse files
jdsgomesfacebook-github-bot
authored andcommitted
[fbsync] Fixed reparametrization for shear X/Y in autoaugment ops (#5384)
Summary: * Added ref tests for shear X/Y * Added PIL tests and fixed tan(level) difference * Updated tests * Fixed reparam for shear X/Y in autoaugment * Fixed arc_level -> level as atan is applied internally * Fixed links Reviewed By: NicolasHug Differential Revision: D34140249 fbshipit-source-id: e7d984977599bbd71e57f403c022620315b052a1
1 parent 67b8888 commit e860498

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

test/common_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def _assert_approx_equal_tensor_to_pil(
187187
tensor = tensor.to(torch.float)
188188
pil_tensor = pil_tensor.to(torch.float)
189189
err = getattr(torch, agg_method)(torch.abs(tensor - pil_tensor)).item()
190-
assert err < tol
190+
assert err < tol, f"{err} vs {tol}"
191191

192192

193193
def _test_fn_on_batch(batch_tensors, fn, scripted_fn_atol=1e-8, **fn_kwargs):

test/test_transforms_tensor.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
cpu_and_gpu,
1515
assert_equal,
1616
)
17+
from PIL import Image
1718
from torchvision import transforms as T
1819
from torchvision.transforms import InterpolationMode
1920
from torchvision.transforms import functional as F
21+
from torchvision.transforms.autoaugment import _apply_op
2022

2123
NEAREST, BILINEAR, BICUBIC = InterpolationMode.NEAREST, InterpolationMode.BILINEAR, InterpolationMode.BICUBIC
2224

@@ -725,6 +727,48 @@ def test_autoaugment_save(augmentation, tmpdir):
725727
s_transform.save(os.path.join(tmpdir, "t_autoaugment.pt"))
726728

727729

730+
@pytest.mark.parametrize("interpolation", [F.InterpolationMode.NEAREST, F.InterpolationMode.BILINEAR])
731+
@pytest.mark.parametrize("mode", ["X", "Y"])
732+
def test_autoaugment__op_apply_shear(interpolation, mode):
733+
# We check that torchvision's implementation of shear is equivalent
734+
# to official CIFAR10 autoaugment implementation:
735+
# https://github.com/tensorflow/models/blob/885fda091c46c59d6c7bb5c7e760935eacc229da/research/autoaugment/augmentation_transforms.py#L273-L290
736+
image_size = 32
737+
738+
def shear(pil_img, level, mode, resample):
739+
if mode == "X":
740+
matrix = (1, level, 0, 0, 1, 0)
741+
elif mode == "Y":
742+
matrix = (1, 0, 0, level, 1, 0)
743+
return pil_img.transform((image_size, image_size), Image.AFFINE, matrix, resample=resample)
744+
745+
t_img, pil_img = _create_data(image_size, image_size)
746+
747+
resample_pil = {
748+
F.InterpolationMode.NEAREST: Image.NEAREST,
749+
F.InterpolationMode.BILINEAR: Image.BILINEAR,
750+
}[interpolation]
751+
752+
level = 0.3
753+
expected_out = shear(pil_img, level, mode=mode, resample=resample_pil)
754+
755+
# Check pil output vs expected pil
756+
out = _apply_op(pil_img, op_name=f"Shear{mode}", magnitude=level, interpolation=interpolation, fill=0)
757+
assert out == expected_out
758+
759+
if interpolation == F.InterpolationMode.BILINEAR:
760+
# We skip bilinear mode for tensors as
761+
# affine transformation results are not exactly the same
762+
# between tensors and pil images
763+
# MAE as around 1.40
764+
# Max Abs error can be 163 or 170
765+
return
766+
767+
# Check tensor output vs expected pil
768+
out = _apply_op(t_img, op_name=f"Shear{mode}", magnitude=level, interpolation=interpolation, fill=0)
769+
_assert_approx_equal_tensor_to_pil(out, expected_out)
770+
771+
728772
@pytest.mark.parametrize("device", cpu_and_gpu())
729773
@pytest.mark.parametrize(
730774
"config",

torchvision/transforms/autoaugment.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,31 @@ def _apply_op(
1414
img: Tensor, op_name: str, magnitude: float, interpolation: InterpolationMode, fill: Optional[List[float]]
1515
):
1616
if op_name == "ShearX":
17+
# magnitude should be arctan(magnitude)
18+
# official autoaug: (1, level, 0, 0, 1, 0)
19+
# https://github.com/tensorflow/models/blob/dd02069717128186b88afa8d857ce57d17957f03/research/autoaugment/augmentation_transforms.py#L290
20+
# compared to
21+
# torchvision: (1, tan(level), 0, 0, 1, 0)
22+
# https://github.com/pytorch/vision/blob/0c2373d0bba3499e95776e7936e207d8a1676e65/torchvision/transforms/functional.py#L976
1723
img = F.affine(
1824
img,
1925
angle=0.0,
2026
translate=[0, 0],
2127
scale=1.0,
22-
shear=[math.degrees(magnitude), 0.0],
28+
shear=[math.degrees(math.atan(magnitude)), 0.0],
2329
interpolation=interpolation,
2430
fill=fill,
2531
center=[0, 0],
2632
)
2733
elif op_name == "ShearY":
34+
# magnitude should be arctan(magnitude)
35+
# See above
2836
img = F.affine(
2937
img,
3038
angle=0.0,
3139
translate=[0, 0],
3240
scale=1.0,
33-
shear=[0.0, math.degrees(magnitude)],
41+
shear=[0.0, math.degrees(math.atan(magnitude))],
3442
interpolation=interpolation,
3543
fill=fill,
3644
center=[0, 0],

0 commit comments

Comments
 (0)