parent
822a3160e4
commit
5fcd3f01a6
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
#include "dataset/kernels/image/uniform_aug_op.h"
|
||||
#include "dataset/kernels/py_func_op.h"
|
||||
#include "dataset/util/random.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
const int UniformAugOp::kDefNumOps = 2;
|
||||
|
||||
UniformAugOp::UniformAugOp(py::list op_list, int32_t num_ops) : num_ops_(num_ops) {
|
||||
std::shared_ptr<TensorOp> tensor_op;
|
||||
// iterate over the op list, cast them to TensorOp and add them to tensor_op_list_
|
||||
for (auto op : op_list) {
|
||||
if (py::isinstance<py::function>(op)) {
|
||||
// python op
|
||||
tensor_op = std::make_shared<PyFuncOp>(op.cast<py::function>());
|
||||
} else if (py::isinstance<TensorOp>(op)) {
|
||||
// C++ op
|
||||
tensor_op = op.cast<std::shared_ptr<TensorOp>>();
|
||||
}
|
||||
tensor_op_list_.insert(tensor_op_list_.begin(), tensor_op);
|
||||
}
|
||||
|
||||
rnd_.seed(GetSeed());
|
||||
}
|
||||
// compute method to apply uniformly random selected augmentations from a list
|
||||
Status UniformAugOp::Compute(const std::vector<std::shared_ptr<Tensor>> &input,
|
||||
std::vector<std::shared_ptr<Tensor>> *output) {
|
||||
IO_CHECK_VECTOR(input, output);
|
||||
|
||||
// variables to generate random number to select ops from the list
|
||||
std::vector<int> random_indexes;
|
||||
|
||||
// variables to copy the result to output if it is not already
|
||||
std::vector<std::shared_ptr<Tensor>> even_out;
|
||||
std::vector<std::shared_ptr<Tensor>> *even_out_ptr = &even_out;
|
||||
int count = 1;
|
||||
|
||||
// select random indexes for candidates to be applied
|
||||
for (int i = 0; i < num_ops_; ++i) {
|
||||
random_indexes.insert(random_indexes.end(),
|
||||
std::uniform_int_distribution<int>(0, tensor_op_list_.size() - 1)(rnd_));
|
||||
}
|
||||
|
||||
for (auto it = random_indexes.begin(); it != random_indexes.end(); ++it) {
|
||||
// Do NOT apply the op, if second random generator returned zero
|
||||
if (std::uniform_int_distribution<int>(0, 1)(rnd_)) {
|
||||
continue;
|
||||
}
|
||||
std::shared_ptr<TensorOp> tensor_op = tensor_op_list_[*it];
|
||||
|
||||
// apply python/C++ op
|
||||
if (count == 1) {
|
||||
(*tensor_op).Compute(input, output);
|
||||
} else if (count % 2 == 0) {
|
||||
(*tensor_op).Compute(*output, even_out_ptr);
|
||||
} else {
|
||||
(*tensor_op).Compute(even_out, output);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
// copy the result to output if it is not in output
|
||||
if (count == 1) {
|
||||
*output = input;
|
||||
} else if ((count % 2 == 1)) {
|
||||
(*output).swap(even_out);
|
||||
}
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
#ifndef DATASET_KERNELS_IMAGE_UNIFORM_AUG_OP_H_
|
||||
#define DATASET_KERNELS_IMAGE_UNIFORM_AUG_OP_H_
|
||||
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "dataset/core/tensor.h"
|
||||
#include "dataset/kernels/tensor_op.h"
|
||||
#include "dataset/util/status.h"
|
||||
#include "dataset/kernels/py_func_op.h"
|
||||
|
||||
#include "pybind11/stl.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace dataset {
|
||||
class UniformAugOp : public TensorOp {
|
||||
public:
|
||||
// Default number of Operations to be applied
|
||||
static const int kDefNumOps;
|
||||
|
||||
// Constructor for UniformAugOp
|
||||
// @param list op_list: list of candidate python operations
|
||||
// @param list num_ops: number of augemtation operations to applied
|
||||
UniformAugOp(py::list op_list, int32_t num_ops);
|
||||
|
||||
~UniformAugOp() override = default;
|
||||
|
||||
void Print(std::ostream &out) const override { out << "UniformAugOp:: number of ops " << num_ops_; }
|
||||
|
||||
// Overrides the base class compute function
|
||||
// @return Status - The error code return
|
||||
Status Compute(const std::vector<std::shared_ptr<Tensor>> &input,
|
||||
std::vector<std::shared_ptr<Tensor>> *output) override;
|
||||
|
||||
private:
|
||||
int32_t num_ops_;
|
||||
std::vector<std::shared_ptr<TensorOp>> tensor_op_list_;
|
||||
std::mt19937 rnd_;
|
||||
};
|
||||
} // namespace dataset
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // DATASET_KERNELS_IMAGE_UNIFORM_AUG_OP_H_
|
Loading…
Reference in new issue