连接Keras模型/替换输入但保留图层

cod*_*ous 4 python deep-learning keras tensorflow

这个问题类似于Keras替换输入层

我有一个分类器网络和一个自动编码器网络,我想使用自动编码器的输出(即编码+解码,作为预处理步骤)作为分类器的输入-但是在分类器已经针对常规数据进行训练之后。

分类网络是使用以下功能性API构建的(基于此示例):

clf_input = Input(shape=(28,28,1))
clf_layer = Conv2D(...)(clf_input)
clf_layer = MaxPooling2D(...)(clf_layer)
...
clf_output = Dense(num_classes, activation='softmax')(clf_layer)
model = Model(clf_input, clf_output)
model.compile(...)
model.fit(...)
Run Code Online (Sandbox Code Playgroud)

像这样的自动编码器(基于此示例):

ae_input = Input(shape=(28,28,1))
x = Conv2D(...)(ae_input)
x = MaxPooling2D(...)(x)
...
encoded = MaxPooling2D(...)(x)
x = Conv2d(...)(encoded)
x = UpSampling2D(...)(x)
...
decoded = Conv2D(...)(x)
autoencoder = Model(ae_input, decoded)
autoencoder.compile(...)
autoencoder.fit(...)
Run Code Online (Sandbox Code Playgroud)

我可以这样连接两个模型(我仍然需要原始模型,因此需要复制):

model_copy = keras.models.clone_model(model)
model_copy.set_weights(model.get_weights())
# remove original input layer
model_copy.layers.pop(0)
# set the new input
new_clf_output = model_copy(decoded)
# get the stacked model
stacked_model = Model(ae_input, new_clf_output)
stacked_model.compile(...)
Run Code Online (Sandbox Code Playgroud)

当我要做的只是将模型应用于新的测试数据时,这种方法非常有用,但是在诸如此类的操作上却出现了错误:

for layer in stacked_model.layers:
    print layer.get_config()
Run Code Online (Sandbox Code Playgroud)

它到达自动编码器的末尾,但随后在分类器模型获得其输入的点失败并显示KeyError。同样在用keras.utils.plot_model我绘制模型时得到这个:

stacked_model

在这里,您可以看到自动编码器层,但是最后,而不是分类器模型中的各个层,一个块中只有完整的模型。

有没有办法连接两个模型,使得新的堆叠模型实际上由所有单独的层组成?

cod*_*ous 5

好的,我能想到的是真正地手动遍历模型的每一层,并再次将它们重新连接,如下所示:

l = model.layers[1](decoded)  # layer 0 is the input layer, which we're replacing
for i in range(2, len(model.layers)):
    l = model.layers[i](l)
stacked_model = Model(ae_input, l)
stacked_model.compile(...)
Run Code Online (Sandbox Code Playgroud)

虽然这可以正常工作并产生正确的图并且没有错误,但这似乎不是最优雅的解决方案...

(顺便说一句,实际上复制模型似乎是不必要的,因为我没有再培训任何东西。)