You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by jx...@apache.org on 2017/11/20 19:57:25 UTC
[incubator-mxnet] branch vision updated: [Image OP] Normalize
(#8731)
This is an automated email from the ASF dual-hosted git repository.
jxie pushed a commit to branch vision
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
The following commit(s) were added to refs/heads/vision by this push:
new e997559 [Image OP] Normalize (#8731)
e997559 is described below
commit e997559513afd4339f93a23ab2ee3f32b612c1e4
Author: Yizhi Liu <ja...@gmail.com>
AuthorDate: Mon Nov 20 11:57:22 2017 -0800
[Image OP] Normalize (#8731)
* image normalize op
* image normalize op param check
---
src/operator/image/image_random-inl.h | 93 +++++++++++++++++++++++++++++++++++
src/operator/image/image_random.cc | 34 ++++++++++++-
2 files changed, 125 insertions(+), 2 deletions(-)
diff --git a/src/operator/image/image_random-inl.h b/src/operator/image/image_random-inl.h
index c50ecb7..6f9cdc0 100644
--- a/src/operator/image/image_random-inl.h
+++ b/src/operator/image/image_random-inl.h
@@ -106,12 +106,105 @@ static void ToTensor(const nnvm::NodeAttrs &attrs,
});
}
+struct NormalizeParam : public dmlc::Parameter<NormalizeParam> {
+ nnvm::Tuple<float> mean;
+ nnvm::Tuple<float> std;
+ DMLC_DECLARE_PARAMETER(NormalizeParam) {
+ DMLC_DECLARE_FIELD(mean)
+ .describe("Sequence of mean for each channel.");
+ DMLC_DECLARE_FIELD(std)
+ .describe("Sequence of standard deviations for each channel.");
+ }
+};
+
+struct normalize {
+ template<typename DType>
+ MSHADOW_XINLINE static void Map(int i, DType *out, const DType *in,
+ const OpReqType req,
+ const int nchannel, const int size,
+ const float *mean, const float *std) {
+ int c = 0;
+ switch (nchannel) {
+ case 1:
+ break;
+ case 3:
+ if (i < size) {
+ c = 0;
+ } else if (i < (size << 1)) {
+ c = 1;
+ } else {
+ c = 2;
+ }
+ break;
+ default:
+ LOG(FATAL) << "not support channel" << nchannel;
+ }
+ float m = (mean ? mean[c] : 0);
+ KERNEL_ASSIGN(out[i], req, static_cast<DType>((in[i] - m) / std[c]));
+ }
+};
+
+static void NormalizeCheckParam(const nnvm::Tuple<float> &mean,
+ const nnvm::Tuple<float> &std,
+ const int nchannel) {
+ CHECK(mean.ndim() == 1 || mean.ndim() == 3)
+ << "Mean must be in dimension 1 or 3.";
+ CHECK(std.ndim() == 1 || std.ndim() == 3)
+ << "Standard deviations must be in dimension 1 or 3.";
+ CHECK(nchannel == 1 || nchannel == 3) << "Image channel must be 1 or 3.";
+ CHECK_EQ(mean.ndim(), nchannel)
+ << "Mean dimension does not agree with image channel.";
+ CHECK_EQ(std.ndim(), nchannel)
+ << "Standard deviations dimension does not agree with image channel.";
+ for (uint32_t c = 0; c < std.ndim(); ++c) {
+ CHECK(std[c] > 0) << "Invalid standard deviation " << std[c];
+ }
+}
+
template<typename xpu>
static void Normalize(const nnvm::NodeAttrs &attrs,
const OpContext &ctx,
const std::vector<TBlob> &inputs,
const std::vector<OpReqType> &req,
const std::vector<TBlob> &outputs) {
+ const NormalizeParam ¶m = nnvm::get<NormalizeParam>(attrs.parsed);
+ auto mean = param.mean;
+ auto std = param.std;
+
+ int nchannel = inputs[0].shape_[0];
+ NormalizeCheckParam(mean, std, nchannel);
+
+ int size = inputs[0].Size() / nchannel;
+ mshadow::Stream<xpu> *s = ctx.get_stream<xpu>();
+ MXNET_ASSIGN_REQ_SWITCH(req[0], Req, {
+ MSHADOW_TYPE_SWITCH(outputs[0].type_flag_, DType, {
+ mxnet_op::Kernel<normalize, xpu>::Launch(
+ s, inputs[0].Size(), outputs[0].dptr<DType>(), inputs[0].dptr<DType>(),
+ Req, nchannel, size, mean.begin(), std.begin());
+ });
+ });
+}
+
+template<typename xpu>
+static void NormalizeBackward(const nnvm::NodeAttrs &attrs,
+ const OpContext &ctx,
+ const std::vector<TBlob> &inputs,
+ const std::vector<OpReqType> &req,
+ const std::vector<TBlob> &outputs) {
+ const NormalizeParam ¶m = nnvm::get<NormalizeParam>(attrs.parsed);
+ int nchannel = inputs[0].shape_[0];
+
+ NormalizeCheckParam(param.mean, param.std, nchannel);
+
+ int size = inputs[0].Size() / nchannel;
+ mshadow::Stream<xpu> *s = ctx.get_stream<xpu>();
+ MXNET_ASSIGN_REQ_SWITCH(req[0], Req, {
+ MSHADOW_TYPE_SWITCH(outputs[0].type_flag_, DType, {
+ mxnet_op::Kernel<normalize, xpu>::Launch(
+ s, inputs[0].Size(), outputs[0].dptr<DType>(), inputs[0].dptr<DType>(),
+ Req, nchannel, size, nullptr, param.std.begin());
+ });
+ });
}
struct RandomBrightnessParam : public dmlc::Parameter<RandomBrightnessParam> {
diff --git a/src/operator/image/image_random.cc b/src/operator/image/image_random.cc
index 26fa843..e32a677 100644
--- a/src/operator/image/image_random.cc
+++ b/src/operator/image/image_random.cc
@@ -28,8 +28,6 @@
#include "../operator_common.h"
#include "../elemwise_op_common.h"
-
-
namespace mxnet {
namespace op {
@@ -46,6 +44,38 @@ NNVM_REGISTER_OP(_image_to_tensor)
.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseNone{ "_copy" })
.add_argument("data", "NDArray-or-Symbol", "The input.");
+DMLC_REGISTER_PARAMETER(NormalizeParam);
+NNVM_REGISTER_OP(_image_normalize)
+.describe(R"code()code" ADD_FILELINE)
+.set_num_inputs(1)
+.set_num_outputs(1)
+.set_attr_parser(ParamParser<NormalizeParam>)
+.set_attr<FResourceRequest>("FResourceRequest", [](const NodeAttrs& attrs) {
+ return std::vector<ResourceRequest>{ResourceRequest::kRandom};
+})
+.set_attr<nnvm::FInferShape>("FInferShape", ElemwiseShape<1, 1>)
+.set_attr<nnvm::FInferType>("FInferType", ElemwiseType<1, 1>)
+.set_attr<nnvm::FInplaceOption>("FInplaceOption",
+[](const NodeAttrs& attrs){
+ return std::vector<std::pair<int, int> >{{0, 0}};
+})
+.set_attr<FCompute>("FCompute<cpu>", Normalize<cpu>)
+.set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseNone{ "_image_backward_normalize" })
+.add_argument("data", "NDArray-or-Symbol", "The input.")
+.add_arguments(NormalizeParam::__FIELDS__());
+
+NNVM_REGISTER_OP(_image_backward_normalize)
+.describe(R"code()code" ADD_FILELINE)
+.set_num_inputs(1)
+.set_num_outputs(1)
+.set_attr_parser(ParamParser<NormalizeParam>)
+.set_attr<nnvm::TIsBackward>("TIsBackward", true)
+.set_attr<nnvm::FInplaceOption>("FInplaceOption",
+[](const NodeAttrs& attrs){
+ return std::vector<std::pair<int, int> >{{0, 0}};
+})
+.set_attr<FCompute>("FCompute<cpu>", NormalizeBackward<cpu>);
+
DMLC_REGISTER_PARAMETER(RandomBrightnessParam);
NNVM_REGISTER_OP(_image_random_brightness)
.describe(R"code()code" ADD_FILELINE)
--
To stop receiving notification emails like this one, please contact
['"commits@mxnet.apache.org" <co...@mxnet.apache.org>'].