6
$\begingroup$

No problems with CNN

cnn = NetChain[
   {
    EmbeddingLayer[16, 100],
    ConvolutionLayer[64, 3, "Interleaving" -> True],
    AggregationLayer[Mean, 1],
    LinearLayer[2],
    SoftmaxLayer[]
    },
   "Input" -> 10
   ] // NetInitialize

enter image description here

cnn@Range[10]

{0.520033,0.479967}

Export["Python\\cnn.json", cnn, "MXNet"]
import mxnet as mx
import numpy as np

cnn = mx.gluon.SymbolBlock.imports('cnn.json', ['Input'], 'cnn.params')

cnn(mx.nd.array([[1,2,3,4,5,6,7,8,9,10]]))

[[0.52003264 0.47996736]]

Problem with RNN

rnn = NetChain[
   {
    EmbeddingLayer[16, 100],
    LongShortTermMemoryLayer[64],
    SequenceLastLayer[],
    LinearLayer[2],
    SoftmaxLayer[]
    },
   "Input" -> 10
   ] // NetInitialize

enter image description here

Export["Python\\rnn.json", rnn, "MXNet"]
import mxnet as mx
import numpy as np

rnn = mx.gluon.SymbolBlock.imports('rnn.json', ['Input'], 'rnn.params')

enter image description here

$\endgroup$
3
  • $\begingroup$ This is definitely a good question. I wonder if it would be worthwhile posting on the Wolfram Community forums as well to try to get the attention of the NN team. It seems to me like there might just be a bug here, but I don't have enough background knowledge of how MXNet is working. Perhaps also there is a version mismatch between the two MXNet installs (the one inside WL and the one for Python...) $\endgroup$
    – Carl Lange
    Commented Apr 20, 2019 at 10:03
  • $\begingroup$ @CarlLange There is no mismatch between the versions of MXNet: v1.4 in both cases (open .json in Notepad; mxnet 1.4.0.post0 via pip). I expect to receive a response from the NN team next week. $\endgroup$ Commented Apr 20, 2019 at 14:18
  • $\begingroup$ Will be interested to hear their response. I've always wanted to be able to deploy these networks but never really got there. $\endgroup$
    – Carl Lange
    Commented Apr 20, 2019 at 14:33

1 Answer 1

1
$\begingroup$

The problem is MXNet-Python fails to load the data associated Nodes

enter image description here Firstly, Let's export two models in Both Mathematica 11.3 and Mathematica 12.0

The models are different

Let's Import the .params file

array120=Import["wolfram_lstm-12.0.json",{"MXNet","ArrayList"}]
Export["wolfram_lstm-12.0.nodes.txt", array120[[-1]]//Normal]

Python Code:

import os
path_root=''
CONTEXT = {'device_type': 'cpu', 'device_id': 0}
ctx="cpu"

import numpy as np
import mxnet as mx

def load_model_bind(sym_file, nd_file, path_root='',ctx='cpu', gpu_id=CONTEXT['device_id']):
    sym_ = mx.symbol.load(sym_file)
    nd_ = mx.nd.load(os.path.join(path_root, nd_file))
    keys = nd_.keys()
    if ctx=="gpu":
        for key in keys:
            nd_[key] = mx.nd.array(nd_[key], ctx=mx.gpu(gpu_id))
    return [sym_, nd_]



def predict113(sym_,nd_,dataIn):
    dataInput = np.array([dataIn])
    # print 'dataInput', dataInput

    if ctx == "cpu":
        dataInputMX = mx.nd.array(dataInput, ctx=mx.cpu(CONTEXT['device_id']))
    elif ctx == "gpu":
        dataInputMX = mx.nd.array(dataInput, ctx=mx.gpu(CONTEXT['device_id']))
    else:
        print 'context error============================='

    # print img_inputND
    # print 'context@',img_inputND.context

    nd_["Input"] = dataInputMX
    # print dataInputMX
    nd_['4.State'] = mx.nd.array([[0, 0, 0, 0, 0]])
    nd_['4.CellState'] = mx.nd.array([[0, 0, 0, 0, 0]])

    e_ = sym_.bind(mx.cpu(0), nd_)
    out_ = e_.forward()
    prob = out_[0].asnumpy()[0]
    print prob

def predict120(sym_, nd_, dataIn):
    dataInput = np.array([dataIn])
    # print 'dataInput', dataInput

    if ctx == "cpu":
        dataInputMX = mx.nd.array(dataInput, ctx=mx.cpu(CONTEXT['device_id']))
    elif ctx == "gpu":
        dataInputMX = mx.nd.array(dataInput, ctx=mx.gpu(CONTEXT['device_id']))
    else:
        print 'context error============================='

    # print img_inputND
    # print 'context@',img_inputND.context


    nd_["Input"] = dataInputMX
    # print dataInputMX
    # nd_['Nodes'] = mx.nd.array((np.zeros(0,180)))
    nd_['Nodes'] = mx.nd.array(np.loadtxt('model-wolfram/wolfram_lstm-12.0.nodes.txt'))
    # nd_['Nodes'] = mx.nd.array(np.ones(180))

    nd_['4.State'] = mx.nd.array([[0,0,0,0,0]])
    nd_['4.CellState'] = mx.nd.array([[0,0,0,0,0]])
    # [-0.48563024 - 0.36583638  1.5399672]
    e_ = sym_.bind(mx.cpu(0), nd_)
    out_ = e_.forward()
    prob = out_[0].asnumpy()[0]
    print prob

file_sym=os.path.join(path_root, "model-wolfram/wolfram_lstm-12.0-symbol.json")
file_nd = os.path.join(path_root, "model-wolfram/wolfram_lstm-12.0-0000.params")

sym_,nd_=load_model_bind(file_sym, file_nd)
predict120(sym_,nd_, [1,2])

file_sym=os.path.join(path_root, "model-wolfram/wolfram_lstm-11.3-symbol.json")
file_nd = os.path.join(path_root, "model-wolfram/wolfram_lstm-11.3-0000.params")

sym_,nd_=load_model_bind(file_sym, file_nd)

predict113(sym_,nd_, [1,2])

Then we load both 11.3 model and 12.0 model and get the same result with that in Mathematica. I've tested the code with python27 and MXNet==1.4

my code and model files were uploaded into my github here

enter image description here


Related https://mathematica.stackexchange.com/a/173766/6648

$\endgroup$
2
  • $\begingroup$ Thanks for your answer! This code works. But let's wait for a response from the NN team. Maybe there is a more beautiful solution. $\endgroup$ Commented Apr 23, 2019 at 8:11
  • $\begingroup$ Glad to know my code works, I think this kind of problems are lasting too long, though some were fixed...from 11.1 to 12.0... hope to know more information from Wolfram NN team. $\endgroup$ Commented Apr 26, 2019 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.