From bdd9aec368261b24627a2349c636e559a2563734 Mon Sep 17 00:00:00 2001 From: mindspore-ci-bot Date: Wed, 27 May 2020 15:16:56 +0800 Subject: [PATCH] !1463 Updated UA, RandSharp and RandColor parameter check, Updated UA code and description. Merge pull request !1463 from alashkari/ua-ops-v2 --- .../dataset/transforms/vision/c_transforms.py | 6 +- .../transforms/vision/py_transforms.py | 6 +- .../transforms/vision/py_transforms_util.py | 40 ++---------- .../dataset/transforms/vision/validators.py | 61 ++++++++++++++++++- 4 files changed, 72 insertions(+), 41 deletions(-) diff --git a/mindspore/dataset/transforms/vision/c_transforms.py b/mindspore/dataset/transforms/vision/c_transforms.py index b46184fa16..5676a8408c 100644 --- a/mindspore/dataset/transforms/vision/c_transforms.py +++ b/mindspore/dataset/transforms/vision/c_transforms.py @@ -45,7 +45,7 @@ import mindspore._c_dataengine as cde from .utils import Inter, Border from .validators import check_prob, check_crop, check_resize_interpolation, check_random_resize_crop, \ check_normalize_c, check_random_crop, check_random_color_adjust, check_random_rotation, \ - check_resize, check_rescale, check_pad, check_cutout, check_uniform_augmentation + check_resize, check_rescale, check_pad, check_cutout, check_uniform_augment_cpp DE_C_INTER_MODE = {Inter.NEAREST: cde.InterpolationMode.DE_INTER_NEAREST_NEIGHBOUR, Inter.LINEAR: cde.InterpolationMode.DE_INTER_LINEAR, @@ -456,7 +456,7 @@ class UniformAugment(cde.UniformAugOp): Args: operations: list of C++ operations (python OPs are not accepted). - num_ops (int): number of OPs to be selected and applied. + num_ops (int, optional): number of OPs to be selected and applied (default=2). Examples: >>> transforms_list = [c_transforms.RandomHorizontalFlip(), @@ -470,7 +470,7 @@ class UniformAugment(cde.UniformAugOp): >>> operations=transforms_all, num_parallel_workers=1) """ - @check_uniform_augmentation + @check_uniform_augment_cpp def __init__(self, operations, num_ops=2): self.operations = operations self.num_ops = num_ops diff --git a/mindspore/dataset/transforms/vision/py_transforms.py b/mindspore/dataset/transforms/vision/py_transforms.py index c247d78da3..f85407c1fe 100644 --- a/mindspore/dataset/transforms/vision/py_transforms.py +++ b/mindspore/dataset/transforms/vision/py_transforms.py @@ -32,7 +32,7 @@ from .validators import check_prob, check_crop, check_resize_interpolation, chec check_normalize_py, check_random_crop, check_random_color_adjust, check_random_rotation, \ check_transforms_list, check_random_apply, check_ten_crop, check_num_channels, check_pad, \ check_random_perspective, check_random_erasing, check_cutout, check_linear_transform, check_random_affine, \ - check_mix_up + check_mix_up, check_positive_degrees, check_uniform_augment_py from .utils import Inter, Border DE_PY_INTER_MODE = {Inter.NEAREST: Image.NEAREST, @@ -1329,6 +1329,7 @@ class RandomColor: >>> py_transforms.ToTensor()]) """ + @check_positive_degrees def __init__(self, degrees=(0.1, 1.9)): self.degrees = degrees @@ -1361,6 +1362,7 @@ class RandomSharpness: """ + @check_positive_degrees def __init__(self, degrees=(0.1, 1.9)): self.degrees = degrees @@ -1458,6 +1460,7 @@ class UniformAugment: Uniformly select and apply a number of transforms sequentially from a list of transforms. Randomly assigns a probability to each transform for each image to decide whether apply it or not. + All the transforms in transform list must have the same input/output data type. Args: transforms (list): List of transformations to be chosen from to apply. @@ -1473,6 +1476,7 @@ class UniformAugment: >>> py_transforms.ToTensor()]) """ + @check_uniform_augment_py def __init__(self, transforms, num_ops=2): self.transforms = transforms self.num_ops = num_ops diff --git a/mindspore/dataset/transforms/vision/py_transforms_util.py b/mindspore/dataset/transforms/vision/py_transforms_util.py index 54fb4c8274..ac77624bf8 100644 --- a/mindspore/dataset/transforms/vision/py_transforms_util.py +++ b/mindspore/dataset/transforms/vision/py_transforms_util.py @@ -1427,17 +1427,6 @@ def random_color(img, degrees): if not is_pil(img): raise TypeError('img should be PIL Image. Got {}'.format(type(img))) - if isinstance(degrees, (list, tuple)): - if len(degrees) != 2: - raise ValueError("Degrees must be a sequence length 2.") - if degrees[0] < 0: - raise ValueError("Degree value must be non-negative.") - if degrees[0] > degrees[1]: - raise ValueError("Degrees should be in (min,max) format. Got (max,min).") - - else: - raise TypeError("Degrees must be a sequence in (min,max) format.") - v = (degrees[1] - degrees[0]) * random.random() + degrees[0] return ImageEnhance.Color(img).enhance(v) @@ -1459,17 +1448,6 @@ def random_sharpness(img, degrees): if not is_pil(img): raise TypeError('img should be PIL Image. Got {}'.format(type(img))) - if isinstance(degrees, (list, tuple)): - if len(degrees) != 2: - raise ValueError("Degrees must be a sequence length 2.") - if degrees[0] < 0: - raise ValueError("Degree value must be non-negative.") - if degrees[0] > degrees[1]: - raise ValueError("Degrees should be in (min,max) format. Got (max,min).") - - else: - raise TypeError("Degrees must be a sequence in (min,max) format.") - v = (degrees[1] - degrees[0]) * random.random() + degrees[0] return ImageEnhance.Sharpness(img).enhance(v) @@ -1537,6 +1515,7 @@ def uniform_augment(img, transforms, num_ops): Uniformly select and apply a number of transforms sequentially from a list of transforms. Randomly assigns a probability to each transform for each image to decide whether apply it or not. + All the transforms in transform list must have the same input/output data type. Args: img: Image to be applied transformation. @@ -1545,23 +1524,14 @@ def uniform_augment(img, transforms, num_ops): Returns: img, Transformed image. - """ - if transforms is None: - raise ValueError("transforms is not provided.") - if not isinstance(transforms, list): - raise ValueError("The transforms needs to be a list.") - - if not isinstance(num_ops, int): - raise ValueError("Number of operations should be a positive integer.") - if num_ops < 1: - raise ValueError("Number of operators should equal or greater than one.") + """ - for _ in range(num_ops): - AugmentOp = random.choice(transforms) + op_idx = np.random.choice(len(transforms), size=num_ops, replace=False) + for idx in op_idx: + AugmentOp = transforms[idx] pr = random.random() if random.random() < pr: img = AugmentOp(img.copy()) - transforms.remove(AugmentOp) return img diff --git a/mindspore/dataset/transforms/vision/validators.py b/mindspore/dataset/transforms/vision/validators.py index 631d478d43..d6fbc4af16 100644 --- a/mindspore/dataset/transforms/vision/validators.py +++ b/mindspore/dataset/transforms/vision/validators.py @@ -816,8 +816,8 @@ def check_rescale(method): return new_method -def check_uniform_augmentation(method): - """Wrapper method to check the parameters of UniformAugmentation.""" +def check_uniform_augment_cpp(method): + """Wrapper method to check the parameters of UniformAugment cpp op.""" @wraps(method) def new_method(self, *args, **kwargs): @@ -850,3 +850,60 @@ def check_uniform_augmentation(method): return method(self, **kwargs) return new_method + + +def check_uniform_augment_py(method): + """Wrapper method to check the parameters of python UniformAugment op.""" + + @wraps(method) + def new_method(self, *args, **kwargs): + transforms, num_ops = (list(args) + 2 * [None])[:2] + if "transforms" in kwargs: + transforms = kwargs.get("transforms") + if transforms is None: + raise ValueError("transforms is not provided.") + if not transforms: + raise ValueError("transforms list is empty.") + check_list(transforms) + for transform in transforms: + if isinstance(transform, TensorOp): + raise ValueError("transform list only accepts Python operations.") + kwargs["transforms"] = transforms + + if "num_ops" in kwargs: + num_ops = kwargs.get("num_ops") + if num_ops is not None: + check_type(num_ops, int) + check_positive(num_ops) + if num_ops > len(transforms): + raise ValueError("num_ops cannot be greater than the length of transforms list.") + kwargs["num_ops"] = num_ops + + return method(self, **kwargs) + + return new_method + + +def check_positive_degrees(method): + """A wrapper method to check degrees parameter in RandSharpness and RandColor""" + + @wraps(method) + def new_method(self, *args, **kwargs): + degrees = (list(args) + [None])[0] + if "degrees" in kwargs: + degrees = kwargs.get("degrees") + + if degrees is not None: + if isinstance(degrees, (list, tuple)): + if len(degrees) != 2: + raise ValueError("Degrees must be a sequence with length 2.") + if degrees[0] < 0: + raise ValueError("Degrees range must be non-negative.") + if degrees[0] > degrees[1]: + raise ValueError("Degrees should be in (min,max) format. Got (max,min).") + else: + raise TypeError("Degrees must be a sequence in (min,max) format.") + + return method(self, **kwargs) + + return new_method