keras-js icon indicating copy to clipboard operation
keras-js copied to clipboard

Variable-size input layers appear to be unsupported

Open madebyollin opened this issue 8 years ago • 6 comments

Keras supports variable-size input layers; they're specified as follows (where the two "None"s would typically be width and height):

inputlayer = Input(shape=(None, None, 4))

This feature is very useful for certain applications (e.g. entirely convolutional networks for image processing). This input layer is then encoded to JSON by encoder.py as:

...
    "config": {
        "batch_input_shape": [null, null, null, 4],
        "input_dtype": "float32",
        "sparse": false,
        "name": "input_1"
    },
...

However, trying to use this model in keras.js results in a "Specified shape incompatible with data." error from checkShape when trying to predict (since shape.reduce((a, b) => a * b, 1) is 0 if shape contains a null). This suggests that variable-size input layers are not yet supported as part of Keras.js.

I'm not sure if this is a planned feature, unplanned feature, or already implemented (and I just missed a configuration step somewhere), so feel free to label/delete this issue as appropriate. Thanks for the amazing library!

madebyollin avatar Nov 12 '16 01:11 madebyollin

Yep, good catch. It isn't supported currently, but definitely should be.

transcranial avatar Nov 16 '16 05:11 transcranial

Got it! Not to impose, but do you happen to have an idea for how difficult something like this would be? I was thinking of trying to hack together a tile-splitting-and-combining engine or something for the tiny project I'm using this in [https://github.com/madebyollin/hintbot/] in order to get things working for my particular application, but if making arbitrary-size layers work in keras.js is just a matter of translating some portion of the keras python code into JS, I might be able to patch a copy of the library directly rather than trying to build stuff outside of it.

I'll try to look into it myself this weekend. Thanks! Edit: I did some initial poking around but not sure how to implement it yet. I'll keep looking once winter break comes around.

madebyollin avatar Nov 16 '16 06:11 madebyollin

Have you found a reason this would be impossible or especially difficult in this codebase? I'm hoping to just try and change the shape of the InputLayer given for Sequential or will it be more difficult than that? I think it should be possible even for larger data sets, especially for prediction since it's less computationally intensive.

LRonHubs avatar Nov 23 '16 22:11 LRonHubs

@transcranial is there any solution for variable-sized input layers? If not, will it be supported in KerasJS?

Gor97 avatar Jun 12 '17 09:06 Gor97

I get into the same problem, any update on this one? work around?

mayuanyang avatar Dec 08 '17 22:12 mayuanyang

I have done a temporary workout around where you can change the config of the first layer (or any input layers, you have to rename layers as well with tensorflow since they names are already used by the original model)

base_model = load_model('variable_sized_model.h5')
s_config = base_model.get_config()
model_idx = np.random.choice(500)
name_mapping = {v['name']: '%04d_%04d' % (model_idx, c_idx) for c_idx,v in enumerate(s_config['layers'])}
raw_str = json.dumps(s_config)
for k,v in name_mapping.items():
    raw_str = raw_str.replace('"{}"'.format(k), '"{}"'.format(v))
n_config = json.loads(raw_str)
n_config['layers'][0]['config']['batch_input_shape'] = (None, 512, 512, 3)

fix_model = Model.from_config(n_config)
fix_model.load_weights('variable_sized_model.h5')
fix_model.save('clean_fixed_model.h5')

kmader avatar Feb 07 '18 10:02 kmader