I can’t seem to figure out how to load a model I stored from a ipython notebook in the c api. I don’t know if the issue happens on the storing or the loading side.
I always end up with:
[18:50:04] src/nnvm/legacy_json_util.cc:209: Loading symbol saved by previous version v1.2.0. Attempting to upgrade...
[18:50:04] src/nnvm/legacy_json_util.cc:217: Symbol successfully upgraded!
[18:50:04] src/c_api/c_predict_api.cc:207: Check failed: infer_complete The shape information of is not enough to get the shapes
The version part confuses me a bit because even after making sure I use 1.2.1 everywhere (from pip in the ipython and compiled from 1.2.1 git sources on the c_api side) I still get that message? But the real issue appears to be the inability to infer the shapes. This also happened with more recent versions of the git sources.
I initially also tried to use gluon but couldn’t figure out how to name in and outputs explicitly especially since my use case will eventually require multiple in and outputs?
I cut down my code to this:
import mxnet
from mxnet import nd, init, autograd
print(mxnet.__version__)
input_data = {
"scalar": nd.zeros((1024,16,1)),
"matrix": nd.zeros((1024,8,137)),
}
label_data = {
"flux_label": nd.zeros((1024,10,138)),
}
dataiter = mxnet.io.NDArrayIter(input_data, label_data, batch_size=128, shuffle=False, last_batch_handle='discard', data_name=['scalar','matrix'], label_name=['flux_label'])
def network():
in_scalar = mxnet.symbol.Variable('scalar')
in_matrix = mxnet.symbol.Variable('matrix')
bcast_scalar = mxnet.symbol.broadcast_to(in_scalar, shape=(0,0,137))
inputs = mxnet.symbol.concat(in_matrix, bcast_scalar, dim=1)
tmp = mxnet.symbol.BatchNorm(inputs)
tmp = mxnet.symbol.FullyConnected(data=tmp, num_hidden=10*138)
flux = tmp.reshape((0,10,138), name='fluxes')
return flux
flux = network()
label = mxnet.symbol.Variable('flux_label')
loss = mxnet.symbol.LinearRegressionOutput(flux, label)
mod = mxnet.mod.Module(symbol=loss, context=mxnet.cpu(0), data_names=['scalar', 'matrix'], label_names=['flux_label'])
mod.bind(data_shapes=dataiter.provide_data, label_shapes=dataiter.provide_label)
mod.init_params()
mod.init_optimizer(optimizer='adagrad')
for epoch in range(1):
dataiter.reset()
for batch in dataiter:
mod.forward(batch, is_train=True)
mod.backward()
mod.update()
flux.save("test.json")
mod.save_params("test.params")
and this:
#include <stdio.h>
#include <stdlib.h>
#include <mxnet/c_predict_api.h>
#include <mxnet/c_api.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
char* read_whole_file(const char *name, int *size) {
struct stat s;
int fd = open(name, O_RDONLY);
if (fd < 0) {
return NULL;
}
fstat(fd, &s);
if(size != NULL) {
*size = s.st_size;
}
char *data = malloc(s.st_size+1);
read(fd, data, s.st_size);
data[s.st_size] = '\0';
close(fd);
return data;
}
int main(int argc, char *argv[]) {
int json_size;
char *json = read_whole_file(argv[1], &json_size);
printf("loaded json file with %d bytes\n", json_size);
int param_size;
char *params = read_whole_file(argv[2], ¶m_size);
printf("loaded param file with %d bytes\n", param_size);
int version;
MXGetVersion(&version);
printf("%d\n", version);
const char *input_keys[] = {"scalar", "matrix"};
const mx_uint input_shape_indptr[] = {0,3,3};
const mx_uint input_shape_data[] = {128, 16, 1, 128, 8, 137};
const char *output_keys[] = {"fluxes"};
PredictorHandle p_handle;
int err = MXPredCreatePartialOut(json,
params,
param_size,
1, 0,
2,
input_keys,
input_shape_indptr,
input_shape_data,
1,
output_keys,
&p_handle);
if(err != 0) {
printf("%s\n", MXGetLastError());
}
free(params);
free(json);
return 0;
}