I have written a Keras custom layer foo
(no trainable weights within it), which accepts an input x
and returns x + n
where n
is additive white Gaussian noise with a pre-specified standard deviation. I wish to train my functional model model-trg
, which includes foo
, instantiated with noise level set to sigma-trg
(during training phase). In the test model model-test
, I duplicate all trainable layers of model-trg
except foo
. In model-test
, I would like to create a second different instance of foo
with parameter sigma-test
, different from sigma-trg
. The objective is to test whether the model, following training, is able to generalize its learning for different noise levels.
Surprisingly, when I print the summary of model-trg
and model-test
, they appear to use foo
as a shared layer i.e. the standard deviation parameter for model-test
appears to be set identically to the standard deviation parameter in model-trg
. The end result is that the performance of my test model is no different than the performance of my training model.
Are there any suggestions on how to force Keras during compilation to avoid creating shared layers if parameters within that layer is different across the training and test model?
Sharing layers across models
if enable_trg is True:
model_trg = Model(inputs=source_input, outputs= preds)
# some code specifying the layers and connections
# some code to compile and train the model
model_trg.save_weights(model_name + '.h5') # save weights
if enable_test is True:
model_trg.load_weights(model_name + '.h5')
model_test= Model(inputs=source_input, outputs = preds)
Training model
y = foo(batch_size=trg_batch_size,noise_stdev=stdev_trg)(x)
Test model
y = foo(batch_size=test_batch_size,noise_stdev=stdev_test)(x)
Custom layer
class Foo(Layer):
def __init__(self, batch_size, noise_stdev, **kwargs):
super(Foo, self).__init__(**kwargs)
self.batch_size = batch_size
self.stdev = noise_stdev
self.supports_masking = True
def build(self,inputShape):
super(Foo,self).build(inputShape)
def call(self, inputs, training=None):
y = inputs[0]
noise = K.random_normal(shape=K.shape(y),mean=0.,stddev=self.stdev)
return y + noise
def get_config(self):
config = {
'batch_size': self.batch_size,
'noise_stdev': self.stdev
}
base_config = super(Foo, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def compute_output_shape(self, input_shape):
return input_shape