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

can not load_model() or load_from_json() if my model contains my own Layer #8612

Closed
talorwu opened this issue Nov 28, 2017 · 13 comments
Closed

Comments

@talorwu
Copy link

talorwu commented Nov 28, 2017

this is my code:
`from keras import backend as K
from keras.engine.topology import Layer
from keras.models import load_model
from keras.layers import Dense
from keras.models import Sequential,model_from_json
import numpy as np

class MyLayer(Layer):

def __init__(self, output_dim, **kwargs):
    self.output_dim = output_dim
    super(MyLayer, self).__init__(**kwargs)

def build(self, input_shape):
    # Create a trainable weight variable for this layer.
    self.kernel = self.add_weight(name='kernel',
                                  shape=(input_shape[1], self.output_dim),
                                  initializer='uniform',
                                  trainable=True)
    super(MyLayer, self).build(input_shape)  # Be sure to call this somewhere!

def call(self, x):
    return K.dot(x, self.kernel)

def compute_output_shape(self, input_shape):
    return (input_shape[0], self.output_dim)

model = Sequential()
model.add(Dense(32, input_shape=(784,)))
model.add(MyLayer(100))
#this is ok
model.save('mode_test.h5')

#wrong
model = load_model('mode_test.h5')

json_string = model.to_json()

open('my_model_architecture.json', 'w').write(json_string)

model.save_weights('my_model_weights.h5')

model = model_from_json(open('my_model_architecture.json').read())

model.load_weights('my_model_weights.h5')`

the Error is:
ValueError: Unknown layer: MyLayer

@bdwyer2
Copy link
Contributor

bdwyer2 commented Nov 28, 2017

From the FAQ:

Handling custom layers (or other custom objects) in saved models

If the model you want to load includes custom layers or other custom classes or functions,
you can pass them to the loading mechanism via the custom_objects argument:

from keras.models import load_model
# Assuming your model includes instance of an "AttentionLayer" class
model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})

Alternatively, you can use a custom object scope:

from keras.utils import CustomObjectScope

with CustomObjectScope({'AttentionLayer': AttentionLayer}):
    model = load_model('my_model.h5')

Custom objects handling works the same way for load_model, model_from_json, model_from_yaml:

from keras.models import model_from_json
model = model_from_json(json_string, custom_objects={'AttentionLayer': AttentionLayer})

@stevewyl
Copy link

stevewyl commented Mar 6, 2018

@bmabey Thanks for the hints!
Still, have problems. I have two attention layer in my model, named as 'AttLayer_1' and 'AttLayer_2'.
Attention is the custom layer class
custom_ob = {'AttLayer1':Attention,'AttLayer2':Attention}
model = load_model('./model/HAN_20_5_201803062109.h5', custom_objects=custom_ob)

with CustomObjectScope(custom_ob):
model = load_model('./model/HAN_20_5_201803062109.h5')

Neither of two methods failed, return "Unknown layer: Attention"

It's so strange. I can use model.load_weights(filepath) to load the saved weights genearted by the same model architecture. I cannot load the model architecture from file. But only by running the code again.

@nielspetersen
Copy link

nielspetersen commented Mar 7, 2018

@stevewyl Is the Attention layer defined within the same file?

As far as I know you have to provide the module of the Attention layer, e.g. custom_layer.Attention.
Thus:

custom_ob = {'AttLayer1': custom_layer.Attention,'AttLayer2': custom_layer.Attention}

This is analogue to the import statement at the beginning of the file.

@shravankgit
Copy link

# Save model
model_json = model.to_json()
with open("model.json", "w") as json_file:
    json_file.write(model_json)
model.save_weights("color_tensorflow_real_mode_2_imgs.h5")

##### Load the model

with open('model.json','r') as f:
    json = f.read()
model = model_from_json(json)
model.load_weights("color_tensorflow_real_mode.h5")

It will help you

@singhay
Copy link

singhay commented Jul 24, 2018

It will error out when using ModelCheckpoint Callback

yashdusing added a commit to yashdusing/Fabrik that referenced this issue Sep 3, 2018
Updated README.md for tested models (AlexNet/Keras). The only change needed is while importing the LRN layer, pass it as a dictionary (more info here : keras-team/keras#8612)
@SujathaSIyer
Copy link

@stevewyl I am facing the same issue too. Did you get any solution for the issue ?

utsavgarg pushed a commit to Cloud-CV/Fabrik that referenced this issue Sep 18, 2018
* Updated README.md for tested models (AlexNet/Keras)

Updated README.md for tested models (AlexNet/Keras). The only change needed is while importing the LRN layer, pass it as a dictionary (more info here : keras-team/keras#8612)

* Update README.md

* Update README.md

* Update README.md

* Create keras_custom_layer_usage.md

Instructions for adding custom layers to Keras

* Update keras_custom_layer_usage.md

Changed keras_custom_layer_usage

* Update README.md

* Update README.md
@Monduiz
Copy link

Monduiz commented Nov 27, 2018

When using a custom layer, you will have to define a get_config function into the layer class. Example:

https://github.com/keras-team/keras/blob/master/keras/layers/convolutional.py#L214

This will show you how to adapt the get_config code to your custom layers.

With the example above:

`def get_config(self):
    config = {
    'output_dim': self.output_dim

    }
base_config = super(MyLayer, self).get_config()
return dict(list(base_config.items()) + list(config.items()))`

You will need to retrain the model using the new class code.

@jnorthrup
Copy link

i have seen this error posted in several places on the internet, and has been fixed in tensorflowjs but not keras or tf python.

my model is culled from early-stopping callback, im not saving it manually. this appears to be common

Traceback (most recent call last):
File "/home/jim/mlcc-exercises/rejuvepredictor/stage4.py", line 175, in
custom_objects={'kernel_initializer':GlorotUniform}
File "/usr/local/lib/python3.6/dist-packages/keras/engine/saving.py", line 419, in load_model
model = _deserialize_model(f, custom_objects, compile)
File "/usr/local/lib/python3.6/dist-packages/keras/engine/saving.py", line 225, in _deserialize_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "/usr/local/lib/python3.6/dist-packages/keras/engine/saving.py", line 458, in model_from_config
return deserialize(config, custom_objects=custom_objects)
File "/usr/local/lib/python3.6/dist-packages/keras/layers/init.py", line 55, in deserialize
printable_module_name='layer')
File "/usr/local/lib/python3.6/dist-packages/keras/utils/generic_utils.py", line 145, in deserialize_keras_object
list(custom_objects.items())))
File "/usr/local/lib/python3.6/dist-packages/keras/engine/sequential.py", line 300, in from_config
custom_objects=custom_objects)
File "/usr/local/lib/python3.6/dist-packages/keras/layers/init.py", line 55, in deserialize
printable_module_name='layer')
File "/usr/local/lib/python3.6/dist-packages/keras/utils/generic_utils.py", line 147, in deserialize_keras_object
return cls.from_config(config['config'])
File "/usr/local/lib/python3.6/dist-packages/keras/layers/recurrent.py", line 2298, in from_config
return cls(**config)
File "/usr/local/lib/python3.6/dist-packages/keras/legacy/interfaces.py", line 91, in wrapper
return func(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/keras/layers/recurrent.py", line 2178, in init
implementation=implementation)
File "/usr/local/lib/python3.6/dist-packages/keras/layers/recurrent.py", line 1841, in init
self.kernel_initializer = initializers.get(kernel_initializer)
File "/usr/local/lib/python3.6/dist-packages/keras/initializers.py", line 508, in get
return deserialize(identifier)
File "/usr/local/lib/python3.6/dist-packages/keras/initializers.py", line 503, in deserialize
printable_module_name='initializer')
File "/usr/local/lib/python3.6/dist-packages/keras/utils/generic_utils.py", line 138, in deserialize_keras_object
': ' + class_name)
ValueError: Unknown initializer: GlorotUniform

satellitelmk pushed a commit to satellitelmk/VisualNN that referenced this issue Dec 9, 2018
* Updated README.md for tested models (AlexNet/Keras)

Updated README.md for tested models (AlexNet/Keras). The only change needed is while importing the LRN layer, pass it as a dictionary (more info here : keras-team/keras#8612)

* Update README.md

* Update README.md

* Update README.md

* Create keras_custom_layer_usage.md

Instructions for adding custom layers to Keras

* Update keras_custom_layer_usage.md

Changed keras_custom_layer_usage

* Update README.md

* Update README.md
@huxianyin
Copy link

I was having same problem when my model contains customer layers, after few hours of debugging, perfectly worked using:

with CustomObjectScope({'AttentionLayer': AttentionLayer}):
model = load_model("my_model.h5")

other than:

model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})

maybe bug of keras?
hope to help

@AdnanRiaz107
Copy link

From the FAQ:

Handling custom layers (or other custom objects) in saved models

If the model you want to load includes custom layers or other custom classes or functions,
you can pass them to the loading mechanism via the custom_objects argument:

from keras.models import load_model
# Assuming your model includes instance of an "AttentionLayer" class
model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})

Alternatively, you can use a custom object scope:

from keras.utils import CustomObjectScope

with CustomObjectScope({'AttentionLayer': AttentionLayer}):
    model = load_model('my_model.h5')

Custom objects handling works the same way for load_model, model_from_json, model_from_yaml:

from keras.models import model_from_json
model = model_from_json(json_string, custom_objects={'AttentionLayer': AttentionLayer})

Hello! I have tried both but I got the error. "ValueError: Unknown layer: Attention"

@singhay
Copy link

singhay commented Jan 25, 2020

@AdnanRiaz107 is the name of attention layer AttentionLayer or Attention? try doing a model.summary()

@Walid-Ahmed
Copy link

This repo shows a simple sample code to build your own keras layer and use it in your model
https://github.com/Walid-Ahmed/kerasExamples/tree/master/creatingCustoumizedLayer
it might help

@arunraja-hub
Copy link

I am trying to build my own model_from_json function from scratch as I am working with a custom .json file. My custom json file follows this format:

{
  "training_params": {...},
    "architecture":{contains the actual model structure as generated by model.to_json()}
}

How can I extract the training_params and model architecture from my custom json to create a model of that architecture and parameters with this line of code
loaded_model = my_model_from_json(loaded_model_json) ?

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

No branches or pull requests