如何在已保存的Keras顺序模型中添加新类

时间:2018-07-24 12:26:11

标签: keras deep-learning conv-neural-network image-recognition

我有10个类别的数据集,因此我的准确率达到了85%,在保存的模型上达到了相同的准确度。 现在我想添加一个新类,如何向保存的模型中添加一个新类。 我尝试删除最后一层并进行训练,但是模型变得过拟合,并且在预测中,每个Images都显示相同的结果(新添加的类)。

这就是我所做的

model.pop()
base_model_layers = model.output
pred = Dense(11, activation='softmax')(base_model_layers)
model = Model(inputs=model.input, outputs=pred)
# compile and fit step

我已经训练了10类的模型,我想用11类的数据加载模型火车并给出预测。

3 个答案:

答案 0 :(得分:1)

model.pop()

base_model_layers = model.output
pred = Dense(11, activation='softmax')(base_model_layers)
model = Model(inputs=model.input, outputs=pred)

在训练之前先冻结第一层

for layer in model.layers[:-2]:
    layer.trainable = False

答案 1 :(得分:1)

使用 model.pop()方法,然后使用 Keras Model()API ,将导致您出现错误 Model()API没有.pop()方法,因此,如果您想多次重新训练模型,则会出现此错误。

但是,仅当您在重新训练后保存模型并在下一次重新训练中使用新保存的模型时,才会发生错误。

另一种非常错误且使用过的方法是使用 model.layers.pop()。这次的问题是该函数仅删除它返回的副本中的最后一层。因此,模型仍然具有该层,而方法的返回不具有该层。

我推荐以下解决方案:

承认您已将已经训练好的模型保存在模型变量中,例如:

model = load_my_trained_model_function()

# creating a new model
model_2 = Sequential()

# getting all the layers except the output one
for layer in model.layers[:-1]: # just exclude last layer from copying
    model_2.add(layer)

# prevent the already trained layers from being trained again 
# (you can use layers[:-n] to only freeze the model layers until the nth layer)
for layer in model_2.layers:
    layer.trainable = False

# adding the new output layer, the name parameter is important 
# otherwise, you will add a Dense_1 named layer, that normally already exists, leading to an error
model_2.add(Dense(num_neurons_you_want, name='new_Dense', activation='softmax'))

现在,您应该指定编译和拟合方法以训练模型并完成:

model_2.compile(loss='categorical_crossentropy',
                optimizer='adam',
                metrics=['accuracy'])

# model.fit trains the model
model_history = model_2.fit(x_train, y_train,
                            batch_size=batch_size,
                            epochs=epochs,
                            verbose=1,
                            validation_split=0.1)

编辑:

请注意,通过添加新的输出层,我们在上次培训中没有调整权重和偏差。

因此,我们几乎失去了之前培训中的所有内容。

我们需要保存以前训练的输出层的权重和偏差,然后将它们添加到新的输出层。

我们还必须考虑是否应该对所有层进行训练,或者是否只允许对某些插入层进行训练。

要使用Keras从输出层获取权重和偏差,我们可以使用以下方法:

# weights_training[0] = layer weights
# weights_training[1] = layer biases
weights_training = model.layers[-1].get_weights()

现在,您应该为新的输出层指定权重。例如,您可以使用权重平均值作为新类的权重。由你决定。

要使用Keras设置新输出层的权重和偏差,我们可以使用以下方法:

model_2.layers[-1].set_weights(weights_re_training)

答案 2 :(得分:1)

我假设问题是单标签多类分类,即一个样本将仅属于11个类中的一个。

这个答案将完全基于实现人类学习机器的方式。因此,这不会为您提供执行该操作的正确代码,但是会告诉您该怎么做,并且您将能够轻松地在keras中实现它。

一个人的孩子在教他新事物时如何学习?首先,我们要求他忘记旧事物并学习新事物。这实际上并不意味着旧的学习是无用的,而是意味着在他学习新知识的时候,旧知识不应受到干扰,因为它将使大脑混乱。因此,孩子只会在一段时间内学习新知识。

但是这里的问题是,事情是相关的。假设孩子学习了C编程语言,然后学习了编译器。编译器和编程语言之间存在联系。如果孩子单独学习这些学科,他们将无法掌握计算机科学,对吗?至此,我们引入了“智能”一词。

了解自己以前学到的东西与现在所学到的东西之间存在联系的孩子是“智能”。发现这两者之间存在实际联系的孩子是“聪明的”。 (深入了解这是没有主题的)

我想说的是:

  • 让模型分别学习新课程。
  • 然后,使模型找到先前学习的类和新类之间的关系。

为此,您需要训练两种不同的模型:

  1. 该模型将学习在新类上进行分类:该模型将是一个二进制分类器。如果样本属于第11类,则预测为1,否则为0。现在,您已经具有属于第11类的样本的训练数据,但是可能没有属于第11类的样本的训练数据。为此,您可以随机选择属于1至10类的样本。为了正确训练模型,属于11类的样本与不属于11类的样本之比必须为1:1。这意味着50%的样本必须属于11类。
  2. 现在,您有两个单独的模型:一个模型预测1-10类,另一个模型预测11类。现在,将这两个模型(最后第二层)的输出与一个新创建的具有11个节点的Dense层连接起来然后让整个模型重新训练自己,以调整预训练的两个模型的权重并学习密集层的新权重。保持低学习率。

最终模型是第三个模型,它是两个模型(没有最后一个Dense层)+一个新的Dense层的组合。

谢谢..