Autoencoder Decoder Weight with Keras Tied Weights

I implemented a weight coder in Keras and successfully trained it.

My goal is to use only part of the Auto-Encoder decoder as the last level of another network to fine tune both the network and the decoder.

The fact is that, as you can see from the summary below, the decoder has no parameters with my implementation of the associated weights, so there is nothing that could be fine tuned. ( decoder.get_weights()returns [])

My question is: should I change the implementation of the associated weights so that the connected layer can still contain the weights, i.e. the transposed weights of the encoder? If so, how?

Or am I just far away?

The following is a summary of the auto-encoder model as well as the class of the bonded dense layer (slightly modified from https://github.com/nanopony/keras-convautoencoder/blob/master/autoencoder_layers.py. )


Layer (type)                     Output Shape          Param #     Connected to                     
====================================================================================================
encoded (Dense)                  (None, Enc_dim)          33000       dense_input_1[0][0]              
____________________________________________________________________________________________________
tieddense_1 (TiedtDense)          (None, Out_Dim)            0           encoded[0][0]                    
====================================================================================================
Total params: 33,000
Trainable params: 33,000
Non-trainable params: 0
________________________________________________________________________


class TiedtDense(Dense):
def __init__(self, output_dim, master_layer, init='glorot_uniform', activation='linear', weights=None,
             W_regularizer=None, b_regularizer=None, activity_regularizer=None,
             W_constraint=None, b_constraint=None, input_dim=None, **kwargs):
    self.master_layer = master_layer
    super(TiedtDense, self).__init__(output_dim, **kwargs)

def build(self, input_shape):
    assert len(input_shape) >= 2
    input_dim = input_shape[-1]
    self.input_dim = input_dim


    self.W = tf.transpose(self.master_layer.W)
    self.b = K.zeros((self.output_dim,))
    self.params = [self.b]
    self.regularizers = []
    if self.W_regularizer:
        self.W_regularizer.set_param(self.W)
        self.regularizers.append(self.W_regularizer)

    if self.b_regularizer:
        self.b_regularizer.set_param(self.b)
        self.regularizers.append(self.b_regularizer)

    if self.activity_regularizer:
        self.activity_regularizer.set_layer(self)
        self.regularizers.append(self.activity_regularizer)

    if self.initial_weights is not None:
        self.set_weights(self.initial_weights)
        del self.initial_weights
+9
source share
1 answer

More than two years have passed since this question was asked, but this answer may still be relevant for some.

The function Layer.get_weights()extracts from self.trainable_weightsand self.non_trainable_weights(see Keras.engine.base_layer.Layer.weights ). In your custom layer of your weight self.Wand self.bdo not add any of these collections, and that is why layer has 0 parameters.

:

class TiedtDense(Dense):
    def __init__(self, output_dim, master_layer, **kwargs):
        self.master_layer = master_layer
        super(TiedtDense, self).__init__(output_dim, **kwargs)

    def build(self, input_shape):
        assert len(input_shape) >= 2
        input_dim = input_shape[-1]
        self.input_dim = input_dim

        self.kernel = tf.transpose(self.master_layer.kernel)
        self.bias = K.zeros((self.units,))
        self.trainable_weights.append(self.kernel)
        self.trainable_weights.append(self.bias)

: . , , keras.engine.base_layer.Layer.add_weight.

0

Source: https://habr.com/ru/post/1655018/


All Articles