In keras Functional API there are few examples for combining models in a different way, but if you want to mix and match parts of models , like combine new classifier-head with a headless pre-trained model, you might encounter some issues. Let's explain how it works behind the scenes.
A saved model is a combination of three things:
- Layer definitions like "Dense" layer with it's regularizes ,output_dim and name
- Layer graph: which layer is connected to which other, and from which direction (in/out)
- Layer weights: for layers which do have them (dropout do not , for example)
When you call: model.to_json() , you get the first two. When you call model.save_weights() you get the third, where the key is the layer-name from (1)
If you want to save and load the exact same model, just call m=model_from_json(json) and then m.load_weights(file). Easy.
If you want to create a head-less model, which does not contain the last few layers, you will have to re-create the model by code, create the connectivity and then use your own function to read the weights file(.h5). The h5 API is quite clean and it's an easy-enough task.
If you want to create a new model from a headless-one and a new head you created, again you will have to define (1) and (2) in code, and then manually load-weights per layer.
Code for connectivity between layers
# assuming this was called already: graph = Graph()
# graph.add_input(name='input1', ndim=2)
new_layer = (Dense(32, 4) #define layer
graph.add_node(new_layer , name='dense1' ,input='input1') #connect layer to input
#note that if you want two inputs, just use instead ,inputs=['input1,'input2']
# and in the end .... graph.add_output(name='output', input='...')
The functional API hides the Graph API and allows you to create a layer and connect it to a node in one line
#assuming input- Input(shape=784,)
Dense(32,4)(input)
It's important to remember that the node connectivity is actually added to the layer instance itself, this sadly means you can't re-use the layer in multiple graphs with totally different connectivity.
You will have to re-instantiate (redefine) a new identical, unconnected, layer.
FAQ:
"UserWarning: Model inputs must come from a Keras Input layer, they cannot be the output of a previous non-Input layer"
You can't instantiate a Model which does not start with Input layer, in other words, you can't just cut the few last layers of an existing model and call Model (input='other_input', output='...same')
No comments:
Post a Comment