0

I have a trained model for image demosaicing, and I want to make it smaller, by removing filters in over spec'd layers.

For example, I want to take the following model (exract):

    conv1 = Conv2D(32, self.kernel_size, activation='relu', padding='same')(chnl4_input)
    conv2 = Conv2D(32, self.kernel_size, strides=(2, 2), activation='relu', padding='same')(conv1)

    conv5 = Conv2D(64, self.kernel_size, activation='relu', padding='same')(conv2)
    conv6 = Conv2D(64, self.kernel_size, activation='relu', padding='same')(conv5)

    up1 = concatenate([UpSampling2D(size=(2, 2))(conv6), conv1], axis=-1)
    conv7 = Conv2D(64, self.kernel_size, activation='relu', padding='same')(up1)

and I want to change the conv5 and conv6 layers to this:

    conv1 = Conv2D(32, self.kernel_size, activation='relu', padding='same')(chnl4_input)
    conv2 = Conv2D(32, self.kernel_size, strides=(2, 2), activation='relu', padding='same')(conv1)

    conv5 = Conv2D(32, self.kernel_size, activation='relu', padding='same')(conv2)
    conv6 = Conv2D(32, self.kernel_size, activation='relu', padding='same')(conv5)

    up1 = concatenate([UpSampling2D(size=(2, 2))(conv6), conv1], axis=-1)
    conv7 = Conv2D(64, self.kernel_size, activation='relu', padding='same')(up1)

I've looked around, but haven't seen any glaringly obvious ways to do this. I found this example of a similar problem, but the solution specifically mentions that the new layers must have the same amount of filters as the old layers, which is no good for me.

If anyone has any idea how I could do this, I'd really appreciate it.

[EDIT]: To clarify, I have an existing model, say 'model A'. I want to create a new model, 'model B'. These two models will be the same, with the exception of the layers I mentioned above. I am looking for a way to initialise the new model with the old models weights for all layers except the ones that have been changed. The new model would then be trained to convergence as per usual.

FCOS
  • 113
  • 11
  • 1
    Do you mean to make the change without retraining the model? Because that is essentially not possible. – Dr. Snoopy Nov 28 '18 at 22:43
  • No, I would be retraining with the new layers. It would essentially be a new model, just with all the other layers initialised to the pre-trained values. I've clarified in question post. – FCOS Nov 29 '18 at 01:06

1 Answers1

2

Build a new model (with exactly the same structure, only changing the number of filters) and transfer weights properly:

transferLayers = [0,1,2,3,4,8,9] #indices must be chosen by you properly

for layer in transferLayers:
    newModel.layers[layer].set_weights(oldModel.layers[layer].get_weights())

There will be a problem with conv7 that will receive a different input ant thus also have a different size for its weight matrix.

What if you change the model structure

Then you should probably create two lists of indices, one for the old model, one for the new.

Or you could recreate the old model adding names to its layers:

  • Recreate the training model exactly the same, but add names to every layer
  • Transfer weights: namedTrainingModel.set_weights(unnamedTraininModel.get_weights())
  • Then create the changed model adding the same names to layers that aren't changed and new names to changed layers

Transfer weights by name:

namedTrainingModel.save_weights('filename')    
changedModel.load_weights('filename', by_name=True)
Daniel Möller
  • 84,878
  • 18
  • 192
  • 214
  • Thanks, looks perfect! Just to clarify for my own purpose, the transferLayers[...] are just the indexs of whatever layers I want to keep? – FCOS Nov 29 '18 at 10:06
  • @FCOS , If you create exactly the same model (just changing the number of filters), yes, you can work with indices of layers. But if you change more things, see the complement in the answer – Daniel Möller Nov 29 '18 at 10:48
  • Thanks, that's great. The structure will be staying the same, it'll purely be filter reductions. Much appreciated. – FCOS Nov 29 '18 at 10:49