Decoder die GEWICHTE der Autoencoder mit gebunden GEWICHTE in Keras

Ich habe implementiert eine gebundene GEWICHTE Auto-encoder in Keras und haben erfolgreich trainiert.

Mein Ziel ist es, verwenden Sie nur die decoder-Teil der Auto-encoder die Letzte Schicht von einem anderen Netzwerk, um die Feinabstimmung sowohl die Netzwerk-und die decoder.

Die Sache ist die, wie Sie unten sehen können aus der Zusammenfassung der decoder hat keine Parameter mit gefesselten GEWICHTE Umsetzung, so gibt es nichts zu fein abgestimmt werden. (decoder.get_weights() gibt [])

Meine Frage ist: Sollte ich die Umsetzung des gebundenen GEWICHTE, so dass die gebundene Schicht immer noch halten Sie GEWICHTE, das ist das umgesetzt GEWICHTE der encoder? Wenn ja, wie?

Oder bin ich einfach nur Weg?

Unten ist die Zusammenfassung der autoencoder-Modell als auch die Klasse der gebunden Dichte Schicht (leicht modifiziert aus 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

1 Antworten

  • rvinas
    4. Mai 2019

    Es ist schon mehr als 2 Jahre her seit diese Frage gestellt wurde, aber diese Antwort noch relevant sein könnte für manche.

    Die Funktion Layer.get_weights() ruft aus self.trainable_weights und self.non_trainable_weights (siehe keras.Motor.base_layer.Schicht.GEWICHTE). In Ihrem benutzerdefinierten layer, Ihre GEWICHTE self.W und self.b nicht Hinzugefügt jede dieser Sammlungen, und deshalb ist die Ebene 0 ein Parameter.

    Könnte man optimieren Sie Ihre Implementierung wie folgt:

    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)
    

    HINWEIS: ich bin ohne die regularizers und Einschränkungen für die Einfachheit. Wenn Sie möchten, dass diese, entnehmen Sie bitte keras.Motor.base_layer.Schicht.add_weight.