# LICENSE HEADER MANAGED BY add-license-header # # Copyright 2018 Kornia Team # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import inspect from typing import List import pytest import torch from kornia.augmentation.auto.autoaugment import AutoAugment from kornia.augmentation.auto.operations import OperationBase, ops from kornia.augmentation.auto.rand_augment.rand_augment import RandAugment from kornia.augmentation.auto.rand_augment.rand_augment import default_policy as randaug_config from kornia.augmentation.auto.trivial_augment import TrivialAugment from kornia.augmentation.container import AugmentationSequential from kornia.geometry.bbox import bbox_to_mask from testing.augmentation.utils import reproducibility_test from testing.base import BaseTester def _find_all_ops() -> List[OperationBase]: _ops = [op for _, op in inspect.getmembers(ops, inspect.isclass)] return [op() for op in _ops if issubclass(op, OperationBase) and op != OperationBase] def _test_sequential(augment_method, device, dtype): inp = torch.rand(1, 3, 1000, 500, device=device, dtype=dtype) bbox = torch.tensor([[[355, 10], [660, 10], [660, 250], [355, 250]]], device=device, dtype=dtype) keypoints = torch.tensor([[[465, 115], [545, 116]]], device=device, dtype=dtype) mask = bbox_to_mask( torch.tensor([[[155, 0], [900, 0], [900, 400], [155, 400]]], device=device, dtype=dtype), 1000, 500 )[:, None] aug = AugmentationSequential(augment_method, data_keys=["input", "mask", "bbox", "keypoints"]) out = aug(inp, mask, bbox, keypoints) assert out[0].shape == inp.shape assert out[1].shape == mask.shape assert out[2].shape == bbox.shape assert out[3].shape == keypoints.shape assert set(out[1].unique().tolist()).issubset(set(mask.unique().tolist())) out_inv = aug.inverse(*out) assert out_inv[0].shape == inp.shape assert out_inv[1].shape == mask.shape assert out_inv[2].shape == bbox.shape assert out_inv[3].shape == keypoints.shape assert set(out_inv[1].unique().tolist()).issubset(set(mask.unique().tolist())) reproducibility_test((inp, mask, bbox, keypoints), aug) class TestAutoAugment(BaseTester): @pytest.mark.parametrize("policy", ["imagenet", "cifar10", "svhn", [[("shear_x", 0.9, 4), ("invert", 0.2, None)]]]) def test_smoke(self, policy, device, dtype): aug = AutoAugment(policy) in_tensor = torch.rand(10, 3, 50, 50, device=device, dtype=dtype, requires_grad=True) aug(in_tensor) aug.is_intensity_only() def test_transform_mat(self, device, dtype): aug = AutoAugment([[("shear_x", 0.9, 4), ("invert", 0.2, None)]], transformation_matrix_mode="silence") in_tensor = torch.rand(10, 3, 50, 50, device=device, dtype=dtype, requires_grad=True) aug(in_tensor) trans = aug.get_transformation_matrix(in_tensor, params=aug._params) self.assert_close(trans, aug.transform_matrix) def test_reproduce(self, device, dtype): aug = AutoAugment() in_tensor = torch.rand(10, 3, 50, 50, device=device, dtype=dtype, requires_grad=True) out_tensor = aug(in_tensor) out_tensor_2 = aug(in_tensor, params=aug._params) self.assert_close(out_tensor, out_tensor_2) def test_sequential(augment_method, device, dtype): _test_sequential(AutoAugment(), device=device, dtype=dtype) class TestRandAugment(BaseTester): @pytest.mark.parametrize("policy", [None, [[("translate_y", -0.5, 0.5)]]]) def test_smoke(self, policy): if policy is None: n = len(randaug_config) else: n = 1 aug = RandAugment(n=n, m=15, policy=policy) in_tensor = torch.rand(10, 3, 50, 50, requires_grad=True) aug(in_tensor) def test_transform_mat(self, device, dtype): aug = RandAugment(n=3, m=15) in_tensor = torch.rand(10, 3, 50, 50, device=device, dtype=dtype, requires_grad=True) aug(in_tensor) trans = aug.get_transformation_matrix(in_tensor, params=aug._params) self.assert_close(trans, aug.transform_matrix) def test_reproduce(self, device, dtype): aug = RandAugment(n=3, m=15) in_tensor = torch.rand(10, 3, 50, 50, device=device, dtype=dtype, requires_grad=True) out_tensor = aug(in_tensor) out_tensor_2 = aug(in_tensor, params=aug._params) self.assert_close(out_tensor, out_tensor_2) def test_sequential(augment_method, device, dtype): _test_sequential(RandAugment(n=3, m=15), device=device, dtype=dtype) class TestTrivialAugment(BaseTester): @pytest.mark.parametrize("policy", [None, [[("translate_y", -0.5, 0.5)]]]) def test_smoke(self, policy): aug = TrivialAugment(policy=policy) in_tensor = torch.rand(10, 3, 50, 50, requires_grad=True) aug(in_tensor) def test_transform_mat(self, device, dtype): aug = TrivialAugment() in_tensor = torch.rand(10, 3, 50, 50, device=device, dtype=dtype, requires_grad=True) aug(in_tensor) aug(in_tensor) trans = aug.get_transformation_matrix(in_tensor, params=aug._params) self.assert_close(trans, aug.transform_matrix) def test_reproduce(self, device, dtype): aug = TrivialAugment() in_tensor = torch.rand(10, 3, 50, 50, device=device, dtype=dtype, requires_grad=True) out_tensor = aug(in_tensor) out_tensor_2 = aug(in_tensor, params=aug._params) self.assert_close(out_tensor, out_tensor_2) def test_sequential(augment_method, device, dtype): _test_sequential(TrivialAugment(), device=device, dtype=dtype)