De-serializing a symbolic Gluon model


#1

The serialization section of the tutorial http://gluon.mxnet.io/chapter03_deep-neural-networks/serialization.html doesn’t have information on how to load a previously saved (to JSON) symbolic model and, after loading the trained params, run predictions. Does this functionality exist in Gluon yet? If not, are there any suggested workarounds/examples?

E.g.

from mxnet.gluon import nn
from mxnet import symbol

def get_net():
# construct a MLP
net = nn.HybridSequential()
with net.name_scope():
net.add(nn.Dense(256, activation=“relu”))
net.add(nn.Dense(128, activation=“relu”))
net.add(nn.Dense(2))
# initialize the parameters
net.collect_params().initialize()
return net

net = get_net()

x = symbol.var(‘data’)
y = net(x)
y.save(‘model.json’)

[train the model here]

net.save_params(‘model.params’)


#2

Response from Madan Jampani:

The following worked for me.

// after training the model save weights to a file.
net.collect_params().save(‘model.params’)

// initialize a SymbolBlock with the store json and params files.

symbol = mx.sym.load(‘model.json’)
// for predictions add a softmax layer (assuming your loss layer in gluon was a softmax cross entropy loss)
outputs = mx.symbol.softmax(data=symbol, name=‘softmax_label’)
inputs = mx.sym.var(‘data’)
// ‘model_’ is the prefix. You want to use the same prefix when you create the Sequential block
param_dict = gluon.ParameterDict(‘model_’)
new_net = gluon.SymbolBlock(outputs, inputs, param_dict)

// initialize weights from file.
new_net.load_params(‘model.params’, ctx=ctx)


#3

With the latest code you can use SymbolBlock.export


#4

This is for saving the model in JSON, right? The de-serialization logic would remain the same?


#5

While attempting something very similar with mxnet 1.1 I ran into some trouble. See my very similar example below:

feature_net = vision.get_model(network_arch, pretrained=True, ctx=ctx, prefix='myprefix_')
net = vision.get_model(network_arch, pretrained=False, ctx=ctx, classes=classes, prefix='myprefix_')
net.initialize(ctx=ctx)
net.features = feature_net.features

…do training …

save model

y = net(mx.sym.var('data'))
y.save(path)

save params

net.save_params(filename)

Now load it using SymbolBlock

model = SymbolBlock(outputs=mx.sym.load_json(open(cfg.predict.model_path, 'r').read()),
                                 inputs=mx.sym.var('data'))
model.load_params(cfg.predict.param_path, ctx=ctx)

This will throw an error since the parameters that were saved earlier have a ‘myprefix’ prefix but the SymbolBlock does not even though the prefix is in the json file. My dirty solution was to set the model’s prefix manually with

model._prefix = 'myprefix_'

which solved the issue but this is not maintainable. Any suggestion on this?