-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Conversation
a1bf838
to
49a9ae4
Compare
python/mxnet/ndarray/ndarray.py
Outdated
return _internal._histogram(data=a, bins=bins) | ||
elif isinstance(bins, int): | ||
if range_ is None: | ||
range_ = (float(a.min().asnumpy()[0]), float(a.max().asnumpy()[0])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't do this in the frontend.
python/mxnet/ndarray/ndarray.py
Outdated
elif isinstance(bins, int): | ||
if range_ is None: | ||
range_ = (float(a.min().asnumpy()[0]), float(a.max().asnumpy()[0])) | ||
return _internal._histogram(data=a, bins=array([]), bin_cnt=bins, range=range_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why make an invalid array/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bins
is not used in this version of _histogram, but it's one of the inputs so I need a mock array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can define a mode
variable in HistogramParam
for distinguishing the cases of 1 and 2 ndarray inputs. When register the op, use set_num_inputs([](const NodeAttrs& attrs)
to define the number of inputs based upon the mode
.
See example:
https://github.com/apache/incubator-mxnet/blob/master/src/operator/nn/convolution.cc#L471
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/operator/tensor/histogram.cc
Outdated
.add_argument("bins", "NDArray-or-Symbol", "Input ndarray") | ||
.add_arguments(HistogramParam::__FIELDS__()); | ||
|
||
NNVM_REGISTER_OP(_backward_histogram) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Historgram op is not differentiable. Don't register backward op.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, will get rid of it.
7c44e7f
to
b17585a
Compare
python/mxnet/ndarray/ndarray.py
Outdated
@@ -3740,3 +3740,32 @@ def empty(shape, ctx=None, dtype=None): | |||
if dtype is None: | |||
dtype = mx_real_t | |||
return NDArray(handle=_new_alloc_handle(shape, ctx, False, dtype)) | |||
|
|||
|
|||
def histogram(a, bins=10, range_=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why underscore suffix for range
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pylint complains if we override the keyword range
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@piiswrong numpy.histogram
has parameter range
. Should we disable pylint check here to make mx.nd.histogram
parameter naming consistent with numpy?
""" | ||
|
||
# pylint: disable= no-member, protected-access | ||
if isinstance(bins, NDArray): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to check whether bins
is a 1d array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's checked inside the op
python/mxnet/ndarray/ndarray.py
Outdated
# pylint: disable= no-member, protected-access | ||
if isinstance(bins, NDArray): | ||
return _internal._histogram(data=a, bins=bins) | ||
elif isinstance(bins, int): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace int
with integer_types
.
def f(x, bins=10, range=None): | ||
return np.histogram(x, bins, range=range) | ||
|
||
shape = (3, 3, 3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Randomize shape and test ndarrays from 1D-5D.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
x = rand_ndarray(shape, stype='default') | ||
mx_bins = mx.nd.array([-1.0, 0.5, 2.0, 4.5, 50.0]) | ||
np_bins = mx_bins.asnumpy() | ||
bin_cnt = 5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should test more settings of bin_cnt
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
python/mxnet/ndarray/ndarray.py
Outdated
elif isinstance(bins, int): | ||
if range_ is None: | ||
range_ = (float(a.min().asnumpy()[0]), float(a.max().asnumpy()[0])) | ||
return _internal._histogram(data=a, bins=array([]), bin_cnt=bins, range=range_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can define a mode
variable in HistogramParam
for distinguishing the cases of 1 and 2 ndarray inputs. When register the op, use set_num_inputs([](const NodeAttrs& attrs)
to define the number of inputs based upon the mode
.
See example:
https://github.com/apache/incubator-mxnet/blob/master/src/operator/nn/convolution.cc#L471
src/operator/tensor/histogram-inl.h
Outdated
SHAPE_ASSIGN_CHECK(*out_attrs, 1, in_attrs->at(1)); | ||
} | ||
|
||
return out_attrs->at(0).ndim() == 1U && out_attrs->at(0).Size() != 0U && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Call shape_is_none
to simplify the code. ndim == 1
should have been guaranteed before this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/operator/tensor/histogram-inl.h
Outdated
|
||
TYPE_ASSIGN_CHECK(*out_attrs, 0, mshadow::kInt64); | ||
TYPE_ASSIGN_CHECK(*out_attrs, 1, in_attrs->at(0)); | ||
return out_attrs->at(0) != -1 && out_attrs->at(1) != -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Call !type_is_none(out_attrs->at(i))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
26a9d38
to
c2a9f1d
Compare
240eecc
to
55d6ccb
Compare
@reminisce @piiswrong @anirudh2290 @rahul003 Unit tests added, this is ready, please give a review if you have time. Thanks! |
python/mxnet/ndarray/ndarray.py
Outdated
res, bin_bounds = np.histogram(a.asnumpy(), bins=bins) | ||
return array(res), array(bin_bounds) | ||
return _internal._histogram(data=a, bin_cnt=bins, range=range) | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why return None? Shouldn't this cause an error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean that I should throw an exception?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added an exception for the illegal input case.
39fe74e
to
c53e477
Compare
src/operator/tensor/histogram.cc
Outdated
.set_attr<nnvm::FInferShape>("FInferShape", HistogramOpShape) | ||
.set_attr<nnvm::FInferType>("FInferType", HistogramOpType) | ||
.set_attr<FCompute>("FCompute<cpu>", HistogramOpForward<cpu>) | ||
.set_attr<nnvm::FInplaceOption>("FInplaceOption", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to register this if it's empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/operator/tensor/histogram.cc
Outdated
} | ||
} | ||
|
||
template<typename cpu> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a template specialization? Same for other places.
template<>
void HistogramForwardImpl<cpu>()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
|
||
template<> | ||
void HistogramForwardImpl<cpu>(const OpContext& ctx, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change this back to using OpContext
? If using Stream for dispatching, you can get rid of the templates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not using OpContext, I'm just getting rid of the stream argument here.
8689ebd
to
ee38e0c
Compare
@piiswrong Should be ready for merge, please take a look when you have time, thanks! |
So symbolic is not supported? |
@piiswrong There's no backward pass for this function, I wonder if symbolic is necessary in this case? |
@piiswrong symbol is added for histogram. |
8bc8e18
to
4595fd9
Compare
* implementation of histogram operator * address code reviews and code re-design * add exception for invalid inputs * address code reviews * add symbol and symbolic forward check for histogram
Description
This PR implements histogram operator.
Checklist
Essentials
Changes
Comments
The user-facing interface resembles basic behaviors of Numpy's histogram: https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.histogram.html.
Three versions are supported:
histogram(x, bins=7) - divided into 7 equal bins in the range of [x.min, x.max]
histogram(x, bins=7, range=(a,b)) - divided into 7 equal bins in the range of [a, b], anything outside the range is ignored
histogram(x, bins=NDArray) - bin bounds are specified by the bins NDArray.