pplonski/keras2cpp

TypeError: string indices must be integers

xdtl opened this issue · 4 comments

xdtl commented

Thank you for your work! I got the following error by running:
python dump_to_simple_cpp.py -a net.json -w net.h5 -o dumped.nnet

Writing to dumped.nnet
Traceback (most recent call last):
File "dump_to_simple_cpp.py", line 33, in
fout.write('layer ' + str(ind) + ' ' + l['class_name'] + '\n')
TypeError: string indices must be integers

The error occurred when ind=0. I checked my 'arch["config"]', which is a very long dict and I only show a small part of it here:

{'layers': [{'class_name': 'InputLayer', 'config': {'batch_input_shape': [None, 1, 160, 128], 'input_dtype': 'float32', 'sparse': False, 'name': 'input_1'}, 'inbound_nodes': [], 'name': 'input_1'}, {'class_name': 'Convolution2D', 'config': {'activity_regularizer': None, 'trainable': True, 'dim_ordering': 'th', 'bias': True, 'nb_row': 3, 'b_constraint': None, 'name': 'convolution2d_1', 'W_constraint': None, 'nb_col': 3, 'subsample': [1, 1], 'init': 'glorot_uniform', 'nb_filter': 32, 'border_mode': 'same', 'b_regularizer': None, 'W_regularizer': None, 'activation': 'relu'}, 'inbound_nodes': [[['input_1', 0, 0]]], 'name': 'convolution2d_1'}, {'class_name': 'Convolution2D', 'config': {'activity_regularizer': None, 'trainable': True, 'dim_ordering': 'th', 'bias': True, 'nb_row': 3, 'b_constraint': None, 'name': 'convolution2d_2', 'W_constraint': None, 'nb_col': 3, 'subsample': [1, 1], 'init': 'glorot_uniform', 'nb_filter': 32, 'border_mode': 'same', 'b_regularizer': None, 'W_regularizer': None, 'activation': 'relu'}, 'inbound_nodes': [[['convolution2d_1', 0, 0]]], 'name': 'convolution2d_2'}, ...

It seems the term 'l['class_name']' caused the problem. But I have no clue how to fix it. Could you please give me some suggestions? Thanks!

Sorry, it is hard to say ... what Keras verison are you using? Do you use theano as backend?

xdtl commented

Thanks for your reply! I don't know which Keras version it is, because I used Amazon AWS to run my code instead of building my own machine. It did show it is using theano backend.

At first, I got 'arch["config"]' like this:
{u'layers': [{u'class_name': u'InputLayer', u'inbound_nodes': [], u'config': {u'batch_input_shape': [None, 1, 160, 128], u'sparse': False, u'input_dtype': u'float32', u'name': u'input_1'}, u'name': u'input_1'}, {u'class_name': u'Convolution2D', u'inbound_nodes': [[[u'input_1', 0, 0]]], u'config': {u'W_constraint': None, u'b_constraint': None, u'name': u'convolution2d_1', u'activity_regularizer': None, u'trainable': True, u'dim_ordering': u'th', u'nb_col': 3, u'subsample': [1, 1], u'init': u'glorot_uniform', u'bias': True, u'nb_filter': 32, u'b_regularizer': None, u'W_regularizer': None, u'nb_row': 3, u'activation': u'relu', u'border_mode': u'same'}, u'name': u'convolution2d_1'}, {u'class_name': u'Convolution2D', u'inbound_nodes': [[[u'convolution2d_1', 0, 0]]], ...

There are a lot of 'u'. I searched online and found it was Unicode object. I followed the suggestions to replace your original code "arch = json.loads(arch)" with "arch = yaml.safe_load(arch)" or "arch = simplejson.loads(arch)". Those 'u' disappeared, but the error is still there...

Try to change line 30:

for ind, l in enumerate(arch["config"]):

to

for ind, l in enumerate(arch["layers"]):

This should help, but for sure it will require more custom changes and I can help with this - sorry! You should change this code by yourself for your needs.

xdtl commented

Thanks very much! This is very helpful. It seems the layout of arch varies from case to case. I tried:
for ind, l in enumerate(arch["config"]["layers"]):
and got dumped.nnet. But test_run_cnn.cc generated another error:
"Layer is empty, maybe it is not defined? Cannot define network."
The problem lies in keras_model.cc, keras::KerasModel::load_weights:
layer_type =="InputLayer",
which doesn't meet any of those if...else... conditions.

I fully understand I am responsible to change it for my own needs. But any directions or suggestions are highly appreciated.