How to convert a CNN from keras to mxnet?

Hi,

this theme is originally from stackoverflow. Unfortunately, the restrictions there don’t allow me to ask advanced questions, so Foivos told me that it would be a good idea to continue the conversation here.

In summary, it was about a keras net, which I wanted to convert to gluon, but which turned out to be difficult. Foivos then sent me the (probably) exact translation of the network. Unfortunately I couldn’t find out if the networks behave the same, because the results of the Class Activation Mapping (CAM), which I also converted from keras to gluon, were different (for details see: https://stackoverflow.com/questions/55186629/how-to-convert-a-cnn-from-keras-to-mxnet/55604738?noredirect=1#comment98154231_55604738).

Now I would like to continue with the topic where I had to stop at stackoverflow.


To be honest, I’m not quite sure if the net is doing the same thing. After the training I created a Class Activation Mapping (CAM) for both keras and mxnet to show me the relevant regions over Europe. Unfortunately I get different results. But maybe my implementation is wrong?

keras:

def get_cam(airport):
    fname = os.path.normpath( "model_{}.h5".format(airport) )
    model = load_model(fname)

    dry_weights  = model.layers[-1].get_weights()[0][:, 0].reshape((20,30,256))
    rain_weights = model.layers[-1].get_weights()[0][:, 1].reshape((20,30,256))
    get_output   = K.function([model.layers[0].input], [model.layers[-3].output, model.layers[-1].output])

    cam = np.zeros((20,30), dtype=np.float32)
    for depth in range(256):
        for i in range(30):
            for j in range(20):
                cam[j, i] += rain_weights[j, i, depth]

    cam /= np.max(cam)
    im = Image.fromarray(np.uint8(cm.jet(cam)*255))
    im = im.resize((120,80), Image.ANTIALIAS)
    #heatmap = cv2.applyColorMap(np.uint8(255*cam), cv2.COLORMAP_JET)
    im.save("{}_rain.png".format(airport)) 

mxnet:

def get_cam(model):
    dry_weights  = model.last_layer.weight.data()[0].reshape((256,20,30)).asnumpy()
    rain_weights = model.last_layer.weight.data()[1].reshape((256,20,30)).asnumpy()

    cam = np.zeros((20,30), dtype=np.float32)
    for depth in range(256):
        for i in range(30):
            for j in range(20):
                cam[j, i] += rain_weights[j, i, depth]

    cam /= np.max(cam)
    im = Image.fromarray(np.uint8(cm.jet(cam)*255))
    im = im.resize((120,80), Image.ANTIALIAS)
    #heatmap = cv2.applyColorMap(np.uint8(255*cam), cv2.COLORMAP_JET)
    im.save("{}_rain.png".format(airport))

call it with:

model = YourNet()
model.load_parameters(in_file, ctx=ctx)
get_cam(model)

I thought, since the channels appear first, I would also have to change the order of the reshape. In any case, I also tried the original order, but with equally bad results. Well, that’s what I get in both cases:

Any ideas?

Hi Stefan,

welcome to the forum. Can you please provide a reference implementation for Keras (somewhere on the github + paper) on which you are based? I’ve found several things online for CAM, and am not really sure what you are doing.

As a side note, the code for mxnet has at least a bug, rain_weights[j, i, depth], here depth should be in the first slot rain_weights[depth,j, i] but I suspect this is a syntactic error, as the code breaks if you use wrong indexing.

Hi Feevos,

of course! Maybe that would have been the best course of action from the beginning… I’m sorry for the delay.

github: https://github.com/prl900/DeepWeather
paper: https://github.com/prl900/DeepWeather/blob/master/1stDeepStructWS_paper_2.pdf

Regards,
Stefan

1 Like