From: @luoyang42 Reviewed-by: Signed-off-by:tags/v1.1.0
| @@ -17,39 +17,168 @@ | |||||
| #include "minddata/dataset/include/transforms.h" | #include "minddata/dataset/include/transforms.h" | ||||
| // Kernel data headers (in alphabetical order) | // Kernel data headers (in alphabetical order) | ||||
| #include "minddata/dataset/kernels/data/compose_op.h" | |||||
| #include "minddata/dataset/kernels/data/duplicate_op.h" | |||||
| #include "minddata/dataset/kernels/data/one_hot_op.h" | #include "minddata/dataset/kernels/data/one_hot_op.h" | ||||
| #include "minddata/dataset/kernels/data/random_apply_op.h" | |||||
| #include "minddata/dataset/kernels/data/random_choice_op.h" | |||||
| #include "minddata/dataset/kernels/data/type_cast_op.h" | #include "minddata/dataset/kernels/data/type_cast_op.h" | ||||
| #ifndef ENABLE_ANDROID | |||||
| #include "minddata/dataset/kernels/data/unique_op.h" | |||||
| #endif | |||||
| namespace mindspore { | namespace mindspore { | ||||
| namespace dataset { | namespace dataset { | ||||
| TensorOperation::TensorOperation() {} | TensorOperation::TensorOperation() {} | ||||
| /* ####################################### Validator Functions ############################################ */ | |||||
| Status ValidateVectorFillvalue(const std::string &transform_name, const std::vector<uint8_t> &fill_value) { | |||||
| if (fill_value.empty() || (fill_value.size() != 1 && fill_value.size() != 3)) { | |||||
| std::string err_msg = | |||||
| transform_name + ": fill_value vector has incorrect size: " + std::to_string(fill_value.size()); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| for (uint8_t single_fill_value : fill_value) { | |||||
| if (single_fill_value > 255) { | |||||
| std::string err_msg = | |||||
| transform_name + ": fill_value has to be between 0 and 255, got:" + std::to_string(single_fill_value); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| Status ValidateProbability(const std::string &transform_name, const float &probability) { | |||||
| if (probability < 0.0 || probability > 1.0) { | |||||
| std::string err_msg = | |||||
| transform_name + ": probability must be between 0.0 and 1.0, got: " + std::to_string(probability); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| Status ValidateVectorPadding(const std::string &transform_name, const std::vector<int32_t> &padding) { | |||||
| if (padding.empty() || padding.size() == 3 || padding.size() > 4) { | |||||
| std::string err_msg = transform_name + ": padding vector has incorrect size: " + std::to_string(padding.size()); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| for (int32_t i = 0; i < padding.size(); ++i) { | |||||
| if (padding[i] < 0) { | |||||
| std::string err_msg = | |||||
| transform_name + | |||||
| ": invalid padding, padding value must be greater than or equal to 0, got: " + std::to_string(padding[i]); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| if (padding[i] == INT_MAX) { | |||||
| std::string err_msg = | |||||
| transform_name + ": invalid padding, padding value too large, got: " + std::to_string(padding[i]); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| Status ValidateVectorPositive(const std::string &transform_name, const std::vector<int32_t> &size) { | |||||
| for (int32_t i = 0; i < size.size(); ++i) { | |||||
| if (size[i] <= 0) { | |||||
| std::string err_msg = | |||||
| transform_name + ": Non-positive size value: " + std::to_string(size[i]) + " at element: " + std::to_string(i); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| Status ValidateVectorTransforms(const std::string &transform_name, | |||||
| const std::vector<std::shared_ptr<TensorOperation>> &transforms) { | |||||
| if (transforms.empty()) { | |||||
| std::string err_msg = transform_name + ": transform list must not be empty."; | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| for (int32_t i = 0; i < transforms.size(); ++i) { | |||||
| if (transforms[i] == nullptr) { | |||||
| std::string err_msg = | |||||
| transform_name + ": transform ops must not be null, got transform[" + std::to_string(i) + "] == nullptr."; | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| bool CmpFloat(const float &a, const float &b, float epsilon) { return (std::fabs(a - b) < epsilon); } | |||||
| // Transform operations for data. | // Transform operations for data. | ||||
| namespace transforms { | namespace transforms { | ||||
| // FUNCTIONS TO CREATE DATA TRANSFORM OPERATIONS | // FUNCTIONS TO CREATE DATA TRANSFORM OPERATIONS | ||||
| // (In alphabetical order) | // (In alphabetical order) | ||||
| // Function to create ComposeOperation. | |||||
| std::shared_ptr<ComposeOperation> Compose(const std::vector<std::shared_ptr<TensorOperation>> &transforms) { | |||||
| auto op = std::make_shared<ComposeOperation>(transforms); | |||||
| // Input validation | |||||
| return op->ValidateParams() ? op : nullptr; | |||||
| } | |||||
| // Function to create DuplicateOperation. | |||||
| std::shared_ptr<DuplicateOperation> Duplicate() { | |||||
| auto op = std::make_shared<DuplicateOperation>(); | |||||
| // Input validation | |||||
| return op->ValidateParams() ? op : nullptr; | |||||
| } | |||||
| // Function to create OneHotOperation. | // Function to create OneHotOperation. | ||||
| std::shared_ptr<OneHotOperation> OneHot(int32_t num_classes) { | std::shared_ptr<OneHotOperation> OneHot(int32_t num_classes) { | ||||
| auto op = std::make_shared<OneHotOperation>(num_classes); | auto op = std::make_shared<OneHotOperation>(num_classes); | ||||
| // Input validation | // Input validation | ||||
| if (!op->ValidateParams()) { | |||||
| return nullptr; | |||||
| } | |||||
| return op; | |||||
| return op->ValidateParams() ? op : nullptr; | |||||
| } | |||||
| // Function to create RandomApplyOperation. | |||||
| std::shared_ptr<RandomApplyOperation> RandomApply(const std::vector<std::shared_ptr<TensorOperation>> &transforms, | |||||
| double prob) { | |||||
| auto op = std::make_shared<RandomApplyOperation>(transforms, prob); | |||||
| // Input validation | |||||
| return op->ValidateParams() ? op : nullptr; | |||||
| } | |||||
| // Function to create RandomChoiceOperation. | |||||
| std::shared_ptr<RandomChoiceOperation> RandomChoice(const std::vector<std::shared_ptr<TensorOperation>> &transforms) { | |||||
| auto op = std::make_shared<RandomChoiceOperation>(transforms); | |||||
| // Input validation | |||||
| return op->ValidateParams() ? op : nullptr; | |||||
| } | } | ||||
| // Function to create TypeCastOperation. | // Function to create TypeCastOperation. | ||||
| std::shared_ptr<TypeCastOperation> TypeCast(std::string data_type) { | std::shared_ptr<TypeCastOperation> TypeCast(std::string data_type) { | ||||
| auto op = std::make_shared<TypeCastOperation>(data_type); | auto op = std::make_shared<TypeCastOperation>(data_type); | ||||
| // Input validation | // Input validation | ||||
| if (!op->ValidateParams()) { | |||||
| return nullptr; | |||||
| } | |||||
| return op; | |||||
| return op->ValidateParams() ? op : nullptr; | |||||
| } | |||||
| #ifndef ENABLE_ANDROID | |||||
| // Function to create UniqueOperation. | |||||
| std::shared_ptr<UniqueOperation> Unique() { | |||||
| auto op = std::make_shared<UniqueOperation>(); | |||||
| // Input validation | |||||
| return op->ValidateParams() ? op : nullptr; | |||||
| } | } | ||||
| #endif | |||||
| /* ####################################### Validator Functions ############################################ */ | /* ####################################### Validator Functions ############################################ */ | ||||
| @@ -57,13 +186,33 @@ std::shared_ptr<TypeCastOperation> TypeCast(std::string data_type) { | |||||
| // (In alphabetical order) | // (In alphabetical order) | ||||
| // ComposeOperation | |||||
| ComposeOperation::ComposeOperation(const std::vector<std::shared_ptr<TensorOperation>> &transforms) | |||||
| : transforms_(transforms) {} | |||||
| Status ComposeOperation::ValidateParams() { | |||||
| RETURN_IF_NOT_OK(ValidateVectorTransforms("Compose", transforms_)); | |||||
| return Status::OK(); | |||||
| } | |||||
| std::shared_ptr<TensorOp> ComposeOperation::Build() { | |||||
| std::vector<std::shared_ptr<TensorOp>> tensor_ops; | |||||
| (void)std::transform(transforms_.begin(), transforms_.end(), std::back_inserter(tensor_ops), | |||||
| [](std::shared_ptr<TensorOperation> op) -> std::shared_ptr<TensorOp> { return op->Build(); }); | |||||
| return std::make_shared<ComposeOp>(tensor_ops); | |||||
| } | |||||
| // DuplicateOperation | |||||
| Status DuplicateOperation::ValidateParams() { return Status::OK(); } | |||||
| std::shared_ptr<TensorOp> DuplicateOperation::Build() { return std::make_shared<DuplicateOp>(); } | |||||
| // OneHotOperation | // OneHotOperation | ||||
| OneHotOperation::OneHotOperation(int32_t num_classes) : num_classes_(num_classes) {} | OneHotOperation::OneHotOperation(int32_t num_classes) : num_classes_(num_classes) {} | ||||
| Status OneHotOperation::ValidateParams() { | Status OneHotOperation::ValidateParams() { | ||||
| if (num_classes_ <= 0) { | if (num_classes_ <= 0) { | ||||
| std::string err_msg = | |||||
| "OneHot: Number of classes must be greater than 0. num_classes: " + std::to_string(num_classes_); | |||||
| std::string err_msg = "OneHot: Number of classes must be greater than 0, but got: " + std::to_string(num_classes_); | |||||
| MS_LOG(ERROR) << err_msg; | MS_LOG(ERROR) << err_msg; | ||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | RETURN_STATUS_SYNTAX_ERROR(err_msg); | ||||
| } | } | ||||
| @@ -73,6 +222,39 @@ Status OneHotOperation::ValidateParams() { | |||||
| std::shared_ptr<TensorOp> OneHotOperation::Build() { return std::make_shared<OneHotOp>(num_classes_); } | std::shared_ptr<TensorOp> OneHotOperation::Build() { return std::make_shared<OneHotOp>(num_classes_); } | ||||
| // RandomApplyOperation | |||||
| RandomApplyOperation::RandomApplyOperation(const std::vector<std::shared_ptr<TensorOperation>> &transforms, double prob) | |||||
| : transforms_(transforms), prob_(prob) {} | |||||
| Status RandomApplyOperation::ValidateParams() { | |||||
| RETURN_IF_NOT_OK(ValidateVectorTransforms("RandomApply", transforms_)); | |||||
| RETURN_IF_NOT_OK(ValidateProbability("RandomApply", prob_)); | |||||
| return Status::OK(); | |||||
| } | |||||
| std::shared_ptr<TensorOp> RandomApplyOperation::Build() { | |||||
| std::vector<std::shared_ptr<TensorOp>> tensor_ops; | |||||
| (void)std::transform(transforms_.begin(), transforms_.end(), std::back_inserter(tensor_ops), | |||||
| [](std::shared_ptr<TensorOperation> op) -> std::shared_ptr<TensorOp> { return op->Build(); }); | |||||
| return std::make_shared<RandomApplyOp>(prob_, tensor_ops); | |||||
| } | |||||
| // RandomChoiceOperation | |||||
| RandomChoiceOperation::RandomChoiceOperation(const std::vector<std::shared_ptr<TensorOperation>> &transforms) | |||||
| : transforms_(transforms) {} | |||||
| Status RandomChoiceOperation::ValidateParams() { | |||||
| RETURN_IF_NOT_OK(ValidateVectorTransforms("RandomChoice", transforms_)); | |||||
| return Status::OK(); | |||||
| } | |||||
| std::shared_ptr<TensorOp> RandomChoiceOperation::Build() { | |||||
| std::vector<std::shared_ptr<TensorOp>> tensor_ops; | |||||
| (void)std::transform(transforms_.begin(), transforms_.end(), std::back_inserter(tensor_ops), | |||||
| [](std::shared_ptr<TensorOperation> op) -> std::shared_ptr<TensorOp> { return op->Build(); }); | |||||
| return std::make_shared<RandomChoiceOp>(tensor_ops); | |||||
| } | |||||
| // TypeCastOperation | // TypeCastOperation | ||||
| TypeCastOperation::TypeCastOperation(std::string data_type) : data_type_(data_type) {} | TypeCastOperation::TypeCastOperation(std::string data_type) : data_type_(data_type) {} | ||||
| @@ -83,7 +265,7 @@ Status TypeCastOperation::ValidateParams() { | |||||
| if (itr == predefine_type.end()) { | if (itr == predefine_type.end()) { | ||||
| std::string err_msg = "TypeCast: Invalid data type: " + data_type_; | std::string err_msg = "TypeCast: Invalid data type: " + data_type_; | ||||
| MS_LOG(ERROR) << "TypeCast: Only supports data type bool, int8, uint8, int16, uint16, int32, uint32, " | MS_LOG(ERROR) << "TypeCast: Only supports data type bool, int8, uint8, int16, uint16, int32, uint32, " | ||||
| << "int64, uint64, float16, float32, float64, string, but got " << data_type_; | |||||
| << "int64, uint64, float16, float32, float64, string, but got: " << data_type_; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | RETURN_STATUS_SYNTAX_ERROR(err_msg); | ||||
| } | } | ||||
| @@ -92,6 +274,13 @@ Status TypeCastOperation::ValidateParams() { | |||||
| std::shared_ptr<TensorOp> TypeCastOperation::Build() { return std::make_shared<TypeCastOp>(data_type_); } | std::shared_ptr<TensorOp> TypeCastOperation::Build() { return std::make_shared<TypeCastOp>(data_type_); } | ||||
| #ifndef ENABLE_ANDROID | |||||
| // UniqueOperation | |||||
| Status UniqueOperation::ValidateParams() { return Status::OK(); } | |||||
| std::shared_ptr<TensorOp> UniqueOperation::Build() { return std::make_shared<UniqueOp>(); } | |||||
| #endif | |||||
| } // namespace transforms | } // namespace transforms | ||||
| } // namespace dataset | } // namespace dataset | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -394,77 +394,7 @@ std::shared_ptr<UniformAugOperation> UniformAugment(std::vector<std::shared_ptr< | |||||
| // Input validation | // Input validation | ||||
| return op->ValidateParams() ? op : nullptr; | return op->ValidateParams() ? op : nullptr; | ||||
| } | } | ||||
| #endif | #endif | ||||
| /* ####################################### Validator Functions ############################################ */ | |||||
| Status ValidateVectorFillvalue(const std::string &dataset_name, const std::vector<uint8_t> &fill_value) { | |||||
| if (fill_value.empty() || (fill_value.size() != 1 && fill_value.size() != 3)) { | |||||
| std::string err_msg = dataset_name + ": fill_value vector has incorrect size: " + std::to_string(fill_value.size()); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| for (uint8_t single_fill_value : fill_value) { | |||||
| if (single_fill_value > 255) { | |||||
| std::string err_msg = | |||||
| dataset_name + ": fill_value has to be between 0 and 255, got:" + std::to_string(single_fill_value); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| Status ValidateVectorProbability(const std::string &dataset_name, const float &probability) { | |||||
| if (probability < 0.0 || probability > 1.0) { | |||||
| std::string err_msg = | |||||
| dataset_name + ": probability must be between 0.0 and 1.0, got: " + std::to_string(probability); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| Status ValidateVectorPadding(const std::string &dataset_name, const std::vector<int32_t> &padding) { | |||||
| if (padding.empty() || padding.size() == 3 || padding.size() > 4) { | |||||
| std::string err_msg = dataset_name + ": padding vector has incorrect size: " + std::to_string(padding.size()); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| for (int32_t i = 0; i < padding.size(); ++i) { | |||||
| if (padding[i] < 0) { | |||||
| std::string err_msg = | |||||
| dataset_name + | |||||
| ": invalid padding, padding value must be greater than or equal to 0, got: " + std::to_string(padding[i]); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| if (padding[i] == INT_MAX) { | |||||
| std::string err_msg = | |||||
| dataset_name + ": invalid padding, padding value too large, got: " + std::to_string(padding[i]); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| Status ValidateVectorPositive(const std::string &dataset_name, const std::vector<int32_t> &size) { | |||||
| for (int32_t i = 0; i < size.size(); ++i) { | |||||
| if (size[i] <= 0) { | |||||
| std::string err_msg = | |||||
| dataset_name + ": Non-positive size value: " + std::to_string(size[i]) + " at element: " + std::to_string(i); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| return Status::OK(); | |||||
| } | |||||
| bool CmpFloat(const float &a, const float &b, float epsilon = 0.0000000001f) { return (std::fabs(a - b) < epsilon); } | |||||
| /* ####################################### Derived TensorOperation classes ################################# */ | /* ####################################### Derived TensorOperation classes ################################# */ | ||||
| @@ -503,17 +433,8 @@ BoundingBoxAugmentOperation::BoundingBoxAugmentOperation(std::shared_ptr<TensorO | |||||
| : transform_(transform), ratio_(ratio) {} | : transform_(transform), ratio_(ratio) {} | ||||
| Status BoundingBoxAugmentOperation::ValidateParams() { | Status BoundingBoxAugmentOperation::ValidateParams() { | ||||
| if (transform_ == nullptr) { | |||||
| std::string err_msg = "BoundingBoxAugment: transform must not be null."; | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| if (ratio_ < 0.0 || ratio_ > 1.0) { | |||||
| std::string err_msg = "BoundingBoxAugment: ratio has to be between 0.0 and 1.0, got: " + std::to_string(ratio_); | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| RETURN_IF_NOT_OK(ValidateVectorTransforms("BoundingBoxAugment", {transform_})); | |||||
| RETURN_IF_NOT_OK(ValidateProbability("BoundingBoxAugment", ratio_)); | |||||
| return Status::OK(); | return Status::OK(); | ||||
| } | } | ||||
| @@ -1315,7 +1236,7 @@ std::shared_ptr<TensorOp> RandomCropWithBBoxOperation::Build() { | |||||
| RandomHorizontalFlipOperation::RandomHorizontalFlipOperation(float probability) : probability_(probability) {} | RandomHorizontalFlipOperation::RandomHorizontalFlipOperation(float probability) : probability_(probability) {} | ||||
| Status RandomHorizontalFlipOperation::ValidateParams() { | Status RandomHorizontalFlipOperation::ValidateParams() { | ||||
| RETURN_IF_NOT_OK(ValidateVectorProbability("RandomHorizontalFlip", probability_)); | |||||
| RETURN_IF_NOT_OK(ValidateProbability("RandomHorizontalFlip", probability_)); | |||||
| return Status::OK(); | return Status::OK(); | ||||
| } | } | ||||
| @@ -1330,7 +1251,7 @@ RandomHorizontalFlipWithBBoxOperation::RandomHorizontalFlipWithBBoxOperation(flo | |||||
| : probability_(probability) {} | : probability_(probability) {} | ||||
| Status RandomHorizontalFlipWithBBoxOperation::ValidateParams() { | Status RandomHorizontalFlipWithBBoxOperation::ValidateParams() { | ||||
| RETURN_IF_NOT_OK(ValidateVectorProbability("RandomHorizontalFlipWithBBox", probability_)); | |||||
| RETURN_IF_NOT_OK(ValidateProbability("RandomHorizontalFlipWithBBox", probability_)); | |||||
| return Status::OK(); | return Status::OK(); | ||||
| } | } | ||||
| @@ -1696,7 +1617,7 @@ std::shared_ptr<TensorOp> RandomSolarizeOperation::Build() { | |||||
| RandomVerticalFlipOperation::RandomVerticalFlipOperation(float probability) : probability_(probability) {} | RandomVerticalFlipOperation::RandomVerticalFlipOperation(float probability) : probability_(probability) {} | ||||
| Status RandomVerticalFlipOperation::ValidateParams() { | Status RandomVerticalFlipOperation::ValidateParams() { | ||||
| RETURN_IF_NOT_OK(ValidateVectorProbability("RandomVerticalFlip", probability_)); | |||||
| RETURN_IF_NOT_OK(ValidateProbability("RandomVerticalFlip", probability_)); | |||||
| return Status::OK(); | return Status::OK(); | ||||
| } | } | ||||
| @@ -1711,7 +1632,7 @@ RandomVerticalFlipWithBBoxOperation::RandomVerticalFlipWithBBoxOperation(float p | |||||
| : probability_(probability) {} | : probability_(probability) {} | ||||
| Status RandomVerticalFlipWithBBoxOperation::ValidateParams() { | Status RandomVerticalFlipWithBBoxOperation::ValidateParams() { | ||||
| RETURN_IF_NOT_OK(ValidateVectorProbability("RandomVerticalFlipWithBBox", probability_)); | |||||
| RETURN_IF_NOT_OK(ValidateProbability("RandomVerticalFlipWithBBox", probability_)); | |||||
| return Status::OK(); | return Status::OK(); | ||||
| } | } | ||||
| @@ -1945,21 +1866,15 @@ UniformAugOperation::UniformAugOperation(std::vector<std::shared_ptr<TensorOpera | |||||
| Status UniformAugOperation::ValidateParams() { | Status UniformAugOperation::ValidateParams() { | ||||
| // transforms | // transforms | ||||
| RETURN_IF_NOT_OK(ValidateVectorTransforms("UniformAug", transforms_)); | |||||
| if (num_ops_ > transforms_.size()) { | if (num_ops_ > transforms_.size()) { | ||||
| std::string err_msg = "UniformAug: num_ops is greater than transforms size, num_ops: " + std::to_string(num_ops_); | |||||
| std::string err_msg = "UniformAug: num_ops is greater than transforms size, but got: " + std::to_string(num_ops_); | |||||
| MS_LOG(ERROR) << err_msg; | MS_LOG(ERROR) << err_msg; | ||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | RETURN_STATUS_SYNTAX_ERROR(err_msg); | ||||
| } | } | ||||
| for (int32_t i = 0; i < transforms_.size(); ++i) { | |||||
| if (transforms_[i] == nullptr) { | |||||
| std::string err_msg = "UniformAug: transform ops must not be null."; | |||||
| MS_LOG(ERROR) << err_msg; | |||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | |||||
| } | |||||
| } | |||||
| // num_ops | // num_ops | ||||
| if (num_ops_ <= 0) { | if (num_ops_ <= 0) { | ||||
| std::string err_msg = "UniformAug: num_ops must be greater than 0, num_ops: " + std::to_string(num_ops_); | |||||
| std::string err_msg = "UniformAug: num_ops must be greater than 0, but got: " + std::to_string(num_ops_); | |||||
| MS_LOG(ERROR) << err_msg; | MS_LOG(ERROR) << err_msg; | ||||
| RETURN_STATUS_SYNTAX_ERROR(err_msg); | RETURN_STATUS_SYNTAX_ERROR(err_msg); | ||||
| } | } | ||||
| @@ -44,12 +44,50 @@ class TensorOperation : public std::enable_shared_from_this<TensorOperation> { | |||||
| virtual Status ValidateParams() = 0; | virtual Status ValidateParams() = 0; | ||||
| }; | }; | ||||
| // Helper function to validate fill value | |||||
| Status ValidateVectorFillvalue(const std::string &transform_name, const std::vector<uint8_t> &fill_value); | |||||
| // Helper function to validate probability | |||||
| Status ValidateProbability(const std::string &transform_name, const float &probability); | |||||
| // Helper function to validate padding | |||||
| Status ValidateVectorPadding(const std::string &transform_name, const std::vector<int32_t> &padding); | |||||
| // Helper function to validate size | |||||
| Status ValidateVectorPositive(const std::string &transform_name, const std::vector<int32_t> &size); | |||||
| // Helper function to validate transforms | |||||
| Status ValidateVectorTransforms(const std::string &transform_name, | |||||
| const std::vector<std::shared_ptr<TensorOperation>> &transforms); | |||||
| // Helper function to compare float value | |||||
| bool CmpFloat(const float &a, const float &b, float epsilon = 0.0000000001f); | |||||
| // Transform operations for performing data transformation. | // Transform operations for performing data transformation. | ||||
| namespace transforms { | namespace transforms { | ||||
| // Transform Op classes (in alphabetical order) | // Transform Op classes (in alphabetical order) | ||||
| class ComposeOperation; | |||||
| class DuplicateOperation; | |||||
| class OneHotOperation; | class OneHotOperation; | ||||
| class RandomApplyOperation; | |||||
| class RandomChoiceOperation; | |||||
| class TypeCastOperation; | class TypeCastOperation; | ||||
| #ifndef ENABLE_ANDROID | |||||
| class UniqueOperation; | |||||
| #endif | |||||
| /// \brief Function to create a Compose TensorOperation. | |||||
| /// \notes Compose a list of transforms into a single transform. | |||||
| /// \param[in] transforms A vector of transformations to be applied. | |||||
| /// \return Shared pointer to the current TensorOperation. | |||||
| std::shared_ptr<ComposeOperation> Compose(const std::vector<std::shared_ptr<TensorOperation>> &transforms); | |||||
| /// \brief Function to create a Duplicate TensorOperation. | |||||
| /// \notes Duplicate the input tensor to a new output tensor. | |||||
| /// The input tensor is carried over to the output list. | |||||
| /// \return Shared pointer to the current TensorOperation. | |||||
| std::shared_ptr<DuplicateOperation> Duplicate(); | |||||
| /// \brief Function to create a OneHot TensorOperation. | /// \brief Function to create a OneHot TensorOperation. | ||||
| /// \notes Convert the labels into OneHot format. | /// \notes Convert the labels into OneHot format. | ||||
| @@ -57,14 +95,61 @@ class TypeCastOperation; | |||||
| /// \return Shared pointer to the current TensorOperation. | /// \return Shared pointer to the current TensorOperation. | ||||
| std::shared_ptr<OneHotOperation> OneHot(int32_t num_classes); | std::shared_ptr<OneHotOperation> OneHot(int32_t num_classes); | ||||
| /// \brief Function to create a RandomApply TensorOperation. | |||||
| /// \notes Randomly perform a series of transforms with a given probability. | |||||
| /// \param[in] transforms A vector of transformations to be applied. | |||||
| /// \param[in] prob The probability to apply the transformation list (default=0.5) | |||||
| /// \return Shared pointer to the current TensorOperation. | |||||
| std::shared_ptr<RandomApplyOperation> RandomApply(const std::vector<std::shared_ptr<TensorOperation>> &transforms, | |||||
| double prob = 0.5); | |||||
| /// \brief Function to create a RandomChoice TensorOperation. | |||||
| /// \notes Randomly selects one transform from a list of transforms to perform operation. | |||||
| /// \param[in] transforms A vector of transformations to be chosen from to apply. | |||||
| /// \return Shared pointer to the current TensorOperation. | |||||
| std::shared_ptr<RandomChoiceOperation> RandomChoice(const std::vector<std::shared_ptr<TensorOperation>> &transforms); | |||||
| /// \brief Function to create a TypeCast TensorOperation. | /// \brief Function to create a TypeCast TensorOperation. | ||||
| /// \notes Tensor operation to cast to a given MindSpore data type. | /// \notes Tensor operation to cast to a given MindSpore data type. | ||||
| /// \param[in] data_type mindspore.dtype to be cast to. | /// \param[in] data_type mindspore.dtype to be cast to. | ||||
| /// \return Shared pointer to the current TensorOperation. | /// \return Shared pointer to the current TensorOperation. | ||||
| std::shared_ptr<TypeCastOperation> TypeCast(std::string data_type); | std::shared_ptr<TypeCastOperation> TypeCast(std::string data_type); | ||||
| #ifndef ENABLE_ANDROID | |||||
| /// \brief Function to create a Unique TensorOperation. | |||||
| /// \notes Return an output tensor containing all the unique elements of the input tensor in | |||||
| /// the same order that they occur in the input tensor. | |||||
| /// \return Shared pointer to the current TensorOperation. | |||||
| std::shared_ptr<UniqueOperation> Unique(); | |||||
| #endif | |||||
| /* ####################################### Derived TensorOperation classes ################################# */ | /* ####################################### Derived TensorOperation classes ################################# */ | ||||
| class ComposeOperation : public TensorOperation { | |||||
| public: | |||||
| explicit ComposeOperation(const std::vector<std::shared_ptr<TensorOperation>> &transforms); | |||||
| ~ComposeOperation() = default; | |||||
| std::shared_ptr<TensorOp> Build() override; | |||||
| Status ValidateParams() override; | |||||
| private: | |||||
| std::vector<std::shared_ptr<TensorOperation>> transforms_; | |||||
| }; | |||||
| class DuplicateOperation : public TensorOperation { | |||||
| public: | |||||
| DuplicateOperation() = default; | |||||
| ~DuplicateOperation() = default; | |||||
| std::shared_ptr<TensorOp> Build() override; | |||||
| Status ValidateParams() override; | |||||
| }; | |||||
| class OneHotOperation : public TensorOperation { | class OneHotOperation : public TensorOperation { | ||||
| public: | public: | ||||
| explicit OneHotOperation(int32_t num_classes_); | explicit OneHotOperation(int32_t num_classes_); | ||||
| @@ -79,6 +164,35 @@ class OneHotOperation : public TensorOperation { | |||||
| float num_classes_; | float num_classes_; | ||||
| }; | }; | ||||
| class RandomApplyOperation : public TensorOperation { | |||||
| public: | |||||
| explicit RandomApplyOperation(const std::vector<std::shared_ptr<TensorOperation>> &transforms, double prob); | |||||
| ~RandomApplyOperation() = default; | |||||
| std::shared_ptr<TensorOp> Build() override; | |||||
| Status ValidateParams() override; | |||||
| private: | |||||
| std::vector<std::shared_ptr<TensorOperation>> transforms_; | |||||
| double prob_; | |||||
| }; | |||||
| class RandomChoiceOperation : public TensorOperation { | |||||
| public: | |||||
| explicit RandomChoiceOperation(const std::vector<std::shared_ptr<TensorOperation>> &transforms); | |||||
| ~RandomChoiceOperation() = default; | |||||
| std::shared_ptr<TensorOp> Build() override; | |||||
| Status ValidateParams() override; | |||||
| private: | |||||
| std::vector<std::shared_ptr<TensorOperation>> transforms_; | |||||
| }; | |||||
| class TypeCastOperation : public TensorOperation { | class TypeCastOperation : public TensorOperation { | ||||
| public: | public: | ||||
| explicit TypeCastOperation(std::string data_type); | explicit TypeCastOperation(std::string data_type); | ||||
| @@ -92,6 +206,19 @@ class TypeCastOperation : public TensorOperation { | |||||
| private: | private: | ||||
| std::string data_type_; | std::string data_type_; | ||||
| }; | }; | ||||
| #ifndef ENABLE_ANDROID | |||||
| class UniqueOperation : public TensorOperation { | |||||
| public: | |||||
| UniqueOperation() = default; | |||||
| ~UniqueOperation() = default; | |||||
| std::shared_ptr<TensorOp> Build() override; | |||||
| Status ValidateParams() override; | |||||
| }; | |||||
| #endif | |||||
| } // namespace transforms | } // namespace transforms | ||||
| } // namespace dataset | } // namespace dataset | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -28,6 +28,107 @@ class MindDataTestPipeline : public UT::DatasetOpTesting { | |||||
| // Tests for data transforms ops (in alphabetical order) | // Tests for data transforms ops (in alphabetical order) | ||||
| TEST_F(MindDataTestPipeline, TestComposeSuccess) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestComposeSuccess."; | |||||
| // Create an ImageFolder Dataset | |||||
| std::string folder_path = datasets_root_path_ + "/testPK/data/"; | |||||
| std::shared_ptr<Dataset> ds = ImageFolder(folder_path, false, RandomSampler(false, 3)); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create objects for the tensor ops | |||||
| std::shared_ptr<TensorOperation> compose = transforms::Compose({vision::Decode(), vision::Resize({777, 777})}); | |||||
| EXPECT_NE(compose, nullptr); | |||||
| // Create a Map operation on ds | |||||
| ds = ds->Map({compose}, {"image"}); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create an iterator over the result of the above dataset | |||||
| // This will trigger the creation of the Execution Tree and launch it. | |||||
| std::shared_ptr<Iterator> iter = ds->CreateIterator(); | |||||
| EXPECT_NE(iter, nullptr); | |||||
| // Iterate the dataset and get each row | |||||
| std::unordered_map<std::string, std::shared_ptr<Tensor>> row; | |||||
| iter->GetNextRow(&row); | |||||
| uint64_t i = 0; | |||||
| while (row.size() != 0) { | |||||
| i++; | |||||
| auto image = row["image"]; | |||||
| auto label = row["label"]; | |||||
| MS_LOG(INFO) << "Tensor image shape: " << image->shape(); | |||||
| MS_LOG(INFO) << "Label shape: " << label->shape(); | |||||
| EXPECT_EQ(image->shape()[0], 777); | |||||
| EXPECT_EQ(image->shape()[1], 777); | |||||
| iter->GetNextRow(&row); | |||||
| } | |||||
| EXPECT_EQ(i, 3); | |||||
| // Manually terminate the pipeline | |||||
| iter->Stop(); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestComposeFail) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestComposeFail with invalid transform."; | |||||
| // Resize: Non-positive size value: -1 at element: 0 | |||||
| // Compose: transform ops must not be null | |||||
| std::shared_ptr<TensorOperation> compose1 = transforms::Compose({vision::Decode(), vision::Resize({-1})}); | |||||
| EXPECT_EQ(compose1, nullptr); | |||||
| // Compose: transform ops must not be null | |||||
| std::shared_ptr<TensorOperation> compose2 = transforms::Compose({vision::Decode(), nullptr}); | |||||
| EXPECT_EQ(compose2, nullptr); | |||||
| // Compose: transform list must not be empty | |||||
| std::shared_ptr<TensorOperation> compose3 = transforms::Compose({}); | |||||
| EXPECT_EQ(compose3, nullptr); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestDuplicateSuccess) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestDuplicateSuccess."; | |||||
| // Create a Cifar10 Dataset | |||||
| std::string folder_path = datasets_root_path_ + "/testCifar10Data/"; | |||||
| std::shared_ptr<Dataset> ds = Cifar10(folder_path, "all", RandomSampler(false, 10)); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create objects for the tensor ops | |||||
| std::shared_ptr<TensorOperation> duplicate = transforms::Duplicate(); | |||||
| EXPECT_NE(duplicate, nullptr); | |||||
| // Create a Map operation on ds | |||||
| ds = ds->Map({duplicate}, {"image"}, {"image", "image_copy"}); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create an iterator over the result of the above dataset | |||||
| // This will trigger the creation of the Execution Tree and launch it. | |||||
| std::shared_ptr<Iterator> iter = ds->CreateIterator(); | |||||
| EXPECT_NE(iter, nullptr); | |||||
| // Iterate the dataset and get each row | |||||
| std::unordered_map<std::string, std::shared_ptr<Tensor>> row; | |||||
| iter->GetNextRow(&row); | |||||
| uint64_t i = 0; | |||||
| while (row.size() != 0) { | |||||
| i++; | |||||
| auto image = row["image"]; | |||||
| auto image_copy = row["image_copy"]; | |||||
| MS_LOG(INFO) << "Tensor image shape: " << image->shape(); | |||||
| EXPECT_EQ(*image, *image_copy); | |||||
| iter->GetNextRow(&row); | |||||
| } | |||||
| EXPECT_EQ(i, 10); | |||||
| // Manually terminate the pipeline | |||||
| iter->Stop(); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestOneHotSuccess1) { | TEST_F(MindDataTestPipeline, TestOneHotSuccess1) { | ||||
| // Testing CutMixBatch on a batch of CHW images | // Testing CutMixBatch on a batch of CHW images | ||||
| // Create a Cifar10 Dataset | // Create a Cifar10 Dataset | ||||
| @@ -157,6 +258,127 @@ TEST_F(MindDataTestPipeline, TestOneHotFail) { | |||||
| EXPECT_EQ(one_hot_op2, nullptr); | EXPECT_EQ(one_hot_op2, nullptr); | ||||
| } | } | ||||
| TEST_F(MindDataTestPipeline, TestRandomApplySuccess) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomApplySuccess."; | |||||
| // Create an ImageFolder Dataset | |||||
| std::string folder_path = datasets_root_path_ + "/testPK/data/"; | |||||
| std::shared_ptr<Dataset> ds = ImageFolder(folder_path, true, RandomSampler(false, 5)); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create objects for the tensor ops | |||||
| std::shared_ptr<TensorOperation> random_apply = transforms::RandomApply({vision::Resize({777, 777})}, 0.8); | |||||
| EXPECT_NE(random_apply, nullptr); | |||||
| // Create a Map operation on ds | |||||
| ds = ds->Map({random_apply}, {"image"}); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create an iterator over the result of the above dataset | |||||
| // This will trigger the creation of the Execution Tree and launch it. | |||||
| std::shared_ptr<Iterator> iter = ds->CreateIterator(); | |||||
| EXPECT_NE(iter, nullptr); | |||||
| // Iterate the dataset and get each row | |||||
| std::unordered_map<std::string, std::shared_ptr<Tensor>> row; | |||||
| iter->GetNextRow(&row); | |||||
| uint64_t i = 0; | |||||
| while (row.size() != 0) { | |||||
| i++; | |||||
| auto image = row["image"]; | |||||
| auto label = row["label"]; | |||||
| MS_LOG(INFO) << "Tensor image shape: " << image->shape(); | |||||
| MS_LOG(INFO) << "Label shape: " << label->shape(); | |||||
| iter->GetNextRow(&row); | |||||
| } | |||||
| EXPECT_EQ(i, 5); | |||||
| // Manually terminate the pipeline | |||||
| iter->Stop(); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestRandomApplyFail) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomApplyFail with invalid transform."; | |||||
| // Resize: Non-positive size value: -1 at element: 0 | |||||
| // RandomApply: transform ops must not be null | |||||
| std::shared_ptr<TensorOperation> random_apply1 = transforms::RandomApply({vision::Decode(), vision::Resize({-1})}); | |||||
| EXPECT_EQ(random_apply1, nullptr); | |||||
| // RandomApply: transform ops must not be null | |||||
| std::shared_ptr<TensorOperation> random_apply2 = transforms::RandomApply({vision::Decode(), nullptr}); | |||||
| EXPECT_EQ(random_apply2, nullptr); | |||||
| // RandomApply: transform list must not be empty | |||||
| std::shared_ptr<TensorOperation> random_apply3 = transforms::RandomApply({}); | |||||
| EXPECT_EQ(random_apply3, nullptr); | |||||
| // RandomApply: Probability has to be between 0 and 1 | |||||
| std::shared_ptr<TensorOperation> random_apply4 = transforms::RandomApply({vision::Resize({100})}, -1); | |||||
| EXPECT_EQ(random_apply4, nullptr); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestRandomChoiceSuccess) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomChoiceSuccess."; | |||||
| // Create an ImageFolder Dataset | |||||
| std::string folder_path = datasets_root_path_ + "/testPK/data/"; | |||||
| std::shared_ptr<Dataset> ds = ImageFolder(folder_path, true, RandomSampler(false, 3)); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create objects for the tensor ops | |||||
| std::shared_ptr<TensorOperation> random_choice = | |||||
| transforms::RandomChoice({vision::Resize({777, 777}), vision::Resize({888, 888})}); | |||||
| EXPECT_NE(random_choice, nullptr); | |||||
| // Create a Map operation on ds | |||||
| ds = ds->Map({random_choice}, {"image"}); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // Create an iterator over the result of the above dataset | |||||
| // This will trigger the creation of the Execution Tree and launch it. | |||||
| std::shared_ptr<Iterator> iter = ds->CreateIterator(); | |||||
| EXPECT_NE(iter, nullptr); | |||||
| // Iterate the dataset and get each row | |||||
| std::unordered_map<std::string, std::shared_ptr<Tensor>> row; | |||||
| iter->GetNextRow(&row); | |||||
| uint64_t i = 0; | |||||
| while (row.size() != 0) { | |||||
| i++; | |||||
| auto image = row["image"]; | |||||
| auto label = row["label"]; | |||||
| MS_LOG(INFO) << "Tensor image shape: " << image->shape(); | |||||
| MS_LOG(INFO) << "Label shape: " << label->shape(); | |||||
| iter->GetNextRow(&row); | |||||
| } | |||||
| EXPECT_EQ(i, 3); | |||||
| // Manually terminate the pipeline | |||||
| iter->Stop(); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestRandomChoiceFail) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestRandomChoiceFail with invalid transform."; | |||||
| // Resize: Non-positive size value: -1 at element: 0 | |||||
| // RandomChoice: transform ops must not be null | |||||
| std::shared_ptr<TensorOperation> random_choice1 = transforms::RandomChoice({vision::Decode(), vision::Resize({-1})}); | |||||
| EXPECT_EQ(random_choice1, nullptr); | |||||
| // RandomChoice: transform ops must not be null | |||||
| std::shared_ptr<TensorOperation> random_choice2 = transforms::RandomChoice({vision::Decode(), nullptr}); | |||||
| EXPECT_EQ(random_choice2, nullptr); | |||||
| // RandomChoice: transform list must not be empty | |||||
| std::shared_ptr<TensorOperation> random_choice3 = transforms::RandomChoice({}); | |||||
| EXPECT_EQ(random_choice3, nullptr); | |||||
| } | |||||
| TEST_F(MindDataTestPipeline, TestTypeCastSuccess) { | TEST_F(MindDataTestPipeline, TestTypeCastSuccess) { | ||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestTypeCastSuccess."; | MS_LOG(INFO) << "Doing MindDataTestPipeline-TestTypeCastSuccess."; | ||||
| @@ -2799,14 +2799,8 @@ TEST_F(MindDataTestPipeline, TestSoftDvppDecodeResizeJpegFail) { | |||||
| EXPECT_EQ(soft_dvpp_decode_resize_jpeg_op4, nullptr); | EXPECT_EQ(soft_dvpp_decode_resize_jpeg_op4, nullptr); | ||||
| } | } | ||||
| TEST_F(MindDataTestPipeline, DISABLED_TestUniformAugmentFail1) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestUniformAugmentFail1 with invalid zero num_ops parameter."; | |||||
| // Create a Mnist Dataset | |||||
| std::string folder_path = datasets_root_path_ + "/testMnistData/"; | |||||
| std::shared_ptr<Dataset> ds = Mnist(folder_path, "all", RandomSampler(false, 20)); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| TEST_F(MindDataTestPipeline, TestUniformAugmentFail1) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestUniformAugmentFail1 with invalid num_ops parameter."; | |||||
| // Create objects for the tensor ops | // Create objects for the tensor ops | ||||
| std::shared_ptr<TensorOperation> random_crop_op = vision::RandomCrop({28, 28}); | std::shared_ptr<TensorOperation> random_crop_op = vision::RandomCrop({28, 28}); | ||||
| EXPECT_NE(random_crop_op, nullptr); | EXPECT_NE(random_crop_op, nullptr); | ||||
| @@ -2814,29 +2808,33 @@ TEST_F(MindDataTestPipeline, DISABLED_TestUniformAugmentFail1) { | |||||
| std::shared_ptr<TensorOperation> center_crop_op = vision::CenterCrop({16, 16}); | std::shared_ptr<TensorOperation> center_crop_op = vision::CenterCrop({16, 16}); | ||||
| EXPECT_NE(center_crop_op, nullptr); | EXPECT_NE(center_crop_op, nullptr); | ||||
| // Try UniformAugment with invalid zero num_ops value | |||||
| std::shared_ptr<TensorOperation> uniform_aug_op = vision::UniformAugment({random_crop_op, center_crop_op}, 0); | |||||
| EXPECT_EQ(uniform_aug_op, nullptr); | |||||
| } | |||||
| // UniformAug: num_ops must be greater than 0 | |||||
| std::shared_ptr<TensorOperation> uniform_aug_op1 = vision::UniformAugment({random_crop_op, center_crop_op}, 0); | |||||
| EXPECT_EQ(uniform_aug_op1, nullptr); | |||||
| TEST_F(MindDataTestPipeline, DISABLED_TestUniformAugmentFail2) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestUniformAugmentFail2 with invalid negative num_ops parameter."; | |||||
| // UniformAug: num_ops must be greater than 0 | |||||
| std::shared_ptr<TensorOperation> uniform_aug_op2 = vision::UniformAugment({random_crop_op, center_crop_op}, -1); | |||||
| EXPECT_EQ(uniform_aug_op2, nullptr); | |||||
| // Create a Mnist Dataset | |||||
| std::string folder_path = datasets_root_path_ + "/testMnistData/"; | |||||
| std::shared_ptr<Dataset> ds = Mnist(folder_path, "all", RandomSampler(false, 20)); | |||||
| EXPECT_NE(ds, nullptr); | |||||
| // UniformAug: num_ops is greater than transforms size | |||||
| std::shared_ptr<TensorOperation> uniform_aug_op3 = vision::UniformAugment({random_crop_op, center_crop_op}, 3); | |||||
| EXPECT_EQ(uniform_aug_op3, nullptr); | |||||
| } | |||||
| // Create objects for the tensor ops | |||||
| std::shared_ptr<TensorOperation> random_crop_op = vision::RandomCrop({28, 28}); | |||||
| EXPECT_NE(random_crop_op, nullptr); | |||||
| TEST_F(MindDataTestPipeline, TestUniformAugmentFail2) { | |||||
| MS_LOG(INFO) << "Doing MindDataTestPipeline-TestUniformAugmentFail2 with invalid transform."; | |||||
| std::shared_ptr<TensorOperation> center_crop_op = vision::CenterCrop({16, 16}); | |||||
| EXPECT_NE(center_crop_op, nullptr); | |||||
| // UniformAug: transform ops must not be null | |||||
| std::shared_ptr<TensorOperation> uniform_aug_op1 = vision::UniformAugment({vision::RandomCrop({-28})}, 1); | |||||
| EXPECT_EQ(uniform_aug_op1, nullptr); | |||||
| // UniformAug: transform ops must not be null | |||||
| std::shared_ptr<TensorOperation> uniform_aug_op2 = vision::UniformAugment({vision::RandomCrop({28}), nullptr}, 2); | |||||
| EXPECT_EQ(uniform_aug_op2, nullptr); | |||||
| // Try UniformAugment with invalid negative num_ops value | |||||
| std::shared_ptr<TensorOperation> uniform_aug_op = vision::UniformAugment({random_crop_op, center_crop_op}, -1); | |||||
| EXPECT_EQ(uniform_aug_op, nullptr); | |||||
| // UniformAug: transform list must not be empty | |||||
| std::shared_ptr<TensorOperation> uniform_aug_op3 = vision::UniformAugment({}, 1); | |||||
| EXPECT_EQ(uniform_aug_op3, nullptr); | |||||
| } | } | ||||
| TEST_F(MindDataTestPipeline, TestUniformAugWithOps) { | TEST_F(MindDataTestPipeline, TestUniformAugWithOps) { | ||||