如何使用Functional API将层添加到现有的Keras模型中?

5

我正在尝试使用Keras模型API来修改已训练的模型,以便在运行时进行微调:

一个非常基本的模型:

inputs = Input((x_train.shape[1:]))
x = BatchNormalization(axis=1)(inputs)
x = Flatten()(x)
outputs = Dense(10, activation='softmax')(x)
model1 = Model(inputs, outputs)
model1.compile(optimizer=Adam(lr=1e-5), loss='categorical_crossentropy', metrics=['categorical_accuracy'])

它的架构是

InputLayer ->  BatchNormalization -> Flatten -> Dense

在我对其进行一些训练批次后,我想在Flatten层和输出之间添加一些额外的Dense层:

x = Dense(32,activation='relu')(model1.layers[-2].output)
outputs = model1.layers[-1](x)

然而,当我运行它时,我得到了这个:

ValueError: Input 0 is incompatible with layer dense_1: expected axis -1 of input 
shape to have value 784 but got shape (None, 32)

发生了什么事情,我如何/是否可以向已经训练好的模型添加层?

1个回答

6
一个密集层被严格用于特定的输入维度,定义完成后该维度无法更改(这将需要不同数量的权重)。因此,如果您真的想在已使用的密集层之前添加层,则需要确保最后一个新层的输出与“flatten”的输出具有相同的形状。(它表示您需要784,因此您的新的最后一个密集层需要784个单元)。
另一种方法 由于正在添加中间层,因此保留最后一层是毫无意义的:它是针对特定输入进行过训练的,如果更改输入,则需要重新训练。既然您必须重新训练它,为什么还要保留它呢?只需创建一个适合您的新层先前的形状就好了。

现在很清楚了,太好了。我明白这可以应用于密集或卷积层,但是 BatchNorm 和 Dropout 不会影响输出形状,所以它们可以插入到模型中,对吧? - vladimir.gorea
1
是的。但是卷积层支持空间维度的可变输入形状(只有过滤器必须固定)。而且,由于您正在处理图像(MNIST,对吧?),如果使用input_shape =(None,None,1),除了获得更好的结果外,您还将能够做您想要的事情。 - Daniel Möller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接