Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Models with InputLayer are not serialized to HDF5 correctly #11683

Closed
cyounkins opened this issue Nov 19, 2018 · 13 comments
Closed

Models with InputLayer are not serialized to HDF5 correctly #11683

cyounkins opened this issue Nov 19, 2018 · 13 comments

Comments

@cyounkins
Copy link

Opening new issue due to #10417 being closed without fix. Below is a demonstration of the issue and a hack to fix existing saved models.

docker run -it tensorflow/tensorflow:1.11.0-py3 /bin/bash
apt-get update
apt-get install python3-venv git hdf5-tools
python3 -m venv env
source env/bin/activate
pip install keras tensorflow
pip install git+git://github.com/keras-team/keras.git --upgrade --no-deps
python test.py
import keras
from keras.models import Sequential, load_model
from keras.layers import Dense, Input, InputLayer

print('keras.__version__=', keras.__version__)

fname1 = 'test1.h5'
model1 = Sequential()
model1.add(Dense(1, input_shape=(64, 64), name='dense'))
model1.compile(loss='mse', optimizer='adam')
model1.save(fname1)
model1 = load_model(fname1)

fname2 = 'test2.h5'
model2 = Sequential()
model2.add(InputLayer((64,64), name='input'))
model2.add(Dense(1, name='dense'))
model2.compile(loss='mse', optimizer='adam')
model2.save(fname2)
# ValueError: You are trying to load a weight file containing 1 layers into a model with 0 layers
model2 = load_model(fname2)

keras.__version__= 2.2.4

$ h5dump -A test1.h5 > test1.structure
$ h5dump -A test2.h5 > test2.structure
$ diff test1.structure test2.structure
...
<       (0): "{"class_name": "Sequential", "config": {"name": "sequential_1", "layers": [{"class_name": "Dense", "config": {"units": 1, "kernel_constraint": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "use_bias": true, "dtype": "float32", "activation": "linear", "kernel_initializer": {"class_name": "VarianceScaling", "config": {"seed": null, "distribution": "uniform", "mode": "fan_avg", "scale": 1.0}}, "batch_input_shape": [null, 64, 64], "bias_constraint": null, "activity_regularizer": null, "name": "dense", "bias_regularizer": null, "trainable": true}}]}}"
---
>       (0): "{"class_name": "Sequential", "config": {"name": "sequential_2", "layers": [{"class_name": "Dense", "config": {"units": 1, "kernel_constraint": null, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "use_bias": true, "trainable": true, "activation": "linear", "kernel_initializer": {"class_name": "VarianceScaling", "config": {"seed": null, "distribution": "uniform", "mode": "fan_avg", "scale": 1.0}}, "bias_constraint": null, "activity_regularizer": null, "name": "dense", "bias_regularizer": null}}]}}"
...

The test1 has the additional structure: "batch_input_shape": [null, 64, 64], "dtype": "float32",

You can fix this using:

import json
import h5py

def fix_layer0(filename, batch_input_shape, dtype):
    with h5py.File(filename, 'r+') as f:
        model_config = json.loads(f.attrs['model_config'].decode('utf-8'))
        layer0 = model_config['config'][0]['config']
        layer0['batch_input_shape'] = batch_input_shape
        layer0['dtype'] = dtype
        f.attrs['model_config'] = json.dumps(model_config).encode('utf-8')

# Example
fix_layer0('test2.h5', [None, 64, 64], 'float32')
@ymodak ymodak self-assigned this Nov 19, 2018
@ymodak
Copy link
Collaborator

ymodak commented Nov 20, 2018

@cyounkins Thanks for posting the workaround. Would you like to keep this issue open?

@cyounkins
Copy link
Author

@ymodak yes absolutely. It is a bug to not be able to deserialize previously serialized networks.

@rbgreenway
Copy link

rbgreenway commented Dec 14, 2018

@cyounkins -- Thanks, for pushing this issue. I have been struggling with this for too long. I simply rolled back to keras 2.1.6, but would much prefer a fix...and that means fix it, not close it because one of our smarter contributors found and posted a way around the bug.

@ymodak
Copy link
Collaborator

ymodak commented Dec 14, 2018

@gabrieldemarmiesse Can you please take a look? Thanks!

@mikephn
Copy link

mikephn commented Dec 21, 2018

What is the workaround if my model is saved as separate .json with architecture and .hdf5 with weights?

@hosford42
Copy link

My own workaround is to build the model directly, rather than using Sequential().

@mikephn
Copy link

mikephn commented Dec 21, 2018

@hosford42 Thanks, I can construct the model in code, but the problem seems to be with loading the weight file into it...

ValueError: You are trying to load a weight file containing 1 layers into a model with 28 layers.

@hosford42
Copy link

hosford42 commented Dec 21, 2018 via email

@mikephn
Copy link

mikephn commented Dec 22, 2018 via email

krikru added a commit to krikru/gui-mnist that referenced this issue Feb 24, 2019
Newer versions of Keras suffer from an inability to serialize a
Sequential model with an InputLayer properly (see
keras-team/keras#11683), which makes Keras
raise a ValueError when loading the model (see
keras-team/keras#10417). As a workaround,
remove the (auxiliary) InputLayer intil the issue has been fixed.
@cottrell
Copy link

I am seeing this with class API for models saved within the same session (not cross version). Is it possible this is related?

@MmAlder
Copy link

MmAlder commented May 4, 2019

Has anyone tried the fix (not a workaround) I proposed in #10417 ? It works for me and I haven't noticed any side effects.

@eliadl
Copy link

eliadl commented Nov 14, 2019

Another workaround is to replace:

InputLayer((64,64))

with this instead:

Lambda(tf.identity, input_shape=(64,64))

@cyounkins
Copy link
Author

@fchollet Was there a fix for this or is it being closed like #10417 without resolution? As I said above, it's clearly a bug to not be able to deserialize something keras serialized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants