Keras:在不同的模型中使用相同的图层(共享权重)

时间:2016-10-27 07:38:48

标签: python machine-learning tensorflow keras

快速回答:

事实上这很容易。 这是代码(对于那些不想阅读所有文本的人):

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))

在此设置中,decode_model将使用与model相同的解码层。 如果您训练modeldecode_model也会接受培训。

实际问题:

我正在尝试为Keras中的MNIST创建一个简单的自动编码器:

这是到目前为止的代码:

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)

我正在训练它以学习身份功能

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

重建非常有趣:

enter image description here

但我还想看一下群集的表示。 将[1,0 ... 0]传递给解码层的输出是多少? 这应该是MNIST中一个类的“集群均值”。

为了做到这一点,我创建了第二个模型decode_model,它重用了解码器层。 但如果我尝试使用该模型,它会抱怨:

  

异常:检查时出错:预期dense_input_5有形状(无,784)但是有形状的数组(10,10)

这看起来很奇怪。它只是一个密集的层,Matrix甚至无法处理784-dim输入。 我决定查看模型摘要:

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

它连接到dense_13。 很难跟踪图层的名称,但这看起来像编码器层。果然,整个模型的模型总结是:

____________________________________________________________________________________________________
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
____________________

显然这些图层是永久连接的。 奇怪的是,decode_model中没有输入图层。

如何在Keras中重复使用图层? 我看过功能API,但也有层融合在一起。

2 个答案:

答案 0 :(得分:5)

哦,没关系。

我应该阅读整个功能API: https://keras.io/getting-started/functional-api-guide/#shared-layers

这是其中一项预测(可能仍缺少一些培训): enter image description here

我猜这可能是3? 好吧,至少它现在有效。

对于有类似问题的人, 这是更新后的代码:

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))

我只编译了其中一个模型。 对于培训,您需要编译模型,以进行不必要的预测。

答案 1 :(得分:0)

可以通过列表model1.layers直接从一个模型访问第二个共享层。棘手的是访问输入层tf.keras.Input(不确定tf.keras.layers.InputLayer,也不建议使用它们),正如我最近看到的那样,这些分配并不那么简单。但是您可以按照定义model1的model1.inputs层的相同顺序通过Input访问输入。您可以建立一个新模型。

in1, in2 = keras.Input(shape=shape1), keras.Input(shape=shape2)
x = Some_Layer(in1)
y1 = Some_Layer(in2)
y2 = Some_model([x, in1, in2])
model1 = Model(inputs=[in1, in2], outputs=[y1, y2])

y3 = Some_model([x, y1])
model2 = Model(inputs=[model1.inputs[0], y1], outputs=[x, y3])