From 25560b3e8763d8f8ed3f722a989aaf3cb394d280 Mon Sep 17 00:00:00 2001 From: Iblis Lin Date: Mon, 11 Mar 2019 12:02:13 +0800 Subject: [PATCH] Julia: rename `mx.clip` to `clamp` for `NDArray` (#14027) - in order to match Julia `Base.clamp` interface - depwarn for `mx.clip` included --- julia/NEWS.md | 7 ++--- julia/src/MXNet.jl | 2 -- julia/src/deprecated.jl | 8 +++-- julia/src/ndarray/arithmetic.jl | 52 ++++++++++++++++++++------------- julia/src/ndarray/remap.jl | 12 ++++++++ julia/src/optimizer.jl | 2 +- julia/test/unittest/ndarray.jl | 12 ++++---- 7 files changed, 60 insertions(+), 35 deletions(-) diff --git a/julia/NEWS.md b/julia/NEWS.md index 4a6c1a210e17..3cd616288bf8 100644 --- a/julia/NEWS.md +++ b/julia/NEWS.md @@ -19,8 +19,6 @@ * Following material from `mx` module got exported (#TBD): * `NDArray` - * `clip()` - * `clip!()` * `context()` * `expand_dims()` * `@inplace` @@ -373,11 +371,12 @@ 99.9889 100.533 100.072 ``` -* Signature of `clip` changed, it doesn't require any keyword argument now. +* Signature of `clip` changed and renamed to `clamp`. + It doesn't require any keyword argument now. (#TBD) Before: `clip(x, a_min = -4, a_max = 4)` - After: `clip(x, -4, 4)` + After: `clamp(x, -4, 4)` ### Optimizer diff --git a/julia/src/MXNet.jl b/julia/src/MXNet.jl index 68663d1e561e..70eda96da9d6 100644 --- a/julia/src/MXNet.jl +++ b/julia/src/MXNet.jl @@ -50,8 +50,6 @@ export SymbolicNode, # ndarray.jl export NDArray, - clip, - clip!, context, expand_dims, @inplace, diff --git a/julia/src/deprecated.jl b/julia/src/deprecated.jl index 70079b8dcd62..7c49b66b14b1 100644 --- a/julia/src/deprecated.jl +++ b/julia/src/deprecated.jl @@ -72,8 +72,6 @@ end @deprecate softmax(x::NDArray; axis = ndims(x)) softmax.(x, axis) @deprecate log_softmax(x::NDArray; axis = ndims(x)) log_softmax.(x, axis) -@deprecate clip(x; a_min = 0, a_max = 0) clip(x, a_min, a_max) - function broadcast_plus(x::NDArray, y::NDArray) @warn("broadcast_plus(x, y) is deprecated, use x .+ y instead.") x .+ y @@ -194,3 +192,9 @@ function empty(dims::Int...) "use `NDArray(undef, dims...)` instead.") NDArray(undef, dims...) end + +# replaced by Base.clamp +@deprecate clip(x::NDArray, lo::Real, hi::Real) clamp(x, lo, hi) +@deprecate clip!(x::NDArray, lo::Real, hi::Real) clamp!(x, lo, hi) +@deprecate clip(x; a_min = 0, a_max = 0) clamp(x, a_min, a_max) + diff --git a/julia/src/ndarray/arithmetic.jl b/julia/src/ndarray/arithmetic.jl index 60dde6bdecdf..4c467a2d96dd 100644 --- a/julia/src/ndarray/arithmetic.jl +++ b/julia/src/ndarray/arithmetic.jl @@ -218,40 +218,52 @@ broadcasted(::typeof(^), x::NDArray{T,N}, y::NDArray{T,N}) where {T,N} = broadcasted(::typeof(^), x::NDArray{T,N}, y::NDArray{T,M}) where {T,N,M} = _broadcast_power(x, y) -_nddoc[:clip] = _nddoc[:clip!] = """ - clip(x::NDArray, min, max) - clip!(x::NDArray, min, max) + clamp(x::NDArray, lo, hi) -Clips (limits) the values in `NDArray`. +Clamps (limits) the values in `NDArray`. Given an interval, values outside the interval are clipped to the interval edges. -Clipping `x` between `min` and `x` would be: +Clamping `x` between low `lo` and high `hi` would be: ```julia -clip(x, min_, max_) = max(min(x, max_), min_)) +clamp(x, lo, hi) = max(min(x, lo), hi)) ``` +The storage type of clip output depends on storage types of inputs and the +`lo`, `hi` parameter values: + +- clamp(default) -> default +- clamp(row_sparse, lo <= 0, hi >= 0) -> row_sparse +- clamp(csr, lo <= 0, hi >= 0) -> csr +- clamp(row_sparse, lo < 0, hi < 0) -> default +- clamp(row_sparse, lo > 0, hi > 0) -> default +- clamp(csr, lo < 0, hi < 0) -> csr +- clamp(csr, lo > 0, hi > 0) -> csr + +## Examples + ```jldoctest julia> x = NDArray(1:9); -julia> mx.clip(x, 2, 8)' +julia> clamp(x, 2, 8)' 1×9 mx.NDArray{Int64,2} @ CPU0: 2 2 3 4 5 6 7 8 8 -``` -The storage type of clip output depends on storage types of inputs and the -`min`, `max` parameter values: - -- clip(default) = default -- clip(row_sparse, min <= 0, max >= 0) = row_sparse -- clip(csr, min <= 0, max >= 0) = csr -- clip(row_sparse, min < 0, max < 0) = default -- clip(row_sparse, min > 0, max > 0) = default -- clip(csr, min < 0, max < 0) = csr -- clip(csr, min > 0, max > 0) = csr +julia> clamp(x, 8, 2)' +1×9 NDArray{Int64,2} @ CPU0: + 8 8 2 2 2 2 2 2 2 + ``` +""" +Base.clamp(x::NDArray, lo::Real, hi::Real) = _clamp(x, lo, hi) +@_remap _clamp(x::NDArray, lo::Real, hi::Real) clip(x; a_min = lo, a_max = hi) + +""" + clamp!(x::NDArray, lo, hi) + +See also [`clamp`](@ref). """ -@_remap clip(x::NDArray, min::Real, max::Real) clip(x; a_min = min, a_max = max) -@_remap clip!(x::NDArray, min::Real, max::Real) clip(x; a_min = min, a_max = max) +Base.clamp!(x::NDArray, lo::Real, hi::Real) = _clamp!(x, lo, hi) +@_remap _clamp!(x::NDArray, lo::Real, hi::Real) clip(x; a_min = lo, a_max = hi) ################################################################################ # remapping to solving type unstablility diff --git a/julia/src/ndarray/remap.jl b/julia/src/ndarray/remap.jl index e6515e43ded9..86cb0373164e 100644 --- a/julia/src/ndarray/remap.jl +++ b/julia/src/ndarray/remap.jl @@ -67,6 +67,18 @@ function _docsig(fname::Symbol, sig::Expr, opname::String) end end +""" + @_remap(sig::Expr, imp::Expr) + +Creating a function in signature `sig` with the function implementation `imp`. + +## Arguments +- `sig` is the function signature. + If the function name ends with `!`, it will invoke the corresponding inplace + call. +- `imp` is the underlying libmxnet API call + +""" macro _remap(sig::Expr, imp::Expr) d = splitdef(:($sig = $imp)) @capture d[:name] (M_.fname_|fname_) diff --git a/julia/src/optimizer.jl b/julia/src/optimizer.jl index 46726500f81f..6eda53e6d5b3 100644 --- a/julia/src/optimizer.jl +++ b/julia/src/optimizer.jl @@ -291,7 +291,7 @@ function normgrad!(opt::AbstractOptimizer, W::NDArray, ∇::NDArray) !iszero(s) && @inplace ∇ .*= s # gradient clipping c = opt.clip - c > 0 && clip!(∇, -c, c) + c > 0 && clamp!(∇, -c, c) # weight decay λ = opt.λ λ > 0 && @inplace ∇ += λ .* W diff --git a/julia/test/unittest/ndarray.jl b/julia/test/unittest/ndarray.jl index eb69a736a6e4..26695e8c4769 100644 --- a/julia/test/unittest/ndarray.jl +++ b/julia/test/unittest/ndarray.jl @@ -885,24 +885,24 @@ function test_saveload() rm(fname) end -function test_clip() +function test_clamp() dims = rand_dims() - @info("NDArray::clip::dims = $dims") + @info("NDArray::clamp::dims = $dims") j_array, nd_array = rand_tensors(dims) clip_up = maximum(abs.(j_array)) / 2 clip_down = 0 - clipped = clip(nd_array, clip_down, clip_up) + clipped = clamp(nd_array, clip_down, clip_up) # make sure the original array is not modified @test copy(nd_array) ≈ j_array @test all(clip_down .<= copy(clipped) .<= clip_up) - @info("NDArray::clip!") + @info("NDArray::clamp!") let x = NDArray(1.0:20) - clip!(x, 5, 15) + clamp!(x, 5, 15) @test all(5 .<= copy(x) .<= 15) end end @@ -1571,7 +1571,7 @@ end test_mod() test_gd() test_saveload() - test_clip() + test_clamp() test_power() test_sqrt() test_eltype()