I created a model with two branches (each a VGG16), but it generate the following error when I try to save it:
h5py/_objects.pyx in h5py._objects.with_phil.wrapper (/tmp/pip-4rPeHA-build/h5py/_objects.c:2684)()
h5py/_objects.pyx in h5py._objects.with_phil.wrapper (/tmp/pip-4rPeHA-build/h5py/_objects.c:2642)()
h5py/h5g.pyx in h5py.h5g.create (/tmp/pip-4rPeHA-build/h5py/h5g.c:2756)()
ValueError: Unable to create group (Name already exists)
Here is my model:
from keras.applications.vgg16 import VGG16
input_1 = Input(shape=(3, 224, 224))
base_model_1 = VGG16(input_tensor=input_1, weights='imagenet', include_top=False)
x = base_model_1.output
x = Flatten()(x)
x = Dense(4096, activation='relu')(x)
branch_1 = Dense(4096, activation='relu')(x)
model_1 = Model(input=base_model_1.input, output=branch_1)
input_2 = Input(shape=(3, 224, 224))
base_model_2 = VGG16(input_tensor=input_2, weights='imagenet', include_top=False)
x = base_model_2.output
x = Flatten()(x)
x = Dense(4096, activation='relu')(x)
branch_2 = Dense(4096, activation='relu')(x)
model_2 = Model(input=base_model_2.input, output=branch_2)
model = Sequential()
merged = Merge([model_1, model_2], mode='concat')
model.add(merged)
model.add(Dense(129, activation='softmax'))
# compile the model
sgd = SGD(lr=1e-4, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics = ['accuracy'])
model.save('both.hdf5')
As I am using keras.applications.vgg16, I cannot change the name of layers if that's the problem (having two VGG16 with same layer name).
How can I fix the issue?
Thank you,
Update:
I tried to solve the problem by adding the following code:
...
model_1 = Model(input=base_model_1.input, output=branch_1)
for i in range(len(model_1.layers)):
model_1.layers[i].name = model_1.layers[i].name + '1'
input_2 = Input(shape=(3, 224, 224))
...
and now it generates a new error:
...
/usr/local/lib/python2.7/dist-packages/keras/models.pyc in save_model(model, filepath, overwrite)
50 f.attrs['model_config'] = json.dumps({
51 'class_name': model.class.name,
---> 52 'config': model.get_config()
53 }, default=get_json_type).encode('utf8')
54/usr/local/lib/python2.7/dist-packages/keras/models.pyc in get_config(self)
955 for layer in self.layers[0].layers:
956 layer_config = {'class_name': layer.class.name,
--> 957 'config': layer.get_config()}
958 layers.append(layer_config)
959 merge_config = self.layers[0].get_config()/usr/local/lib/python2.7/dist-packages/keras/engine/topology.pyc in get_config(self)
2317 node_index = self.input_layers_node_indices[i]
2318 node_key = layer.name + '_ib-' + str(node_index)
-> 2319 new_node_index = node_conversion_map[node_key]
2320 tensor_index = self.input_layers_tensor_indices[i]
2321 model_inputs.append([layer.name, new_node_index, tensor_index])KeyError: 'input_11_ib-0'
I fixed it by changing the name of the first VGG16 immediately after loading:
from keras.applications.vgg16 import VGG16
input_1 = Input(shape=(3, 224, 224))
base_model_1 = VGG16(input_tensor=input_1, weights='imagenet', include_top=False)
for i in range(1,len(base_model_1.layers)):
base_model_1.layers[i].name = base_model_1.layers[i].name + '1'
...
It fixed the issue with model.save() and I can load the model immediately after I saved it. But after I train it and save it again then I cannot load it again. It gives me the following error when I want to load the trained model:
Exception: Optimizer weight shape (64,) not compatible with provided weight shape (64, 3, 3, 3)
I installed HDFview and opened the hdf5 file and deleted the optimizer part of the file. Now I can load the model and it works like a charm ! However, I think it is a bug and should get fixed.
For anyone else:
I had this issue when I pretrained a part of a model, saved it, and then attempted to load and train it more as a part of a larger network.
What worked for me is to first create a temporary, equivalently structured (new, untrained) model, and then overwrite it with a load_model(...) call. This serves to give all of the model layers unique names, such that they can be concurrently trained and then saved.
E.g.
# Create an identically structured model
# This will "obtain" unique names for the layers in the saved version of this model
model = Sequential()
model.add(....)
model.add(....)
..
..
# Now load the actual saved model
model = load_model('savedModel.h5')
# Use/Train/Save the model jsut fine
model.save('ReSavedModel.h5')
Thanks @patyork, you just saved me a lot of time figuring out what is wrong!
I am, however, using separate programs to create the smaller model and the larger model and I would prefer not to give all information about the small model to the program of the larger model.
Based on the abovementioned information I tried renaming the layers of the smaller model after loading and it works fine for me.
E.g.
Load existing model
model = load_model(...)
Rename layers for saving
i = 0
for layer in model.flattened_layers:
layer.name = "small_model_{0}".format(i)
i += 1
Continue constructing larger model
...
This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 30 days if no further activity occurs, but feel free to re-open a closed issue if needed.
Most helpful comment
For anyone else:
I had this issue when I pretrained a part of a model, saved it, and then attempted to load and train it more as a part of a larger network.
What worked for me is to first create a temporary, equivalently structured (new, untrained) model, and then overwrite it with a
load_model(...)call. This serves to give all of the model layers unique names, such that they can be concurrently trained and then saved.E.g.