dmlc / MXNet.jl

MXNet Julia Package - flexible and efficient deep learning in Julia

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

mx.transpose arbitrary axis?

jingpengw opened this issue · comments

mx.transpose seems only be able to transpose all the axis, how can I swap arbitrary axis of a symbolic NDArray?

methods( mx.transpose )
transpose(in1::MXNet.mx.NDArray)
transpose(in1::MXNet.mx.NDArray, out1::MXNet.mx.NDArray) at ~.julia/v0.4/MXNet/src/ndarray.jl:1046

the python frontend seems have this functionality.

We currently don't create docs for this function because it collides with the Julia base function. But it takes the same kwargs as the Python version. See http://mxnet.io/packages/python/ndarray.html#mxnet.ndarray.transpose

thanks for the explanation. I tried but still not work. Anything wrong here?

julia> a = rand(mx.MX_float, 2,3,4,5,6);

julia> mxa = mx.NDArray(a)
mx.NDArray{Float32}(2,3,4,5,6)

julia> mx.transpose(mxa, axes=(2,1,3,4,5))
ERROR: MethodError: `_compose!` has no method matching _compose!(::MXNet.mx.SymbolicNode, ::Symbol, ::MXNet.mx.NDArray)
Closest candidates are:
  _compose!(::MXNet.mx.SymbolicNode, ::Union{Ptr{UInt8},Symbol}, ::MXNet.mx.SymbolicNode...)
  _compose!(::MXNet.mx.SymbolicNode)
  _compose!(::MXNet.mx.SymbolicNode, ::MXNet.mx.SymbolicNode...)
 in __transpose#65__ at /usr/people/jingpeng/.julia/v0.4/MXNet/src/symbolic-node.jl:673

julia> mx.transpose(mxa, (2,1,3,4,5))
ERROR: MethodError: `_compose!` has no method matching _compose!(::MXNet.mx.SymbolicNode, ::Symbol, ::MXNet.mx.NDArray, ::Tuple{Int64,Int64,Int64,Int64,Int64})
Closest candidates are:
  _compose!(::MXNet.mx.SymbolicNode, ::Union{Ptr{UInt8},Symbol}, ::MXNet.mx.SymbolicNode...)
  _compose!(::MXNet.mx.SymbolicNode)
  _compose!(::MXNet.mx.SymbolicNode, ::MXNet.mx.SymbolicNode...)
 in __transpose#65__ at /usr/people/jingpeng/.julia/v0.4/MXNet/src/symbolic-node.jl:673

@pluskid Any input? It seems that we don't generate the transpose function for the axes version. Looking at the output of MXFuncDescribe n_scalars = 0

julia> mx._get_function_expressions(mx._get_function(:transpose), :transpose)
2-element Array{Expr,1}:
 :(function transpose(in1::MXNet.mx.NDArray,out1::MXNet.mx.NDArray)
        begin  # /home/wallnuss/.julia/v0.6/MXNet/src/ndarray.jl, line 1044:
            local handle = _get_function(:transpose) # /home/wallnuss/.julia/v0.6/MXNet/src/ndarray.jl, line 1045:
            _invoke_mxfunction(handle,MX_handle[in1],MX_float[],MX_handle[out1])
        end
        return out1
    end)
 :(function transpose(in1::MXNet.mx.NDArray)
        transpose(in1::MXNet.mx.NDArray,NDArray(_ndarray_alloc()))
    end)                                                                                                                                             
julia> mx._get_function_description(mx._get_function(:transpose))
(:transpose,"    transpose(src, axes)\n\nTranspose the input matrix and return a new one\n\n# Arguments\n* `src::NDArray`: Source input to the function\n\n* `axes::Shape(tuple), optional, default=()`: Target axis order. By default the axes will be inverted.\n")

It seems to me that we need to use MXFuncInvokeEx to be able to pass kwargs to mxnet and combine that with information from MXFuncGetInfo to discover the kwargs.

@jingpengwu This is a real problem on our side, so thank you for bringing this to our attention.

An update of this issue.

In the master branch, the transpose function was replaced with SwapAxis and the axis number is following python style again. It might be more efficient to follow the internal indexing of mxnet, but is potentially confusing for Julia users.

julia> using MXNet

julia> a = rand(2,2)
2×2 Array{Float64,2}:
 0.82092   0.842056
 0.653796  0.842246

julia> nda = mx.NDArray(a)
mx.NDArray{Float64}(2,2)

julia> copy( mx.SwapAxis(nda; dim1 = 1, dim2=0) )
2×2 Array{Float64,2}:
 0.82092   0.653796
 0.842056  0.842246

Yes, this is a long standing issue. Currently I don't have very good solution except it clearly document it (which is still need to be done...)

One way might be to take a look at the design of https://github.com/JuliaArrays/AxisArrays.jl and PermutedDimensionArrays. Julia's toolbox to work with arbitrary arrays should allow us to use Python's convention while keeping performance.