You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

py_transforms.py 9.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. # Copyright 2019 Huawei Technologies Co., Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. # ==============================================================================
  15. """
  16. The module transforms.py_transform is implemented based on Python. It provides common
  17. operations including OneHotOp.
  18. """
  19. from .validators import check_one_hot_op, check_compose_list, check_random_apply, check_transforms_list, \
  20. check_compose_call
  21. from . import py_transforms_util as util
  22. class OneHotOp:
  23. """
  24. Apply one hot encoding transformation to the input label, make label be more smoothing and continuous.
  25. Args:
  26. num_classes (int): Number of classes of objects in dataset. Value must be larger than 0.
  27. smoothing_rate (float, optional): Adjustable hyperparameter for label smoothing level.
  28. (Default=0.0 means no smoothing is applied.)
  29. Examples:
  30. >>> import mindspore.dataset.transforms as py_transforms
  31. >>>
  32. >>> transforms_list = [py_transforms.OneHotOp(num_classes=10, smoothing_rate=0.1)]
  33. >>> transform = py_transforms.Compose(transforms_list)
  34. >>> data1 = data1.map(input_columns=["label"], operations=transform())
  35. """
  36. @check_one_hot_op
  37. def __init__(self, num_classes, smoothing_rate=0.0):
  38. self.num_classes = num_classes
  39. self.smoothing_rate = smoothing_rate
  40. def __call__(self, label):
  41. """
  42. Call method.
  43. Args:
  44. label (numpy.ndarray): label to be applied label smoothing.
  45. Returns:
  46. label (numpy.ndarray), label after being Smoothed.
  47. """
  48. return util.one_hot_encoding(label, self.num_classes, self.smoothing_rate)
  49. class Compose:
  50. """
  51. Compose a list of transforms.
  52. .. Note::
  53. Compose takes a list of transformations either provided in py_transforms or from user-defined implementation;
  54. each can be an initialized transformation class or a lambda function, as long as the output from the last
  55. transformation is a single tensor of type numpy.ndarray. See below for an example of how to use Compose
  56. with py_transforms classes and check out FiveCrop or TenCrop for the use of them in conjunction with lambda
  57. functions.
  58. Args:
  59. transforms (list): List of transformations to be applied.
  60. Examples:
  61. >>> import mindspore.dataset as ds
  62. >>> import mindspore.dataset.vision.py_transforms as py_vision
  63. >>> import mindspore.dataset.transforms.py_transforms as py_transforms
  64. >>>
  65. >>> dataset_dir = "path/to/imagefolder_directory"
  66. >>> # create a dataset that reads all files in dataset_dir with 8 threads
  67. >>> data1 = ds.ImageFolderDataset(dataset_dir, num_parallel_workers=8)
  68. >>> # create a list of transformations to be applied to the image data
  69. >>> transform = py_transforms.Compose([py_vision.Decode(),
  70. >>> py_vision.RandomHorizontalFlip(0.5),
  71. >>> py_vision.ToTensor(),
  72. >>> py_vision.Normalize((0.491, 0.482, 0.447), (0.247, 0.243, 0.262)),
  73. >>> py_vision.RandomErasing()])
  74. >>> # apply the transform to the dataset through dataset.map()
  75. >>> data1 = data1.map(operations=transform, input_columns="image")
  76. >>>
  77. >>> # Compose is also be invoked implicitly, by just passing in a list of ops
  78. >>> # the above example then becomes:
  79. >>> transform_list = [py_vision.Decode(),
  80. >>> py_vision.RandomHorizontalFlip(0.5),
  81. >>> py_vision.ToTensor(),
  82. >>> py_vision.Normalize((0.491, 0.482, 0.447), (0.247, 0.243, 0.262)),
  83. >>> py_vision.RandomErasing()]
  84. >>>
  85. >>> # apply the transform to the dataset through dataset.map()
  86. >>> data2 = data2.map(operations=transform_list, input_columns="image")
  87. >>>
  88. >>> # Certain C++ and Python ops can be combined, but not all of them
  89. >>> # An example of combined operations
  90. >>> import mindspore.dataset as ds
  91. >>> import mindspore.dataset.transforms.c_transforms as c_transforms
  92. >>> import mindspore.dataset.vision.c_transforms as c_vision
  93. >>>
  94. >>> data3 = ds.NumpySlicesDataset(arr, column_names=["cols"], shuffle=False)
  95. >>> transformed_list = [py_transforms.OneHotOp(2), c_transforms.Mask(c_transforms.Relational.EQ, 1)]
  96. >>> data3 = data3.map(operations=transformed_list, input_columns=["cols"])
  97. >>>
  98. >>> # Here is an example of mixing vision ops
  99. >>> data_dir = "/path/to/imagefolder_directory"
  100. >>> data4 = ds.ImageFolderDataset(dataset_dir=data_dir, shuffle=False)
  101. >>> input_columns = ["column_names"]
  102. >>> op_list=[c_vision.Decode(),
  103. >>> c_vision.Resize((224, 244)),
  104. >>> py_vision.ToPIL(),
  105. >>> np.array, # need to convert PIL image to a NumPy array to pass it to C++ operation
  106. >>> c_vision.Resize((24, 24))]
  107. >>> data4 = data4.map(operations=op_list, input_columns=input_columns)
  108. """
  109. @check_compose_list
  110. def __init__(self, transforms):
  111. self.transforms = transforms
  112. @check_compose_call
  113. def __call__(self, *args):
  114. """
  115. Call method.
  116. Returns:
  117. lambda function, Lambda function that takes in an args to apply transformations on.
  118. """
  119. return util.compose(self.transforms, *args)
  120. class RandomApply:
  121. """
  122. Randomly perform a series of transforms with a given probability.
  123. Args:
  124. transforms (list): List of transformations to apply.
  125. prob (float, optional): The probability to apply the transformation list (default=0.5).
  126. Examples:
  127. >>> import mindspore.dataset.vision.py_transforms as py_vision
  128. >>> from mindspore.dataset.transforms.py_transforms import Compose
  129. >>>
  130. >>> Compose([py_vision.Decode(),
  131. >>> py_vision.RandomApply(transforms_list, prob=0.6),
  132. >>> py_vision.ToTensor()])
  133. """
  134. @check_random_apply
  135. def __init__(self, transforms, prob=0.5):
  136. self.prob = prob
  137. self.transforms = transforms
  138. def __call__(self, img):
  139. """
  140. Call method.
  141. Args:
  142. img (PIL image): Image to be randomly applied a list transformations.
  143. Returns:
  144. img (PIL image), Transformed image.
  145. """
  146. return util.random_apply(img, self.transforms, self.prob)
  147. class RandomChoice:
  148. """
  149. Randomly select one transform from a series of transforms and applies that on the image.
  150. Args:
  151. transforms (list): List of transformations to be chosen from to apply.
  152. Examples:
  153. >>> import mindspore.dataset.vision.py_transforms as py_vision
  154. >>> from mindspore.dataset.transforms.py_transforms import Compose, RandomChoice
  155. >>>
  156. >>> Compose([py_vision.Decode(),
  157. >>> RandomChoice(transforms_list),
  158. >>> py_vision.ToTensor()])
  159. """
  160. @check_transforms_list
  161. def __init__(self, transforms):
  162. self.transforms = transforms
  163. def __call__(self, img):
  164. """
  165. Call method.
  166. Args:
  167. img (PIL image): Image to be applied transformation.
  168. Returns:
  169. img (PIL image), Transformed image.
  170. """
  171. return util.random_choice(img, self.transforms)
  172. class RandomOrder:
  173. """
  174. Perform a series of transforms to the input PIL image in a random order.
  175. Args:
  176. transforms (list): List of the transformations to apply.
  177. Examples:
  178. >>> import mindspore.dataset.vision.py_transforms as py_vision
  179. >>> from mindspore.dataset.transforms.py_transforms import Compose
  180. >>>
  181. >>> Compose([py_vision.Decode(),
  182. >>> py_vision.RandomOrder(transforms_list),
  183. >>> py_vision.ToTensor()])
  184. """
  185. @check_transforms_list
  186. def __init__(self, transforms):
  187. self.transforms = transforms
  188. def __call__(self, img):
  189. """
  190. Call method.
  191. Args:
  192. img (PIL image): Image to apply transformations in a random order.
  193. Returns:
  194. img (PIL image), Transformed image.
  195. """
  196. return util.random_order(img, self.transforms)