In keras, is it possible to share weights between two layers, but to have other parameters differ? Consider the following (admittedly a bit contrived) example:
conv1 = Conv2D(64, 3, input_shape=input_shape, padding='same')
conv2 = Conv2D(64, 3, input_shape=input_shape, padding='valid')
Notice that the layers are identical except for the padding
. Can I get keras to use the same weights for both? (i.e. also train the network accordingly?)
I've looked at the keras doc, and the section on shared layers seems to imply that sharing works only if the layers are completely identical.
To my knowledge, this cannot be done by the common "API level" of Keras usage. However, if you dig a bit deeper, there are some (ugly) ways to share the weights.
First of all, the weights of the
Conv2D
layers are created inside thebuild()
function, by callingadd_weight()
:For your provided usage (i.e., default
trainable
/constraint
/regularizer
/initializer
),add_weight()
does nothing special but appending the weight variables to_trainable_weights
:Finally, since
build()
is only called inside__call__()
if the layer hasn't been built, shared weights between layers can be created by:conv1.build()
to initialize theconv1.kernel
andconv1.bias
variables to be shared.conv2.build()
to initialize the layer.conv2.kernel
andconv2.bias
byconv1.kernel
andconv1.bias
.conv2.kernel
andconv2.bias
fromconv2._trainable_weights
.conv1.kernel
andconv1.bias
toconv2._trainable_weights
.conv2.__call__()
will be called; however, sinceconv2
has already been built, the weights are not going to be re-initialized.The following code snippet may be helpful:
One drawback of this hacky weight-sharing is that the weights will not remain shared after model saving/loading. This will not affect prediction, but it may be problematic if you want to load the trained model for further fine-tuning.