[MD] Transform Unification Feature - Phase 2C - legacy deprecated Python UT tests

This commit is contained in:
Cathy Wong 2022-05-02 14:50:47 -04:00
parent 351ce03fb2
commit a275b8b267
12 changed files with 2600 additions and 0 deletions

View File

@ -0,0 +1,15 @@
# Copyright 2022 Huawei Technologies Co., Ltd
#
# 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.
# ============================================================================
"""Deprecated dataset tests for c_transforms.py and py_transforms.py"""

View File

@ -0,0 +1,29 @@
# Copyright 2022 Huawei Technologies Co., Ltd
#
# 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.
# ============================================================================
"""
@File : conftest.py
@Desc : common fixtures for pytest dataset_deprecated
"""
import pytest
from mindspore.dataset.engine.iterators import _cleanup, _unset_iterator_cleanup
@pytest.fixture(scope="function", autouse=True)
def close_iterators():
yield
# Note: code after `yield` is teardown code
_cleanup()
_unset_iterator_cleanup()

View File

@ -0,0 +1,365 @@
# Copyright 2020-2022 Huawei Technologies Co., Ltd
#
# 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 numpy as np
import pytest
import mindspore.common.dtype as mstype
import mindspore.dataset as ds
import mindspore.dataset.transforms.c_transforms as c_transforms
import mindspore.dataset.transforms.py_transforms as py_transforms
import mindspore.dataset.vision.c_transforms as c_vision
import mindspore.dataset.vision.py_transforms as py_vision
from ..dataset.util import visualize_list, save_and_check_md5, config_get_set_seed, config_get_set_num_parallel_workers
GENERATE_GOLDEN = False
def test_compose():
"""
Feature: Compose Op
Description: Test C++ and Python Compose Op
Expectation: Invalid input is detected
"""
original_seed = config_get_set_seed(0)
def test_config(arr, op_list):
try:
data = ds.NumpySlicesDataset(arr, column_names="col", shuffle=False)
data = data.map(input_columns=["col"], operations=op_list)
res = []
for i in data.create_dict_iterator(num_epochs=1, output_numpy=True):
res.append(i["col"].tolist())
return res
except (TypeError, ValueError) as e:
return str(e)
# Test simple compose with only 1 op, this would generate a warning
assert test_config([[1, 0], [3, 4]], c_transforms.Compose([c_transforms.Fill(2)])) == [[2, 2], [2, 2]]
# Test 1 column -> 2 columns -> 1 -> 2 -> 1
assert test_config([[1, 0]],
c_transforms.Compose(
[c_transforms.Duplicate(), c_transforms.Concatenate(), c_transforms.Duplicate(),
c_transforms.Concatenate()])) \
== [[1, 0] * 4]
# Test one Python transform followed by a C++ transform. Type after OneHot is a float (mixed use-case)
assert test_config([1, 0],
c_transforms.Compose([py_transforms.OneHotOp(2), c_transforms.TypeCast(mstype.int32)])) \
== [[0, 1], [1, 0]]
# Test exceptions.
with pytest.raises(TypeError) as error_info:
c_transforms.Compose([1, c_transforms.TypeCast(mstype.int32)])
assert "op_list[0] is neither a c_transform op (TensorOperation) nor a callable pyfunc." in str(error_info.value)
# Test empty op list
with pytest.raises(ValueError) as error_info:
test_config([1, 0], c_transforms.Compose([]))
assert "op_list can not be empty." in str(error_info.value)
# Test Python compose op
assert test_config([1, 0], py_transforms.Compose([py_transforms.OneHotOp(2)])) == [[0, 1], [1, 0]]
assert test_config([1, 0], py_transforms.Compose([py_transforms.OneHotOp(2), (lambda x: x + x)])) == [[0, 2],
[2, 0]]
# Test nested Python compose op
assert test_config([1, 0],
py_transforms.Compose([py_transforms.Compose([py_transforms.OneHotOp(2)]), (lambda x: x + x)])) \
== [[0, 2], [2, 0]]
# Test passing a list of Python ops without Compose wrapper
assert test_config([1, 0],
[py_transforms.Compose([py_transforms.OneHotOp(2)]), (lambda x: x + x)]) \
== [[0, 2], [2, 0]]
assert test_config([1, 0], [py_transforms.OneHotOp(2), (lambda x: x + x)]) == [[0, 2], [2, 0]]
# Test a non callable function
with pytest.raises(ValueError) as error_info:
py_transforms.Compose([1])
assert "transforms[0] is not callable." in str(error_info.value)
# Test empty Python op list
with pytest.raises(ValueError) as error_info:
test_config([1, 0], py_transforms.Compose([]))
assert "transforms list is empty." in str(error_info.value)
# Pass in extra brackets
with pytest.raises(TypeError) as error_info:
py_transforms.Compose([(lambda x: x + x)])()
assert "Compose was called without an image. Fix invocation (avoid it being invoked as Compose([...])())." in str(
error_info.value)
# Restore configuration
ds.config.set_seed(original_seed)
def test_lambdas():
"""
Feature: Compose Op
Description: Test Multi Column Python Compose Op
Expectation: Dataset pipeline runs successfully and results are verified
"""
original_seed = config_get_set_seed(0)
def test_config(arr, input_columns, output_columns, op_list):
data = ds.NumpySlicesDataset(arr, column_names=input_columns, shuffle=False)
data = data.map(operations=op_list, input_columns=input_columns, output_columns=output_columns,
column_order=output_columns)
res = []
for i in data.create_dict_iterator(num_epochs=1, output_numpy=True):
for col_name in output_columns:
res.append(i[col_name].tolist())
return res
arr = ([[1]], [[3]])
assert test_config(arr, ["col0", "col1"], ["a"], py_transforms.Compose([(lambda x, y: x)])) == [[1]]
assert test_config(arr, ["col0", "col1"], ["a"], py_transforms.Compose([lambda x, y: x, lambda x: x])) == [[1]]
assert test_config(arr, ["col0", "col1"], ["a", "b"],
py_transforms.Compose([lambda x, y: x, lambda x: (x, x * 2)])) == \
[[1], [2]]
assert test_config(arr, ["col0", "col1"], ["a", "b"],
[lambda x, y: (x, x + y), lambda x, y: (x, y * 2)]) == [[1], [8]]
# Restore configuration
ds.config.set_seed(original_seed)
def test_c_py_compose_transforms_module():
"""
Feature: Compose Op
Description: Test combining Python and C++ transforms
Expectation: Dataset pipeline runs successfully and results are verified
"""
original_seed = config_get_set_seed(0)
def test_config(arr, input_columns, output_cols, op_list):
data = ds.NumpySlicesDataset(arr, column_names=input_columns, shuffle=False)
data = data.map(operations=op_list, input_columns=input_columns, output_columns=output_cols,
column_order=output_cols)
res = []
for i in data.create_dict_iterator(num_epochs=1, output_numpy=True):
for col_name in output_cols:
res.append(i[col_name].tolist())
return res
arr = [1, 0]
assert test_config(arr, ["cols"], ["cols"],
[py_transforms.OneHotOp(2), c_transforms.Mask(c_transforms.Relational.EQ, 1)]) == \
[[False, True],
[True, False]]
assert test_config(arr, ["cols"], ["cols"],
[py_transforms.OneHotOp(2), (lambda x: x + x), c_transforms.Fill(1)]) \
== [[1, 1], [1, 1]]
assert test_config(arr, ["cols"], ["cols"],
[py_transforms.OneHotOp(2), (lambda x: x + x), c_transforms.Fill(1), (lambda x: x + x)]) \
== [[2, 2], [2, 2]]
assert test_config([[1, 3]], ["cols"], ["cols"],
[c_transforms.PadEnd([3], -1), (lambda x: x + x)]) \
== [[2, 6, -2]]
arr = ([[1]], [[3]])
assert test_config(arr, ["col0", "col1"], ["a"], [(lambda x, y: x + y), c_transforms.PadEnd([2], -1)]) == [[4, -1]]
# Restore configuration
ds.config.set_seed(original_seed)
def test_c_py_compose_vision_module(plot=False, run_golden=True):
"""
Feature: Compose Op
Description: Test combining Python and C++ vision transforms
Expectation: Dataset pipeline runs successfully and md5 results are verified
"""
original_seed = config_get_set_seed(10)
original_num_parallel_workers = config_get_set_num_parallel_workers(1)
def test_config(plot, file_name, op_list):
data_dir = "../data/dataset/testImageNetData/train/"
data1 = ds.ImageFolderDataset(dataset_dir=data_dir, shuffle=False)
data1 = data1.map(operations=op_list, input_columns=["image"])
data2 = ds.ImageFolderDataset(dataset_dir=data_dir, shuffle=False)
data2 = data2.map(operations=c_vision.Decode(), input_columns=["image"])
original_images = []
transformed_images = []
for item in data1.create_dict_iterator(num_epochs=1, output_numpy=True):
transformed_images.append(item["image"])
for item in data2.create_dict_iterator(num_epochs=1, output_numpy=True):
original_images.append(item["image"])
if run_golden:
# Compare with expected md5 from images
save_and_check_md5(data1, file_name, generate_golden=GENERATE_GOLDEN)
if plot:
visualize_list(original_images, transformed_images)
test_config(op_list=[c_vision.Decode(),
py_vision.ToPIL(),
py_vision.Resize((224, 224)),
np.array],
plot=plot, file_name="compose_c_py_1.npz")
test_config(op_list=[c_vision.Decode(),
c_vision.Resize((224, 244)),
py_vision.ToPIL(),
np.array,
c_vision.Resize((24, 24))],
plot=plot, file_name="compose_c_py_2.npz")
test_config(op_list=[py_vision.Decode(),
py_vision.Resize((224, 224)),
np.array,
c_vision.RandomColor()],
plot=plot, file_name="compose_c_py_3.npz")
# Restore configuration
ds.config.set_seed(original_seed)
ds.config.set_num_parallel_workers((original_num_parallel_workers))
def test_py_transforms_with_c_vision():
"""
Feature: Compose Op
Description: Test invalid scenarios since as c_transform should not be used in
py_transforms.Random(Apply/Choice/Order)
Expectation: Invalid input is detected
"""
original_seed = config_get_set_seed(0)
def test_config(op_list):
data_dir = "../data/dataset/testImageNetData/train/"
data = ds.ImageFolderDataset(dataset_dir=data_dir, shuffle=False)
data = data.map(operations=op_list)
res = []
for i in data.create_dict_iterator(num_epochs=1, output_numpy=True):
for col_name in output_cols:
res.append(i[col_name].tolist())
return res
with pytest.raises(ValueError) as error_info:
test_config(py_transforms.RandomApply([c_vision.RandomResizedCrop(200)]))
assert "transforms[0] is not a py transforms." in str(error_info.value)
with pytest.raises(ValueError) as error_info:
test_config(py_transforms.RandomChoice([c_vision.RandomResizedCrop(200)]))
assert "transforms[0] is not a py transforms." in str(error_info.value)
with pytest.raises(ValueError) as error_info:
test_config(py_transforms.RandomOrder([np.array, c_vision.RandomResizedCrop(200)]))
assert "transforms[1] is not a py transforms." in str(error_info.value)
with pytest.raises(RuntimeError) as error_info:
test_config([py_transforms.OneHotOp(20, 0.1)])
assert "is smaller than the category number" in str(error_info.value)
# Restore configuration
ds.config.set_seed(original_seed)
def test_py_vision_with_c_transforms():
"""
Feature: Compose Op
Description: Test combining Python vision operations with C++ transforms operations
Expectation: Dataset pipeline runs successfully for valid input and results verified. Invalid input is detected.
"""
original_seed = config_get_set_seed(0)
def test_config(op_list):
data_dir = "../data/dataset/testImageNetData/train/"
data1 = ds.ImageFolderDataset(dataset_dir=data_dir, shuffle=False)
data1 = data1.map(operations=op_list, input_columns=["image"])
transformed_images = []
for item in data1.create_dict_iterator(num_epochs=1, output_numpy=True):
transformed_images.append(item["image"])
return transformed_images
# Test with Mask Op
output_arr = test_config([py_vision.Decode(),
py_vision.CenterCrop((2)), np.array,
c_transforms.Mask(c_transforms.Relational.GE, 100)])
exp_arr = [np.array([[[True, False, False],
[True, False, False]],
[[True, False, False],
[True, False, False]]]),
np.array([[[True, False, False],
[True, False, False]],
[[True, False, False],
[True, False, False]]])]
for exp_a, output in zip(exp_arr, output_arr):
np.testing.assert_array_equal(exp_a, output)
# Test with Fill Op
output_arr = test_config([py_vision.Decode(),
py_vision.CenterCrop((4)), np.array,
c_transforms.Fill(10)])
exp_arr = [np.ones((4, 4, 3)) * 10] * 2
for exp_a, output in zip(exp_arr, output_arr):
np.testing.assert_array_equal(exp_a, output)
# Test with Concatenate Op, which will raise an error since ConcatenateOp only supports rank 1 tensors.
with pytest.raises(RuntimeError) as error_info:
test_config([py_vision.Decode(),
py_vision.CenterCrop((2)), np.array,
c_transforms.Concatenate(0)])
assert "only 1D input supported" in str(error_info.value)
# Restore configuration
ds.config.set_seed(original_seed)
def test_compose_with_custom_function():
"""
Feature: Compose Op
Description: Test Python Compose with custom function
Expectation: Dataset pipeline runs successfully and results are verified
"""
def custom_function(x):
return (x, x * x)
# First dataset
op_list = [
lambda x: x * 3,
custom_function,
# convert two column output to one
lambda *images: np.stack(images)
]
data = ds.NumpySlicesDataset([[1, 2]], column_names=["col0"], shuffle=False)
data = data.map(input_columns=["col0"], operations=op_list)
#
res = []
for i in data.create_dict_iterator(num_epochs=1, output_numpy=True):
res.append(i["col0"].tolist())
assert res == [[[3, 6], [9, 36]]]
if __name__ == "__main__":
test_compose()
test_lambdas()
test_c_py_compose_transforms_module()
test_c_py_compose_vision_module(plot=True)
test_py_transforms_with_c_vision()
test_py_vision_with_c_transforms()
test_compose_with_custom_function()

View File

@ -0,0 +1,226 @@
# Copyright 2019-2022 Huawei Technologies Co., Ltd
#
# 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.
# ==============================================================================
"""
Testing CutOut op in DE
"""
import numpy as np
import mindspore.dataset as ds
import mindspore.dataset.transforms.py_transforms
import mindspore.dataset.vision.c_transforms as c
import mindspore.dataset.vision.py_transforms as f
from mindspore import log as logger
from ..dataset.util import visualize_image, visualize_list, diff_mse, save_and_check_md5, \
config_get_set_seed, config_get_set_num_parallel_workers
DATA_DIR = ["../data/dataset/test_tf_file_3_images/train-0000-of-0001.data"]
SCHEMA_DIR = "../data/dataset/test_tf_file_3_images/datasetSchema.json"
GENERATE_GOLDEN = False
def test_cut_out_op(plot=False):
"""
Feature: CutOut Op
Description: Test CutOut C++ op
Expectation: Dataset pipeline runs successfully and results are verified against RandomErasing Op
"""
logger.info("test_cut_out")
# First dataset
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
transforms_1 = [
f.Decode(),
f.ToTensor(),
f.RandomErasing(value='random')
]
transform_1 = mindspore.dataset.transforms.py_transforms.Compose(transforms_1)
data1 = data1.map(operations=transform_1, input_columns=["image"])
# Second dataset
data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
decode_op = c.Decode()
cut_out_op = c.CutOut(80)
transforms_2 = [
decode_op,
cut_out_op
]
data2 = data2.map(operations=transforms_2, input_columns=["image"])
num_iter = 0
for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True),
data2.create_dict_iterator(num_epochs=1, output_numpy=True)):
num_iter += 1
image_1 = (item1["image"].transpose(1, 2, 0) * 255).astype(np.uint8)
# C image doesn't require transpose
image_2 = item2["image"]
logger.info("shape of image_1: {}".format(image_1.shape))
logger.info("shape of image_2: {}".format(image_2.shape))
logger.info("dtype of image_1: {}".format(image_1.dtype))
logger.info("dtype of image_2: {}".format(image_2.dtype))
mse = diff_mse(image_1, image_2)
if plot:
visualize_image(image_1, image_2, mse)
def test_cut_out_op_multicut(plot=False):
"""
Feature: CutOut Op
Description: Test CutOut o with multiple patches
Expectation: Dataset pipeline runs successfully and results are visually verified
"""
logger.info("test_cut_out")
# First dataset
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
transforms_1 = [
f.Decode(),
f.ToTensor(),
]
transform_1 = mindspore.dataset.transforms.py_transforms.Compose(transforms_1)
data1 = data1.map(operations=transform_1, input_columns=["image"])
# Second dataset
data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
decode_op = c.Decode()
cut_out_op = c.CutOut(80, num_patches=10)
transforms_2 = [
decode_op,
cut_out_op
]
data2 = data2.map(operations=transforms_2, input_columns=["image"])
num_iter = 0
image_list_1, image_list_2 = [], []
for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True),
data2.create_dict_iterator(num_epochs=1, output_numpy=True)):
num_iter += 1
image_1 = (item1["image"].transpose(1, 2, 0) * 255).astype(np.uint8)
# C image doesn't require transpose
image_2 = item2["image"]
image_list_1.append(image_1)
image_list_2.append(image_2)
logger.info("shape of image_1: {}".format(image_1.shape))
logger.info("shape of image_2: {}".format(image_2.shape))
logger.info("dtype of image_1: {}".format(image_1.dtype))
logger.info("dtype of image_2: {}".format(image_2.dtype))
if plot:
visualize_list(image_list_1, image_list_2)
def test_cut_out_md5():
"""
Feature: CutOut Op
Description: Test CutOut C++ op and Cutout Py op with md5 check
Expectation: Dataset pipeline runs successfully and md5 results are verified
"""
logger.info("test_cut_out_md5")
original_seed = config_get_set_seed(2)
original_num_parallel_workers = config_get_set_num_parallel_workers(1)
# First dataset
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
decode_op = c.Decode()
cut_out_op = c.CutOut(100)
data1 = data1.map(operations=decode_op, input_columns=["image"])
data1 = data1.map(operations=cut_out_op, input_columns=["image"])
data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
transforms = [
f.Decode(),
f.ToTensor(),
f.Cutout(100)
]
transform = mindspore.dataset.transforms.py_transforms.Compose(transforms)
data2 = data2.map(operations=transform, input_columns=["image"])
# Compare with expected md5 from images
filename1 = "cut_out_01_c_result.npz"
save_and_check_md5(data1, filename1, generate_golden=GENERATE_GOLDEN)
filename2 = "cut_out_01_py_result.npz"
save_and_check_md5(data2, filename2, generate_golden=GENERATE_GOLDEN)
# Restore config
ds.config.set_seed(original_seed)
ds.config.set_num_parallel_workers(original_num_parallel_workers)
def test_cut_out_comp(plot=False):
"""
Feature: CutOut Op
Description: Test Test CutOut C++ op and Cutout Py op
Expectation: Dataset pipeline runs successfully and results are visually verified
"""
logger.info("test_cut_out_comp")
# First dataset
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
transforms_1 = [
f.Decode(),
f.ToTensor(),
f.Cutout(200)
]
transform_1 = mindspore.dataset.transforms.py_transforms.Compose(transforms_1)
data1 = data1.map(operations=transform_1, input_columns=["image"])
# Second dataset
data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
transforms_2 = [
c.Decode(),
c.CutOut(200)
]
data2 = data2.map(operations=transforms_2, input_columns=["image"])
num_iter = 0
image_list_1, image_list_2 = [], []
for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True),
data2.create_dict_iterator(num_epochs=1, output_numpy=True)):
num_iter += 1
image_1 = (item1["image"].transpose(1, 2, 0) * 255).astype(np.uint8)
# C image doesn't require transpose
image_2 = item2["image"]
logger.info("shape of image_1: {}".format(image_1.shape))
logger.info("shape of image_2: {}".format(image_2.shape))
logger.info("dtype of image_1: {}".format(image_1.dtype))
logger.info("dtype of image_2: {}".format(image_2.dtype))
image_list_1.append(image_1)
image_list_2.append(image_2)
if plot:
visualize_list(image_list_1, image_list_2, visualize_mode=2)
if __name__ == "__main__":
test_cut_out_op(plot=True)
test_cut_out_op_multicut(plot=True)
test_cut_out_md5()
test_cut_out_comp(plot=True)

View File

@ -0,0 +1,338 @@
# Copyright 2020-2022 Huawei Technologies Co., Ltd
#
# 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 cv2
import numpy as np
import pytest
from PIL import Image
import mindspore.dataset.vision.c_transforms as C
import mindspore.dataset.vision.py_transforms as PY
from mindspore import log as logger
def test_eager_decode_c():
"""
Feature: Decode op
Description: Test eager support for Decode C++ op
Expectation: Output image size from op is correct
"""
img = np.fromfile("../data/dataset/apple.jpg", dtype=np.uint8)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
img = C.Decode()(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
assert img.shape == (2268, 4032, 3)
fp = open("../data/dataset/apple.jpg", "rb")
img2 = fp.read()
img2 = C.Decode()(img2)
logger.info("Image.type: {}, Image.shape: {}".format(type(img2), img2.shape))
assert img2.shape == (2268, 4032, 3)
def test_eager_decode_py():
"""
Feature: Decode op
Description: Test eager support for Decode Python op
Expectation: Output image size from op is correct
"""
img = np.fromfile("../data/dataset/apple.jpg", dtype=np.uint8)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
img = PY.Decode()(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
assert img.size == (4032, 2268)
fp = open("../data/dataset/apple.jpg", "rb")
img2 = fp.read()
img2 = PY.Decode()(img2)
logger.info("Image.type: {}, Image.shape: {}".format(type(img2), img2.size))
assert img2.size == (4032, 2268)
def test_eager_resize():
"""
Feature: Resize op
Description: Test eager support for Resize C++ op
Expectation: Output image info from op is correct
"""
img = cv2.imread("../data/dataset/apple.jpg")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
img = C.Resize(size=(32, 32))(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
assert img.shape == (32, 32, 3)
def test_eager_rescale():
"""
Feature: Rescale op
Description: Test eager support for Rescale C++ op
Expectation: Output image info from op is correct
"""
img = cv2.imread("../data/dataset/apple.jpg")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
pixel = img[0][0][0]
rescale_factor = 0.5
img = C.Rescale(rescale=rescale_factor, shift=0)(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
pixel_rescaled = img[0][0][0]
assert pixel * rescale_factor == pixel_rescaled
def test_eager_normalize_c():
"""
Feature: Normalize op
Description: Test eager support for Normalize C++ op
Expectation: Output image info from op is correct
"""
img = Image.open("../data/dataset/apple.jpg").convert("RGB")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
pixel = img.getpixel((0, 0))[0]
mean_vec = [100, 100, 100]
std_vec = [2, 2, 2]
img = C.Normalize(mean=mean_vec, std=std_vec)(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
pixel_normalized = img[0][0][0]
assert (pixel - mean_vec[0]) / std_vec[0] == pixel_normalized
def test_eager_normalize_py():
"""
Feature: Normalize op
Description: Test eager support for Normalize Python op
Expectation: Output image info from op is correct
"""
img = Image.open("../data/dataset/apple.jpg").convert("RGB")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
pixel = img.getpixel((0, 0))[0]
img = PY.ToTensor()(img)
mean_vec = [.100, .100, .100]
std_vec = [.2, .2, .2]
img = PY.Normalize(mean=mean_vec, std=std_vec)(img)
pixel_normalized = img[0][0][0]
assert (pixel / 255 - mean_vec[0]) / std_vec[0] == pytest.approx(pixel_normalized, 0.0001)
def test_eager_hwc2chw():
"""
Feature: HWC2CHW op
Description: Test eager support for HWC2CHW C++ op
Expectation: Output image info from op is correct
"""
img = cv2.imread("../data/dataset/apple.jpg")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
channel = img.shape
img = C.HWC2CHW()(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
channel_swaped = img.shape
assert channel == (channel_swaped[1], channel_swaped[2], channel_swaped[0])
def test_eager_pad_c():
"""
Feature: Pad op
Description: Test eager support for Pad C++ op
Expectation: Output image size info from op is correct
"""
img = Image.open("../data/dataset/apple.jpg").convert("RGB")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
img = C.Resize(size=(32, 32))(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
size = img.shape
pad = 4
img = C.Pad(padding=pad)(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
size_padded = img.shape
assert size_padded == (size[0] + 2 * pad, size[1] + 2 * pad, size[2])
def test_eager_pad_py():
"""
Feature: Pad op
Description: Test eager support for Pad Python op
Expectation: Output image size info from op is correct
"""
img = Image.open("../data/dataset/apple.jpg").convert("RGB")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
img = PY.Resize(size=(32, 32))(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
size = img.size
pad = 4
img = PY.Pad(padding=pad)(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
size_padded = img.size
assert size_padded == (size[0] + 2 * pad, size[1] + 2 * pad)
def test_eager_cutout_pil_c():
"""
Feature: CutOut op
Description: Test eager support for CutOut C++ op with PIL input
Expectation: Output image size info from op is correct
"""
img = Image.open("../data/dataset/apple.jpg").convert("RGB")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
img = C.Resize(size=(32, 32))(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
size = img.shape
img = C.CutOut(2, 4)(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
size_cutout = img.shape
assert size_cutout == size
def test_eager_cutout_pil_py():
"""
Feature: CutOut op
Description: Test eager support for CutOut Python op with PIL input
Expectation: Receive non-None output image from op
"""
img = Image.open("../data/dataset/apple.jpg").convert("RGB")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
img = PY.Resize(size=(32, 32))(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
img = PY.ToTensor()(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
img = PY.Cutout(2, 4)(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
assert img is not None
def test_eager_cutout_cv_c():
"""
Feature: CutOut op
Description: Test eager support for CutOut C++ op with CV input
Expectation: Output image size info from op is correct
"""
img = cv2.imread("../data/dataset/apple.jpg")
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
img = C.Resize(size=(32, 32))(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
size = img.shape
img = C.CutOut(2, 4)(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.size))
size_cutout = img.shape
assert size_cutout == size
def test_eager_exceptions():
"""
Feature: Eager Support
Description: Exception eager support test for various vision C++ ops
Expectation: Error input image is detected
"""
try:
img = "../data/dataset/apple.jpg"
_ = C.Decode()(img)
assert False
except TypeError as e:
assert "Input should be an encoded image in 1-D NumPy format" in str(e)
try:
img = np.array(["a", "b", "c"])
_ = C.Decode()(img)
assert False
except TypeError as e:
assert "Input should be an encoded image in 1-D NumPy format" in str(e)
try:
img = cv2.imread("../data/dataset/apple.jpg")
_ = C.Resize(size=(-32, 32))(img)
assert False
except ValueError as e:
assert "not within the required interval" in str(e)
try:
img = "../data/dataset/apple.jpg"
_ = C.Pad(padding=4)(img)
assert False
except TypeError as e:
assert "Input should be NumPy or PIL image" in str(e)
def test_eager_exceptions_normalize():
"""
Feature: Normalize op
Description: Exception eager support test for Normalize Python op
Expectation: Error input image is detected
"""
try:
img = Image.open("../data/dataset/apple.jpg").convert("RGB")
mean_vec = [.100, .100, .100]
std_vec = [.2, .2, .2]
_ = PY.Normalize(mean=mean_vec, std=std_vec)(img)
assert False
except TypeError as e:
assert "img should be NumPy image" in str(e)
def test_eager_exceptions_pad():
"""
Feature: Pad op
Description: Exception eager support test for Pad Python op
Expectation: Error input image is detected
"""
try:
img = "../data/dataset/apple.jpg"
_ = PY.Pad(padding=4)(img)
assert False
except TypeError as e:
assert "img should be PIL image" in str(e)
if __name__ == '__main__':
test_eager_decode_c()
test_eager_decode_py()
test_eager_resize()
test_eager_rescale()
test_eager_normalize_c()
test_eager_normalize_py()
test_eager_hwc2chw()
test_eager_pad_c()
test_eager_pad_py()
test_eager_cutout_pil_c()
test_eager_cutout_pil_py()
test_eager_cutout_cv_c()
test_eager_exceptions()
test_eager_exceptions_normalize()
test_eager_exceptions_pad()

View File

@ -0,0 +1,315 @@
# Copyright 2020-2022 Huawei Technologies Co., Ltd
#
# 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.
# ==============================================================================
"""
Testing Equalize op in DE
"""
import numpy as np
import mindspore.dataset as ds
import mindspore.dataset.transforms.py_transforms
import mindspore.dataset.vision.c_transforms as C
import mindspore.dataset.vision.py_transforms as F
from mindspore import log as logger
from ..dataset.util import visualize_list, visualize_one_channel_dataset, diff_mse, save_and_check_md5
DATA_DIR = "../data/dataset/testImageNetData/train/"
MNIST_DATA_DIR = "../data/dataset/testMnistData"
GENERATE_GOLDEN = False
def test_equalize_callable():
"""
Feature: Equalize Op
Description: Test op in eager mode
Expectation: Output image shape from op is verified
"""
logger.info("Test Equalize callable")
img = np.fromfile("../data/dataset/apple.jpg", dtype=np.uint8)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
img = C.Decode()(img)
img = C.Equalize()(img)
logger.info("Image.type: {}, Image.shape: {}".format(type(img), img.shape))
assert img.shape == (2268, 4032, 3)
def test_equalize_py(plot=False):
"""
Feature: Equalize Op
Description: Test Python op
Expectation: Dataset pipeline runs successfully and results are visually verified
"""
logger.info("Test Equalize")
# Original Images
data_set = ds.ImageFolderDataset(dataset_dir=DATA_DIR, shuffle=False)
transforms_original = mindspore.dataset.transforms.py_transforms.Compose([F.Decode(),
F.Resize((224, 224)),
F.ToTensor()])
ds_original = data_set.map(operations=transforms_original, input_columns="image")
ds_original = ds_original.batch(512)
for idx, (image, _) in enumerate(ds_original):
if idx == 0:
images_original = np.transpose(image.asnumpy(), (0, 2, 3, 1))
else:
images_original = np.append(images_original,
np.transpose(image.asnumpy(), (0, 2, 3, 1)),
axis=0)
# Color Equalized Images
data_set = ds.ImageFolderDataset(dataset_dir=DATA_DIR, shuffle=False)
transforms_equalize = mindspore.dataset.transforms.py_transforms.Compose([F.Decode(),
F.Resize((224, 224)),
F.Equalize(),
F.ToTensor()])
ds_equalize = data_set.map(operations=transforms_equalize, input_columns="image")
ds_equalize = ds_equalize.batch(512)
for idx, (image, _) in enumerate(ds_equalize):
if idx == 0:
images_equalize = np.transpose(image.asnumpy(), (0, 2, 3, 1))
else:
images_equalize = np.append(images_equalize,
np.transpose(image.asnumpy(), (0, 2, 3, 1)),
axis=0)
num_samples = images_original.shape[0]
mse = np.zeros(num_samples)
for i in range(num_samples):
mse[i] = diff_mse(images_equalize[i], images_original[i])
logger.info("MSE= {}".format(str(np.mean(mse))))
if plot:
visualize_list(images_original, images_equalize)
def test_equalize_c(plot=False):
"""
Feature: Equalize Op
Description: Test C++ op
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test Equalize cpp op")
# Original Images
data_set = ds.ImageFolderDataset(dataset_dir=DATA_DIR, shuffle=False)
transforms_original = [C.Decode(), C.Resize(size=[224, 224])]
ds_original = data_set.map(operations=transforms_original, input_columns="image")
ds_original = ds_original.batch(512)
for idx, (image, _) in enumerate(ds_original):
if idx == 0:
images_original = image.asnumpy()
else:
images_original = np.append(images_original,
image.asnumpy(),
axis=0)
# Equalize Images
data_set = ds.ImageFolderDataset(dataset_dir=DATA_DIR, shuffle=False)
transform_equalize = [C.Decode(), C.Resize(size=[224, 224]),
C.Equalize()]
ds_equalize = data_set.map(operations=transform_equalize, input_columns="image")
ds_equalize = ds_equalize.batch(512)
for idx, (image, _) in enumerate(ds_equalize):
if idx == 0:
images_equalize = image.asnumpy()
else:
images_equalize = np.append(images_equalize,
image.asnumpy(),
axis=0)
if plot:
visualize_list(images_original, images_equalize)
num_samples = images_original.shape[0]
mse = np.zeros(num_samples)
for i in range(num_samples):
mse[i] = diff_mse(images_equalize[i], images_original[i])
logger.info("MSE= {}".format(str(np.mean(mse))))
def test_equalize_py_c(plot=False):
"""
Feature: Equalize Op
Description: Test C++ op and Python op
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test Equalize cpp and python op")
# equalize Images in cpp
data_set = ds.ImageFolderDataset(dataset_dir=DATA_DIR, shuffle=False)
data_set = data_set.map(operations=[C.Decode(), C.Resize((224, 224))], input_columns=["image"])
ds_c_equalize = data_set.map(operations=C.Equalize(), input_columns="image")
ds_c_equalize = ds_c_equalize.batch(512)
for idx, (image, _) in enumerate(ds_c_equalize):
if idx == 0:
images_c_equalize = image.asnumpy()
else:
images_c_equalize = np.append(images_c_equalize,
image.asnumpy(),
axis=0)
# Equalize images in python
data_set = ds.ImageFolderDataset(dataset_dir=DATA_DIR, shuffle=False)
data_set = data_set.map(operations=[C.Decode(), C.Resize((224, 224))], input_columns=["image"])
transforms_p_equalize = mindspore.dataset.transforms.py_transforms.Compose([lambda img: img.astype(np.uint8),
F.ToPIL(),
F.Equalize(),
np.array])
ds_p_equalize = data_set.map(operations=transforms_p_equalize, input_columns="image")
ds_p_equalize = ds_p_equalize.batch(512)
for idx, (image, _) in enumerate(ds_p_equalize):
if idx == 0:
images_p_equalize = image.asnumpy()
else:
images_p_equalize = np.append(images_p_equalize,
image.asnumpy(),
axis=0)
num_samples = images_c_equalize.shape[0]
mse = np.zeros(num_samples)
for i in range(num_samples):
mse[i] = diff_mse(images_p_equalize[i], images_c_equalize[i])
logger.info("MSE= {}".format(str(np.mean(mse))))
if plot:
visualize_list(images_c_equalize, images_p_equalize, visualize_mode=2)
def test_equalize_one_channel():
"""
Feature: Equalize Op
Description: Test Equalize cpp op with one channel images
Expectation: Invalid input is detected
"""
logger.info("Test Equalize C++ op With One Channel Images")
c_op = C.Equalize()
try:
data_set = ds.ImageFolderDataset(dataset_dir=DATA_DIR, shuffle=False)
data_set = data_set.map(operations=[C.Decode(), C.Resize((224, 224)),
lambda img: np.array(img[:, :, 0])], input_columns=["image"])
data_set.map(operations=c_op, input_columns="image")
except RuntimeError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert "The shape" in str(e)
def test_equalize_mnist_c(plot=False):
"""
Feature: Equalize Op
Description: Test Equalize C++ op with MNIST dataset (Grayscale images)
Expectation: Dataset pipeline runs successfully and md5 results are verified
"""
logger.info("Test Equalize C++ op With MNIST Images")
data_set = ds.MnistDataset(dataset_dir=MNIST_DATA_DIR, num_samples=2, shuffle=False)
ds_equalize_c = data_set.map(operations=C.Equalize(), input_columns="image")
ds_orig = ds.MnistDataset(dataset_dir=MNIST_DATA_DIR, num_samples=2, shuffle=False)
images = []
images_trans = []
labels = []
for _, (data_orig, data_trans) in enumerate(zip(ds_orig, ds_equalize_c)):
image_orig, label_orig = data_orig
image_trans, _ = data_trans
images.append(image_orig.asnumpy())
labels.append(label_orig.asnumpy())
images_trans.append(image_trans.asnumpy())
# Compare with expected md5 from images
filename = "equalize_mnist_result_c.npz"
save_and_check_md5(ds_equalize_c, filename, generate_golden=GENERATE_GOLDEN)
if plot:
visualize_one_channel_dataset(images, images_trans, labels)
def test_equalize_md5_py():
"""
Feature: Equalize Op
Description: Test Python op with md5 check
Expectation: Dataset pipeline runs successfully and md5 results are verified
"""
logger.info("Test Equalize")
# First dataset
data1 = ds.ImageFolderDataset(dataset_dir=DATA_DIR, shuffle=False)
transforms = mindspore.dataset.transforms.py_transforms.Compose([F.Decode(),
F.Equalize(),
F.ToTensor()])
data1 = data1.map(operations=transforms, input_columns="image")
# Compare with expected md5 from images
filename = "equalize_01_result.npz"
save_and_check_md5(data1, filename, generate_golden=GENERATE_GOLDEN)
def test_equalize_md5_c():
"""
Feature: Equalize Op
Description: Test C++ op with md5 check
Expectation: Dataset pipeline runs successfully and md5 results are verified
"""
logger.info("Test Equalize cpp op with md5 check")
# Generate dataset
data_set = ds.ImageFolderDataset(dataset_dir=DATA_DIR, shuffle=False)
transforms_equalize = [C.Decode(),
C.Resize(size=[224, 224]),
C.Equalize(),
F.ToTensor()]
data = data_set.map(operations=transforms_equalize, input_columns="image")
# Compare with expected md5 from images
filename = "equalize_01_result_c.npz"
save_and_check_md5(data, filename, generate_golden=GENERATE_GOLDEN)
if __name__ == "__main__":
test_equalize_callable()
test_equalize_py(plot=False)
test_equalize_c(plot=False)
test_equalize_py_c(plot=False)
test_equalize_mnist_c(plot=True)
test_equalize_one_channel()
test_equalize_md5_py()
test_equalize_md5_c()

View File

@ -0,0 +1,125 @@
# Copyright 2022 Huawei Technologies Co., Ltd
#
# 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 pytest
import mindspore.dataset as ds
from mindspore.dataset.transforms import c_transforms
from mindspore.dataset.transforms import py_transforms
import mindspore.dataset.vision.c_transforms as c_vision
import mindspore.dataset.vision.py_transforms as py_vision
DATA_DIR = "../data/dataset/testPK/data"
def test_map_c_transform_exception():
"""
Feature: test c error op def
Description: op defined like c_vision.HWC2CHW
Expectation: success
"""
data_set = ds.ImageFolderDataset(DATA_DIR, num_parallel_workers=1, shuffle=True)
train_image_size = 224
mean = [0.485 * 255, 0.456 * 255, 0.406 * 255]
std = [0.229 * 255, 0.224 * 255, 0.225 * 255]
# define map operations
random_crop_decode_resize_op = c_vision.RandomCropDecodeResize(train_image_size,
scale=(0.08, 1.0),
ratio=(0.75, 1.333))
random_horizontal_flip_op = c_vision.RandomHorizontalFlip(prob=0.5)
normalize_op = c_vision.Normalize(mean=mean, std=std)
hwc2chw_op = c_vision.HWC2CHW # exception
data_set = data_set.map(operations=random_crop_decode_resize_op, input_columns="image", num_parallel_workers=1)
data_set = data_set.map(operations=random_horizontal_flip_op, input_columns="image", num_parallel_workers=1)
data_set = data_set.map(operations=normalize_op, input_columns="image", num_parallel_workers=1)
with pytest.raises(ValueError) as info:
data_set = data_set.map(operations=hwc2chw_op, input_columns="image", num_parallel_workers=1)
assert "Parameter operations's element of method map should be a " in str(info.value)
# compose exception
with pytest.raises(ValueError) as info:
c_transforms.Compose([
c_vision.RandomCropDecodeResize(train_image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
c_vision.RandomHorizontalFlip,
c_vision.Normalize(mean=mean, std=std),
c_vision.HWC2CHW()])
assert " should be a " in str(info.value)
# randomapply exception
with pytest.raises(ValueError) as info:
c_transforms.RandomApply([
c_vision.RandomCropDecodeResize,
c_vision.RandomHorizontalFlip(prob=0.5),
c_vision.Normalize(mean=mean, std=std),
c_vision.HWC2CHW()])
assert " should be a " in str(info.value)
# randomchoice exception
with pytest.raises(ValueError) as info:
c_transforms.RandomChoice([
c_vision.RandomCropDecodeResize(train_image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
c_vision.RandomHorizontalFlip(prob=0.5),
c_vision.Normalize,
c_vision.HWC2CHW()])
assert " should be a " in str(info.value)
def test_map_py_transform_exception():
"""
Feature: test python error op def
Description: op defined like py_vision.RandomHorizontalFlip
Expectation: success
"""
data_set = ds.ImageFolderDataset(DATA_DIR, num_parallel_workers=1, shuffle=True)
# define map operations
decode_op = py_vision.Decode()
random_horizontal_flip_op = py_vision.RandomHorizontalFlip # exception
to_tensor_op = py_vision.ToTensor()
trans = [decode_op, random_horizontal_flip_op, to_tensor_op]
with pytest.raises(ValueError) as info:
data_set = data_set.map(operations=trans, input_columns="image", num_parallel_workers=1)
assert "Parameter operations's element of method map should be a " in str(info.value)
# compose exception
with pytest.raises(ValueError) as info:
py_transforms.Compose([
py_vision.Decode,
py_vision.RandomHorizontalFlip(),
py_vision.ToTensor()])
assert " should be a " in str(info.value)
# randomapply exception
with pytest.raises(ValueError) as info:
py_transforms.RandomApply([
py_vision.Decode(),
py_vision.RandomHorizontalFlip,
py_vision.ToTensor()])
assert " should be a " in str(info.value)
# randomchoice exception
with pytest.raises(ValueError) as info:
py_transforms.RandomChoice([
py_vision.Decode(),
py_vision.RandomHorizontalFlip(),
py_vision.ToTensor])
assert " should be a " in str(info.value)
if __name__ == '__main__':
test_map_c_transform_exception()
test_map_py_transform_exception()

View File

@ -0,0 +1,171 @@
# Copyright 2019-2022 Huawei Technologies Co., Ltd
#
# 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 numpy as np
import mindspore.dataset as ds
import mindspore.dataset.transforms.c_transforms as c
import mindspore.dataset.transforms.py_transforms as f
import mindspore.dataset.vision.c_transforms as c_vision
import mindspore.dataset.vision.py_transforms as py_vision
from mindspore import log as logger
DATA_DIR = "../data/dataset/testImageNetData/train"
DATA_DIR_2 = "../data/dataset/testImageNetData2/train"
def test_one_hot_op():
"""
Feature: OneHot Op
Description: Test Python op, one hot encoding with smoothing_rate
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test one hot encoding op")
# define map operations
dataset = ds.ImageFolderDataset(DATA_DIR)
num_classes = 2
epsilon_para = 0.1
transforms = [f.OneHotOp(num_classes=num_classes, smoothing_rate=epsilon_para)]
transform_label = f.Compose(transforms)
dataset = dataset.map(operations=transform_label, input_columns=["label"])
golden_label = np.ones(num_classes) * epsilon_para / num_classes
golden_label[1] = 1 - epsilon_para / num_classes
for data in dataset.create_dict_iterator(num_epochs=1, output_numpy=True):
label = data["label"]
logger.info("label is {}".format(label))
logger.info("golden_label is {}".format(golden_label))
assert label.all() == golden_label.all()
logger.info("====test one hot op ok====")
def test_mix_up_single():
"""
Feature: MixUp Op
Description: Test Python op, single batch mix up scenario
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test single batch mix up op")
resize_height = 224
resize_width = 224
# Create dataset and define map operations
ds1 = ds.ImageFolderDataset(DATA_DIR_2)
num_classes = 10
decode_op = c_vision.Decode()
resize_op = c_vision.Resize((resize_height, resize_width), c_vision.Inter.LINEAR)
one_hot_encode = c.OneHot(num_classes) # num_classes is input argument
ds1 = ds1.map(operations=decode_op, input_columns=["image"])
ds1 = ds1.map(operations=resize_op, input_columns=["image"])
ds1 = ds1.map(operations=one_hot_encode, input_columns=["label"])
# apply batch operations
batch_size = 3
ds1 = ds1.batch(batch_size, drop_remainder=True)
ds2 = ds1
alpha = 0.2
transforms = [py_vision.MixUp(batch_size=batch_size, alpha=alpha, is_single=True)
]
ds1 = ds1.map(operations=transforms, input_columns=["image", "label"])
for data1, data2 in zip(ds1.create_dict_iterator(num_epochs=1, output_numpy=True),
ds2.create_dict_iterator(num_epochs=1, output_numpy=True)):
image1 = data1["image"]
label = data1["label"]
logger.info("label is {}".format(label))
image2 = data2["image"]
label2 = data2["label"]
logger.info("label2 is {}".format(label2))
lam = np.abs(label - label2)
for index in range(batch_size - 1):
if np.square(lam[index]).mean() != 0:
lam_value = 1 - np.sum(lam[index]) / 2
img_golden = lam_value * image2[index] + (1 - lam_value) * image2[index + 1]
assert image1[index].all() == img_golden.all()
logger.info("====test single batch mixup ok====")
def test_mix_up_multi():
"""
Feature: MixUp Op
Description: Test Python op, multiple batch mix up scenario
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test several batch mix up op")
resize_height = 224
resize_width = 224
# Create dataset and define map operations
ds1 = ds.ImageFolderDataset(DATA_DIR_2)
num_classes = 3
decode_op = c_vision.Decode()
resize_op = c_vision.Resize((resize_height, resize_width), c_vision.Inter.LINEAR)
one_hot_encode = c.OneHot(num_classes) # num_classes is input argument
ds1 = ds1.map(operations=[decode_op, resize_op], input_columns=["image"])
ds1 = ds1.map(operations=one_hot_encode, input_columns=["label"])
# apply batch operations
batch_size = 3
ds1 = ds1.batch(batch_size, drop_remainder=True)
ds2 = ds1
alpha = 0.2
transforms = [py_vision.MixUp(batch_size=batch_size, alpha=alpha, is_single=False)
]
ds1 = ds1.map(operations=transforms, input_columns=["image", "label"])
num_iter = 0
batch1_image1 = 0
for data1, data2 in zip(ds1.create_dict_iterator(num_epochs=1, output_numpy=True),
ds2.create_dict_iterator(num_epochs=1, output_numpy=True)):
image1 = data1["image"]
label1 = data1["label"]
logger.info("label: {}".format(label1))
image2 = data2["image"]
label2 = data2["label"]
logger.info("label2: {}".format(label2))
if num_iter == 0:
batch1_image1 = image1
if num_iter == 1:
lam = np.abs(label2 - label1)
logger.info("lam value in multi: {}".format(lam))
for index in range(batch_size):
if np.square(lam[index]).mean() != 0:
lam_value = 1 - np.sum(lam[index]) / 2
img_golden = lam_value * image2[index] + (1 - lam_value) * batch1_image1[index]
assert image1[index].all() == img_golden.all()
logger.info("====test several batch mixup ok====")
break
num_iter += 1
assert num_iter == 1
if __name__ == "__main__":
test_one_hot_op()
test_mix_up_single()
test_mix_up_multi()

View File

@ -0,0 +1,359 @@
# Copyright 2019-2022 Huawei Technologies Co., Ltd
#
# 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.
# ==============================================================================
"""
Testing Normalize op in DE
"""
import numpy as np
import mindspore.dataset as ds
import mindspore.dataset.transforms.py_transforms
import mindspore.dataset.vision.c_transforms as c_vision
import mindspore.dataset.vision.py_transforms as py_vision
from mindspore import log as logger
from ..dataset.util import diff_mse, save_and_check_md5, visualize_image
DATA_DIR = ["../data/dataset/test_tf_file_3_images/train-0000-of-0001.data"]
SCHEMA_DIR = "../data/dataset/test_tf_file_3_images/datasetSchema.json"
GENERATE_GOLDEN = False
def normalize_np(image, mean, std):
"""
Apply the Normalization
"""
# DE decodes the image in RGB by default, hence
# the values here are in RGB
image = np.array(image, np.float32)
image = image - np.array(mean)
image = image * (1.0 / np.array(std))
return image
def util_test_normalize(mean, std, op_type):
"""
Utility function for testing Normalize. Input arguments are given by other tests
"""
if op_type == "cpp":
# define map operations
decode_op = c_vision.Decode()
normalize_op = c_vision.Normalize(mean, std)
# Generate dataset
data = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data = data.map(operations=decode_op, input_columns=["image"])
data = data.map(operations=normalize_op, input_columns=["image"])
elif op_type == "python":
# define map operations
transforms = [
py_vision.Decode(),
py_vision.ToTensor(),
py_vision.Normalize(mean, std)
]
transform = mindspore.dataset.transforms.py_transforms.Compose(transforms)
# Generate dataset
data = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data = data.map(operations=transform, input_columns=["image"])
else:
raise ValueError("Wrong parameter value")
return data
def util_test_normalize_grayscale(num_output_channels, mean, std):
"""
Utility function for testing Normalize. Input arguments are given by other tests
"""
transforms = [
py_vision.Decode(),
py_vision.Grayscale(num_output_channels),
py_vision.ToTensor(),
py_vision.Normalize(mean, std)
]
transform = mindspore.dataset.transforms.py_transforms.Compose(transforms)
# Generate dataset
data = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data = data.map(operations=transform, input_columns=["image"])
return data
def test_normalize_op_c(plot=False):
"""
Feature: Normalize Op
Description: Test C++ op in dataset pipeline
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test Normalize in cpp")
mean = [121.0, 115.0, 100.0]
std = [70.0, 68.0, 71.0]
# define map operations
decode_op = c_vision.Decode()
normalize_op = c_vision.Normalize(mean, std)
# First dataset
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data1 = data1.map(operations=decode_op, input_columns=["image"])
data1 = data1.map(operations=normalize_op, input_columns=["image"])
# Second dataset
data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data2 = data2.map(operations=decode_op, input_columns=["image"])
num_iter = 0
for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True),
data2.create_dict_iterator(num_epochs=1, output_numpy=True)):
image_de_normalized = item1["image"]
image_original = item2["image"]
image_np_normalized = normalize_np(image_original, mean, std)
mse = diff_mse(image_de_normalized, image_np_normalized)
logger.info("image_{}, mse: {}".format(num_iter + 1, mse))
assert mse < 0.01
if plot:
visualize_image(image_original, image_de_normalized, mse, image_np_normalized)
num_iter += 1
def test_normalize_op_py(plot=False):
"""
Feature: Normalize Op
Description: Test Python op in dataset pipeline
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test Normalize in python")
mean = [0.475, 0.45, 0.392]
std = [0.275, 0.267, 0.278]
# define map operations
transforms = [
py_vision.Decode(),
py_vision.ToTensor()
]
transform = mindspore.dataset.transforms.py_transforms.Compose(transforms)
normalize_op = py_vision.Normalize(mean, std)
# First dataset
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data1 = data1.map(operations=transform, input_columns=["image"])
data1 = data1.map(operations=normalize_op, input_columns=["image"])
# Second dataset
data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data2 = data2.map(operations=transform, input_columns=["image"])
num_iter = 0
for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True),
data2.create_dict_iterator(num_epochs=1, output_numpy=True)):
image_de_normalized = (item1["image"].transpose(1, 2, 0) * 255).astype(np.uint8)
image_np_normalized = (normalize_np(item2["image"].transpose(1, 2, 0), mean, std) * 255).astype(np.uint8)
image_original = (item2["image"].transpose(1, 2, 0) * 255).astype(np.uint8)
mse = diff_mse(image_de_normalized, image_np_normalized)
logger.info("image_{}, mse: {}".format(num_iter + 1, mse))
assert mse < 0.01
if plot:
visualize_image(image_original, image_de_normalized, mse, image_np_normalized)
num_iter += 1
def test_normalize_md5_01():
"""
Feature: Normalize Op
Description: Test C++ op and Python op in same dataset pipeline
Expectation: Dataset pipeline runs successfully and md5 results are verified
"""
logger.info("test_normalize_md5_01")
data_c = util_test_normalize([121.0, 115.0, 100.0], [70.0, 68.0, 71.0], "cpp")
data_py = util_test_normalize([0.475, 0.45, 0.392], [0.275, 0.267, 0.278], "python")
# check results with md5 comparison
filename1 = "normalize_01_c_result.npz"
filename2 = "normalize_01_py_result.npz"
save_and_check_md5(data_c, filename1, generate_golden=GENERATE_GOLDEN)
save_and_check_md5(data_py, filename2, generate_golden=GENERATE_GOLDEN)
def test_normalize_md5_02():
"""
Feature: Normalize Op
Description: Test Python op with len(mean)=len(std)=1 and RGB images
Expectation: Dataset pipeline runs successfully and md5 results are verified
"""
logger.info("test_normalize_md5_02")
data_py = util_test_normalize([0.475], [0.275], "python")
# check results with md5 comparison
filename2 = "normalize_02_py_result.npz"
save_and_check_md5(data_py, filename2, generate_golden=GENERATE_GOLDEN)
def test_normalize_exception_unequal_size_c():
"""
Feature: Normalize Op
Description: Test Normalize C++ op with error input: len(mean) != len(std)
Expectation: Invalid input is detected
"""
logger.info("test_normalize_exception_unequal_size_c")
try:
_ = c_vision.Normalize([100, 250, 125], [50, 50, 75, 75])
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert str(e) == "Length of mean and std must be equal."
def test_normalize_exception_out_of_range_c():
"""
Feature: Normalize Op
Description: Test Normalize Python op with error input: value is not in range [0,255]
Expectation: Invalid input is detected
"""
logger.info("test_normalize_exception_out_of_range_c")
try:
_ = c_vision.Normalize([256, 250, 125], [50, 75, 75])
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert "not within the required interval" in str(e)
try:
_ = c_vision.Normalize([255, 250, 125], [0, 75, 75])
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert "not within the required interval" in str(e)
def test_normalize_exception_unequal_size_py():
"""
Feature: Normalize Op
Description: Test Normalize Python op with error input: len(mean) != len(std)
Expectation: Invalid input is detected
"""
logger.info("test_normalize_exception_unequal_size_py")
try:
_ = py_vision.Normalize([0.50, 0.30, 0.75], [0.18, 0.32, 0.71, 0.72])
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert str(e) == "Length of mean and std must be equal."
def test_normalize_exception_invalid_size_py():
"""
Feature: Normalize Op
Description: Test Normalize Python op with error input: len(mean)=len(std)=2
Expectation: Invalid input is detected
"""
logger.info("test_normalize_exception_invalid_size_py")
data = util_test_normalize([0.75, 0.25], [0.18, 0.32], "python")
try:
_ = data.create_dict_iterator(num_epochs=1).__next__()
except RuntimeError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert "Length of mean and std must both be 1 or" in str(e)
def test_normalize_exception_invalid_range_py():
"""
Feature: Normalize Op
Description: Test Normalize Python op with error input: value is not in range [0,1]
Expectation: Invalid input is detected
"""
logger.info("test_normalize_exception_invalid_range_py")
try:
_ = py_vision.Normalize([0.75, 1.25, 0.5], [0.1, 0.18, 1.32])
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert "Input mean_value is not within the required interval of [0.0, 1.0]." in str(e)
def test_normalize_grayscale_md5_01():
"""
Feature: Normalize Op
Description: Test Python op with len(mean)=len(std)=1 and 1 channel grayscale images
Expectation: Dataset pipeline runs successfully and md5 results are verified
"""
logger.info("test_normalize_grayscale_md5_01")
data = util_test_normalize_grayscale(1, [0.5], [0.175])
# check results with md5 comparison
filename = "normalize_03_py_result.npz"
save_and_check_md5(data, filename, generate_golden=GENERATE_GOLDEN)
def test_normalize_grayscale_md5_02():
"""
Feature: Normalize Op
Description: Test Python op with len(mean)=len(std)=1 and 3 channel grayscale images
Expectation: Dataset pipeline runs successfully and md5 results are verified
"""
logger.info("test_normalize_grayscale_md5_02")
data = util_test_normalize_grayscale(3, [0.5, 0.5, 0.5], [0.175, 0.235, 0.512])
# check results with md5 comparison
filename = "normalize_04_py_result.npz"
save_and_check_md5(data, filename, generate_golden=GENERATE_GOLDEN)
def test_normalize_grayscale_exception():
"""
Feature: Normalize Op
Description: Test Normalize Python op with error input: len(mean)=len(std)=3 with 1 channel grayscale images
Expectation: Invalid input is detected
"""
logger.info("test_normalize_grayscale_exception")
try:
_ = util_test_normalize_grayscale(1, [0.5, 0.5, 0.5], [0.175, 0.235, 0.512])
except RuntimeError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert "Input is not within the required range" in str(e)
def test_multiple_channels():
"""
Feature: Normalize Op
Description: Test C++ op with multiple channels
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("test_multiple_channels")
def util_test(item, mean, std):
data = ds.NumpySlicesDataset([item], shuffle=False)
data = data.map(c_vision.Normalize(mean, std))
for d in data.create_tuple_iterator(num_epochs=1, output_numpy=True):
actual = d[0]
mean = np.array(mean, dtype=item.dtype)
std = np.array(std, dtype=item.dtype)
expected = item
if len(item.shape) != 1 and len(mean) == 1:
mean = [mean[0]] * expected.shape[-1]
std = [std[0]] * expected.shape[-1]
if len(item.shape) == 2:
expected = np.expand_dims(expected, 2)
for c in range(expected.shape[-1]):
expected[:, :, c] = (expected[:, :, c] - mean[c]) / std[c]
expected = expected.squeeze()
np.testing.assert_almost_equal(actual, expected, decimal=6)
util_test(np.ones(shape=[2, 2, 3]), mean=[0.5, 0.6, 0.7], std=[0.1, 0.2, 0.3])
util_test(np.ones(shape=[20, 45, 3]) * 1.3, mean=[0.5, 0.6, 0.7], std=[0.1, 0.2, 0.3])
util_test(np.ones(shape=[20, 45, 4]) * 1.3, mean=[0.5, 0.6, 0.7, 0.8], std=[0.1, 0.2, 0.3, 0.4])
util_test(np.ones(shape=[2, 2]), mean=[0.5], std=[0.1])
util_test(np.ones(shape=[2, 2, 5]), mean=[0.5], std=[0.1])
util_test(np.ones(shape=[6, 6, 129]), mean=[0.5] * 129, std=[0.1] * 129)
util_test(np.ones(shape=[6, 6, 129]), mean=[0.5], std=[0.1])
if __name__ == "__main__":
test_normalize_op_c(plot=True)
test_normalize_op_py(plot=True)
test_normalize_md5_01()
test_normalize_md5_02()
test_normalize_exception_unequal_size_c()
test_normalize_exception_unequal_size_py()
test_normalize_exception_invalid_size_py()
test_normalize_exception_invalid_range_py()
test_normalize_grayscale_md5_01()
test_normalize_grayscale_md5_02()
test_normalize_grayscale_exception()

View File

@ -0,0 +1,219 @@
# Copyright 2020-2022 Huawei Technologies Co., Ltd
#
# 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.
# ==============================================================================
"""
Testing NormalizePad op in DE
"""
import numpy as np
import mindspore.dataset as ds
import mindspore.dataset.transforms.py_transforms
import mindspore.dataset.vision.c_transforms as c_vision
import mindspore.dataset.vision.py_transforms as py_vision
from mindspore import log as logger
from ..dataset.util import diff_mse, visualize_image
DATA_DIR = ["../data/dataset/test_tf_file_3_images/train-0000-of-0001.data"]
SCHEMA_DIR = "../data/dataset/test_tf_file_3_images/datasetSchema.json"
GENERATE_GOLDEN = False
def normalizepad_np(image, mean, std):
"""
Apply the normalize+pad
"""
# DE decodes the image in RGB by default, hence
# the values here are in RGB
image = np.array(image, np.float32)
image = image - np.array(mean)
image = image * (1.0 / np.array(std))
zeros = np.zeros([image.shape[0], image.shape[1], 1], dtype=np.float32)
output = np.concatenate((image, zeros), axis=2)
return output
def test_normalizepad_op_c(plot=False):
"""
Feature: NormalizePad Op
Description: Test C++ op in dataset pipeline
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test NormalizePad in cpp")
mean = [121.0, 115.0, 100.0]
std = [70.0, 68.0, 71.0]
# define map operations
decode_op = c_vision.Decode()
normalizepad_op = c_vision.NormalizePad(mean, std)
# First dataset
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data1 = data1.map(operations=decode_op, input_columns=["image"])
data1 = data1.map(operations=normalizepad_op, input_columns=["image"])
# Second dataset
data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data2 = data2.map(operations=decode_op, input_columns=["image"])
num_iter = 0
for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True),
data2.create_dict_iterator(num_epochs=1, output_numpy=True)):
image_de_normalized = item1["image"]
image_original = item2["image"]
image_np_normalized = normalizepad_np(image_original, mean, std)
mse = diff_mse(image_de_normalized, image_np_normalized)
logger.info("image_{}, mse: {}".format(num_iter + 1, mse))
assert mse < 0.01
if plot:
visualize_image(image_original, image_de_normalized, mse, image_np_normalized)
num_iter += 1
def test_normalizepad_op_py(plot=False):
"""
Feature: NormalizePad Op
Description: Test Python op in dataset pipeline
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test NormalizePad in python")
mean = [0.475, 0.45, 0.392]
std = [0.275, 0.267, 0.278]
# define map operations
transforms = [
py_vision.Decode(),
py_vision.ToTensor()
]
transform = mindspore.dataset.transforms.py_transforms.Compose(transforms)
normalizepad_op = py_vision.NormalizePad(mean, std)
# First dataset
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data1 = data1.map(operations=transform, input_columns=["image"])
data1 = data1.map(operations=normalizepad_op, input_columns=["image"])
# Second dataset
data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image"], shuffle=False)
data2 = data2.map(operations=transform, input_columns=["image"])
num_iter = 0
for item1, item2 in zip(data1.create_dict_iterator(num_epochs=1, output_numpy=True),
data2.create_dict_iterator(num_epochs=1, output_numpy=True)):
image_de_normalized = (item1["image"].transpose(1, 2, 0) * 255).astype(np.uint8)
image_np_normalized = (normalizepad_np(item2["image"].transpose(1, 2, 0), mean, std) * 255).astype(np.uint8)
image_original = (item2["image"].transpose(1, 2, 0) * 255).astype(np.uint8)
mse = diff_mse(image_de_normalized, image_np_normalized)
logger.info("image_{}, mse: {}".format(num_iter + 1, mse))
assert mse < 0.01
if plot:
visualize_image(image_original, image_de_normalized, mse, image_np_normalized)
num_iter += 1
def test_decode_normalizepad_op():
"""
Feature: NormalizePad Op
Description: Test Decode C++ op followed by NormalizePad op in dataset pipeline
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("Test [Decode, NormalizePad] in one Map")
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["image", "label"], num_parallel_workers=1,
shuffle=False)
# define map operations
decode_op = c_vision.Decode()
normalizepad_op = c_vision.NormalizePad([121.0, 115.0, 100.0], [70.0, 68.0, 71.0], "float16")
# apply map operations on images
data1 = data1.map(operations=[decode_op, normalizepad_op], input_columns=["image"])
num_iter = 0
for item in data1.create_dict_iterator(num_epochs=1, output_numpy=True):
logger.info("Looping inside iterator {}".format(num_iter))
assert item["image"].dtype == np.float16
num_iter += 1
def test_normalizepad_exception_unequal_size_c():
"""
Feature: NormalizePad Op
Description: Test NormalizePad C++ op with error input: len(mean) != len(std)
Expectation: Invalid input is detected
"""
logger.info("test_normalize_exception_unequal_size_c")
try:
_ = c_vision.NormalizePad([100, 250, 125], [50, 50, 75, 75])
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert str(e) == "Length of mean and std must be equal."
try:
_ = c_vision.NormalizePad([100, 250, 125], [50, 50, 75], 1)
except TypeError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert str(e) == "dtype should be string."
try:
_ = c_vision.NormalizePad([100, 250, 125], [50, 50, 75], "")
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert str(e) == "dtype only support float32 or float16."
def test_normalizepad_exception_unequal_size_py():
"""
Feature: NormalizePad Op
Description: Test NormalizePad Python op with error input: len(mean) != len(std)
Expectation: Invalid input is detected
"""
logger.info("test_normalizepad_exception_unequal_size_py")
try:
_ = py_vision.NormalizePad([0.50, 0.30, 0.75], [0.18, 0.32, 0.71, 0.72])
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert str(e) == "Length of mean and std must be equal."
try:
_ = py_vision.NormalizePad([0.50, 0.30, 0.75], [0.18, 0.32, 0.71], 1)
except TypeError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert str(e) == "dtype should be string."
try:
_ = py_vision.NormalizePad([0.50, 0.30, 0.75], [0.18, 0.32, 0.71], "")
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert str(e) == "dtype only support float32 or float16."
def test_normalizepad_exception_invalid_range_py():
"""
Feature: NormalizePad Op
Description: Test NormalizePad Python op with error input: value is not in range [0,1]
Expectation: Invalid input is detected
"""
logger.info("test_normalizepad_exception_invalid_range_py")
try:
_ = py_vision.NormalizePad([0.75, 1.25, 0.5], [0.1, 0.18, 1.32])
except ValueError as e:
logger.info("Got an exception in DE: {}".format(str(e)))
assert "Input mean_value is not within the required interval of [0.0, 1.0]." in str(e)
if __name__ == "__main__":
test_normalizepad_op_c(plot=True)
test_normalizepad_op_py(plot=True)
test_decode_normalizepad_op()
test_normalizepad_exception_unequal_size_c()
test_normalizepad_exception_unequal_size_py()
test_normalizepad_exception_invalid_range_py()

View File

@ -0,0 +1,245 @@
# Copyright 2019-2022 Huawei Technologies Co., Ltd
#
# 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.
# ==============================================================================
"""
Testing the OneHot Op
"""
import numpy as np
import mindspore.dataset as ds
import mindspore.dataset.transforms.c_transforms as data_trans
import mindspore.dataset.transforms.py_transforms as py_trans
import mindspore.dataset.vision.c_transforms as c_vision
from mindspore import log as logger
from ..dataset.util import dataset_equal_with_function
DATA_DIR = ["../data/dataset/test_tf_file_3_images/train-0000-of-0001.data"]
SCHEMA_DIR = "../data/dataset/test_tf_file_3_images/datasetSchema.json"
def one_hot(index, depth):
"""
Apply the one_hot
"""
arr = np.zeros([1, depth], dtype=np.int32)
arr[0, index] = 1
return arr
def test_one_hot():
"""
Feature: OneHot Op
Description: Test C++ op with One Hot Encoding
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("test_one_hot")
depth = 10
# First dataset
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, shuffle=False)
one_hot_op = data_trans.OneHot(num_classes=depth)
data1 = data1.map(operations=one_hot_op, input_columns=["label"], column_order=["label"])
# Second dataset
data2 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, columns_list=["label"], shuffle=False)
assert dataset_equal_with_function(data1, data2, 0, one_hot, depth)
def test_one_hot_post_aug():
"""
Feature: OneHot Op
Description: Test C++ op with One Hot Encoding after Multiple Data Augmentation Operators
Expectation: Dataset pipeline runs successfully and results are verified
"""
logger.info("test_one_hot_post_aug")
data1 = ds.TFRecordDataset(DATA_DIR, SCHEMA_DIR, shuffle=False)
# Define data augmentation parameters
rescale = 1.0 / 255.0
shift = 0.0
resize_height, resize_width = 224, 224
# Define map operations
decode_op = c_vision.Decode()
rescale_op = c_vision.Rescale(rescale, shift)
resize_op = c_vision.Resize((resize_height, resize_width))
# Apply map operations on images
data1 = data1.map(operations=decode_op, input_columns=["image"])
data1 = data1.map(operations=rescale_op, input_columns=["image"])
data1 = data1.map(operations=resize_op, input_columns=["image"])
# Apply one-hot encoding on labels
depth = 4
one_hot_encode = data_trans.OneHot(depth)
data1 = data1.map(operations=one_hot_encode, input_columns=["label"])
# Apply datasets ops
buffer_size = 100
seed = 10
batch_size = 2
ds.config.set_seed(seed)
data1 = data1.shuffle(buffer_size=buffer_size)
data1 = data1.batch(batch_size, drop_remainder=True)
num_iter = 0
for item in data1.create_dict_iterator(num_epochs=1):
logger.info("image is: {}".format(item["image"]))
logger.info("label is: {}".format(item["label"]))
num_iter += 1
assert num_iter == 1
def test_one_hot_success():
"""
Feature: OneHot Op
Description: Test Python op, with generated label using np.array(index)
Expectation: Dataset pipeline runs successfully and results are verified
"""
class GetDatasetGenerator:
def __init__(self):
np.random.seed(58)
self.__data = np.random.sample((5, 2))
self.__label = []
for index in range(5):
self.__label.append(np.array(index))
def __getitem__(self, index):
return (self.__data[index], self.__label[index])
def __len__(self):
return len(self.__data)
dataset = ds.GeneratorDataset(GetDatasetGenerator(), ["data", "label"], shuffle=False)
one_hot_encode = py_trans.OneHotOp(10)
trans = py_trans.Compose([one_hot_encode])
dataset = dataset.map(operations=trans, input_columns=["label"])
for index, item in enumerate(dataset.create_dict_iterator(num_epochs=1, output_numpy=True)):
assert item["label"][index] == 1.0
def test_one_hot_success2():
"""
Feature: OneHot Op
Description: Test Python op, with generated label using np.array([index])
Expectation: Dataset pipeline runs successfully and results are verified
"""
class GetDatasetGenerator:
def __init__(self):
np.random.seed(58)
self.__data = np.random.sample((5, 2))
self.__label = []
for index in range(5):
self.__label.append(np.array([index]))
def __getitem__(self, index):
return (self.__data[index], self.__label[index])
def __len__(self):
return len(self.__data)
dataset = ds.GeneratorDataset(GetDatasetGenerator(), ["data", "label"], shuffle=False)
one_hot_encode = py_trans.OneHotOp(10)
trans = py_trans.Compose([one_hot_encode])
dataset = dataset.map(operations=trans, input_columns=["label"])
for index, item in enumerate(dataset.create_dict_iterator(num_epochs=1, output_numpy=True)):
logger.info(item)
assert item["label"][0][index] == 1.0
def test_one_hot_success3():
"""
Feature: OneHot Op
Description: Test Python op, with multi-dimension generated label
Expectation: Dataset pipeline runs successfully and results are verified
"""
class GetDatasetGenerator:
def __init__(self):
np.random.seed(58)
self.__data = np.random.sample((5, 2))
self.__label = []
for _ in range(5):
value = np.ones([10, 1], dtype=np.int32)
for i in range(10):
value[i][0] = i
self.__label.append(value)
def __getitem__(self, index):
return (self.__data[index], self.__label[index])
def __len__(self):
return len(self.__data)
dataset = ds.GeneratorDataset(GetDatasetGenerator(), ["data", "label"], shuffle=False)
one_hot_encode = py_trans.OneHotOp(10)
trans = py_trans.Compose([one_hot_encode])
dataset = dataset.map(operations=trans, input_columns=["label"])
for item in dataset.create_dict_iterator(num_epochs=1, output_numpy=True):
logger.info(item)
for i in range(10):
assert item["label"][i][0][i] == 1.0
def test_one_hot_type_error():
"""
Feature: OneHot Op
Description: Test Python op with invalid float input type
Expectation: Invalid input is detected
"""
class GetDatasetGenerator:
def __init__(self):
np.random.seed(58)
self.__data = np.random.sample((5, 2))
self.__label = []
for index in range(5):
self.__label.append(np.array(float(index)))
def __getitem__(self, index):
return (self.__data[index], self.__label[index])
def __len__(self):
return len(self.__data)
dataset = ds.GeneratorDataset(GetDatasetGenerator(), ["data", "label"], shuffle=False)
one_hot_encode = py_trans.OneHotOp(10)
trans = py_trans.Compose([one_hot_encode])
dataset = dataset.map(operations=trans, input_columns=["label"])
try:
for index, item in enumerate(dataset.create_dict_iterator(num_epochs=1, output_numpy=True)):
assert item["label"][index] == 1.0
except RuntimeError as e:
assert "the input numpy type should be int" in str(e)
if __name__ == "__main__":
test_one_hot()
test_one_hot_post_aug()
test_one_hot_success()
test_one_hot_success2()
test_one_hot_success3()
test_one_hot_type_error()

View File

@ -0,0 +1,193 @@
# Copyright 2021-2022 Huawei Technologies Co., Ltd
#
# 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.
# ==============================================================================
"""
Testing RgbToBgr op in DE
"""
import numpy as np
from numpy.testing import assert_allclose
import mindspore.dataset as ds
import mindspore.dataset.transforms.py_transforms
import mindspore.dataset.vision.c_transforms as vision
import mindspore.dataset.vision.py_transforms as py_vision
DATA_DIR = ["../data/dataset/test_tf_file_3_images/train-0000-of-0001.data"]
SCHEMA_DIR = "../data/dataset/test_tf_file_3_images/datasetSchema.json"
def generate_numpy_random_rgb(shape):
# Only generate floating points that are fractions like n / 256, since they
# are RGB pixels. Some low-precision floating point types in this test can't
# handle arbitrary precision floating points well.
return np.random.randint(0, 256, shape) / 255.
def test_rgb_bgr_hwc_py():
"""
Feature: RgbToBgr Op
Description: Test Python op with HWC input shape in eager mode
Expectation: Output image shape from op is verified
"""
rgb_flat = generate_numpy_random_rgb((64, 3)).astype(np.float32)
rgb_np = rgb_flat.reshape((8, 8, 3))
rgb2bgr_op = py_vision.RgbToBgr(is_hwc=True)
bgr_np_pred = rgb2bgr_op(rgb_np)
r, g, b = rgb_np[:, :, 0], rgb_np[:, :, 1], rgb_np[:, :, 2]
bgr_np_gt = np.stack((b, g, r), axis=2)
assert bgr_np_pred.shape == rgb_np.shape
assert_allclose(bgr_np_pred.flatten(),
bgr_np_gt.flatten(),
rtol=1e-5,
atol=0)
def test_rgb_bgr_hwc_c():
"""
Feature: RgbToBgr Op
Description: Test C++ op with HWC input shape in eager mode
Expectation: Output image shape from op is verified
"""
rgb_flat = generate_numpy_random_rgb((64, 3)).astype(np.float32)
rgb_np = rgb_flat.reshape((8, 8, 3))
rgb2bgr_op = vision.RgbToBgr()
bgr_np_pred = rgb2bgr_op(rgb_np)
r, g, b = rgb_np[:, :, 0], rgb_np[:, :, 1], rgb_np[:, :, 2]
bgr_np_gt = np.stack((b, g, r), axis=2)
assert bgr_np_pred.shape == rgb_np.shape
assert_allclose(bgr_np_pred.flatten(),
bgr_np_gt.flatten(),
rtol=1e-5,
atol=0)
def test_rgb_bgr_chw_py():
"""
Feature: RgbToBgr Op
Description: Test Python op in with CHW input shape eager mode
Expectation: Output image shape from op is verified
"""
rgb_flat = generate_numpy_random_rgb((64, 3)).astype(np.float32)
rgb_np = rgb_flat.reshape((3, 8, 8))
rgb2bgr_op = py_vision.RgbToBgr(is_hwc=False)
rgb_np_pred = rgb2bgr_op(rgb_np)
rgb_np_gt = rgb_np[::-1, :, :]
assert rgb_np_pred.shape == rgb_np.shape
assert_allclose(rgb_np_pred.flatten(),
rgb_np_gt.flatten(),
rtol=1e-5,
atol=0)
def test_rgb_bgr_pipeline_py():
"""
Feature: RgbToBgr Op
Description: Test Python op in dataset pipeline
Expectation: Dataset pipeline runs successfully and results are verified
"""
# First dataset
transforms1_list = [py_vision.Decode(), py_vision.Resize([64, 64]), py_vision.ToTensor()]
transforms1 = mindspore.dataset.transforms.py_transforms.Compose(
transforms1_list)
ds1 = ds.TFRecordDataset(DATA_DIR,
SCHEMA_DIR,
columns_list=["image"],
shuffle=False)
ds1 = ds1.map(operations=transforms1, input_columns=["image"])
# Second dataset
transforms2 = [
py_vision.Decode(),
py_vision.Resize([64, 64]),
py_vision.ToTensor(),
py_vision.RgbToBgr()
]
transforms2 = mindspore.dataset.transforms.py_transforms.Compose(
transforms2)
ds2 = ds.TFRecordDataset(DATA_DIR,
SCHEMA_DIR,
columns_list=["image"],
shuffle=False)
ds2 = ds2.map(operations=transforms2, input_columns=["image"])
num_iter = 0
for data1, data2 in zip(ds1.create_dict_iterator(num_epochs=1),
ds2.create_dict_iterator(num_epochs=1)):
num_iter += 1
ori_img = data1["image"].asnumpy()
cvt_img = data2["image"].asnumpy()
cvt_img_gt = ori_img[::-1, :, :]
assert_allclose(cvt_img_gt.flatten(),
cvt_img.flatten(),
rtol=1e-5,
atol=0)
assert ori_img.shape == cvt_img.shape
assert num_iter == 3
def test_rgb_bgr_pipeline_c():
"""
Feature: RgbToBgr Op
Description: Test C++ op in dataset pipeline
Expectation: Dataset pipeline runs successfully and results are verified
"""
# First dataset
transforms1 = [
# Set Decode(rbg=True) for test coverage of deprecated rgb arg
vision.Decode(rgb=True),
vision.Resize([60, 60])
]
transforms1 = mindspore.dataset.transforms.py_transforms.Compose(
transforms1)
ds1 = ds.TFRecordDataset(DATA_DIR,
SCHEMA_DIR,
columns_list=["image"],
shuffle=False)
ds1 = ds1.map(operations=transforms1, input_columns=["image"])
# Second dataset
transforms2_list = [
# Set Decode(True) for test coverage of deprecated rgb arg
vision.Decode(True),
vision.Resize([60, 60]),
vision.RgbToBgr()
]
transforms2 = mindspore.dataset.transforms.py_transforms.Compose(transforms2_list)
ds2 = ds.TFRecordDataset(DATA_DIR,
SCHEMA_DIR,
columns_list=["image"],
shuffle=False)
ds2 = ds2.map(operations=transforms2, input_columns=["image"])
for data1, data2 in zip(ds1.create_dict_iterator(num_epochs=1),
ds2.create_dict_iterator(num_epochs=1)):
ori_img = data1["image"].asnumpy()
cvt_img = data2["image"].asnumpy()
cvt_img_gt = ori_img[:, :, ::-1]
assert_allclose(cvt_img_gt.flatten(),
cvt_img.flatten(),
rtol=1e-5,
atol=0)
assert ori_img.shape == cvt_img.shape
if __name__ == "__main__":
test_rgb_bgr_hwc_py()
test_rgb_bgr_hwc_c()
test_rgb_bgr_chw_py()
test_rgb_bgr_pipeline_py()
test_rgb_bgr_pipeline_c()