Keras: usar la misma capa en diferentes modelos (compartir pesos)

Respuesta rápida:

De hecho, esto es realmente fácil. Aquí está el código (para aquellos que no quieren leer todo ese texto):

inputs=Input((784,)) encode=Dense(10, input_shape=[784])(inputs) decode=Dense(784, input_shape=[10]) model=Model(input=inputs, output=decode(encode)) inputs_2=Input((10,)) decode_model=Model(input=inputs_2, output=decode(inputs_2)) 

En esta configuración, decode_model utilizará la misma capa de deencoding que el model . Si entrenas el model , el decode_model también será entrenado.

Pregunta actual:

Estoy tratando de crear un codificador automático simple para MNIST en Keras:

Este es el código hasta ahora:

 model=Sequential() encode=Dense(10, input_shape=[784]) decode=Dense(784, input_shape=[10]) model.add(encode) model.add(decode) model.compile(loss="mse", optimizer="adadelta", metrics=["accuracy"]) decode_model=Sequential() decode_model.add(decode) 

Lo estoy entrenando para aprender la función de identidad.

 model.fit(X_train,X_train,batch_size=50, nb_epoch=10, verbose=1, validation_data=[X_test, X_test]) 

La reconstrucción es bastante interesante:

introduzca la descripción de la imagen aquí

Pero también me gustaría ver las representaciones de cluster. ¿Cuál es la salida de pasar [1,0 … 0] a la capa de deencoding? Esta debe ser la “media de agrupación” de una clase en MNIST.

Para hacer eso, creé un segundo modelo decode_model , que reutiliza la capa del decodificador. Pero si trato de usar ese modelo, se queja:

Excepción: error al verificar: se esperaba que dense_input_5 tuviera forma (Ninguna, 784) pero que obtuviera una matriz con forma (10, 10)

Eso parecía extraño. Es simplemente una capa densa, la Matrix ni siquiera podría procesar una entrada de 784 dim. Decidí mirar el resumen del modelo:

 ____________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ==================================================================================================== dense_14 (Dense) (None, 784) 8624 dense_13[0][0] ==================================================================================================== Total params: 8624 

Está conectado a dense_13. Es difícil hacer un seguimiento de los nombres de las capas, pero se parece a la capa del codificador. Efectivamente, el resumen del modelo de todo el modelo es:

 ____________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ==================================================================================================== dense_13 (Dense) (None, 10) 7850 dense_input_6[0][0] ____________________________________________________________________________________________________ dense_14 (Dense) (None, 784) 8624 dense_13[0][0] ==================================================================================================== Total params: 16474 ____________________ 

Aparentemente las capas están conectadas permanentemente. Curiosamente, no hay ninguna capa de entrada en mi decode_model .

¿Cómo puedo reutilizar una capa en Keras? He mirado la API funcional, pero también allí, las capas se fusionan.

Oh no importa.

Debería haber leído la API funcional completa: https://keras.io/getting-started/functional-api-guide/#shared-layers

Aquí está una de las predicciones (tal vez todavía falta algo de entrenamiento): introduzca la descripción de la imagen aquí

Supongo que esto podría ser un 3? Bueno, al menos funciona ahora.

Y para aquellos con problemas similares, aquí está el código actualizado:

 inputs=Input((784,)) encode=Dense(10, input_shape=[784])(inputs) decode=Dense(784, input_shape=[10]) model=Model(input=inputs, output=decode(encode)) model.compile(loss="mse", optimizer="adadelta", metrics=["accuracy"]) inputs_2=Input((10,)) decode_model=Model(input=inputs_2, output=decode(inputs_2)) 

Solo compilé uno de los modelos. Para el entrenamiento necesitas comstackr un modelo, para una predicción que no es necesaria.