如何在已保存的keras序列模型中添加新类

如何在已保存的keras序列模型中添加新类,keras,deep-learning,conv-neural-network,image-recognition,Keras,Deep Learning,Conv Neural Network,Image Recognition,我有10个类的数据集,我有85%的准确率,在保存的模型上也有同样的准确率。 现在我想添加一个新类,如何向保存的模型添加一个新类。 我试图删除最后一层和训练,但模型得到过度拟合,在预测每个图像显示相同的结果(新添加的类) 这就是我所做的 model.pop() base_model_layers = model.output pred = Dense(11, activation='softmax')(base_model_layers) model = Model(inputs=model.in

我有10个类的数据集,我有85%的准确率,在保存的模型上也有同样的准确率。 现在我想添加一个新类,如何向保存的模型添加一个新类。 我试图删除最后一层和训练,但模型得到过度拟合,在预测每个图像显示相同的结果(新添加的类)

这就是我所做的

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类数据加载模型,并给出预测

model.pop()

base_model_layers = model.output
pred = Dense(11, activation='softmax')(base_model_layers)
model = Model(inputs=model.input, outputs=pred)
在训练前冻结第一层
使用model.pop()方法,然后使用Keras model()API将导致出现错误模型()API没有.pop()方法,因此如果要多次重新训练模型,则会出现此错误。

但只有在重新培训后保存模型并在下次重新培训中使用新保存的模型时,才会发生错误。

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

我推荐以下解决方案:

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

model=load\u my\u trained\u model\u function()
#创建新模型
模型_2=顺序()
#获取除输出层之外的所有层
对于模型中的层。层[:-1]:#仅从复制中排除最后一层
模型2.添加(图层)
#防止已训练的图层再次训练
#(可以使用图层[:-n]仅冻结模型图层,直到第n个图层)
对于模型_2.layers中的层:
layer.trainable=错误
#添加新的输出层时,name参数很重要
#否则,您将添加一个通常已经存在的稠密_1命名层,从而导致错误
模型2.add(密集型(num_neurons_you_,name='new'u Dense',activation='softmax'))
现在您应该指定编译和拟合方法来训练您的模型,完成了:

model_2.compile(loss='classifical_crossentropy',
优化器='adam',
指标=[‘准确度’])
#拟合训练模型
模型历史=模型2.拟合(x列车、y列车、,
批次大小=批次大小,
时代,
verbose=1,
验证(拆分=0.1)
编辑:

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

因此,我们几乎失去了上次训练的一切

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

我们还必须考虑是否应该让所有层都训练,或者即使我们只允许训练一些夹层

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

#权重_训练[0]=层权重
#权重_训练[1]=层偏差
权重\训练=模型。层[-1]。获取\权重()
现在,您应该为新输出层指定权重。例如,可以使用新类权重的权重平均值。这取决于你

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

模型2.层[-1]。设置权重(权重重新训练)

我假设问题是单标签多类别分类,即一个样本只属于11个类别中的1个

这个答案将完全基于实现人类学习机器的方式。因此,这不会为您提供一个正确的代码来说明如何做到这一点,但它会告诉您要做什么,并且您将能够轻松地在keras中实现它

当你教一个人类孩子新事物时,他是如何学习的?首先,我们要求他忘记旧的,学习新的。这实际上并不意味着旧的知识是无用的,但它意味着在他学习新知识的时候,旧的知识不应该干扰,因为它会迷惑大脑。因此,孩子只能在一段时间内学习新知识

但问题是,事情是相关的。假设,孩子学习了C编程语言,然后学习了编译器。编译器和编程语言之间存在着某种联系。如果孩子单独学习这些科目,就不能掌握计算机科学,对吗?在这一点上,我们引入了“智力”一词

懂得自己以前学到的东西和现在学到的东西之间存在联系的孩子是“聪明的”。而发现这两件事之间实际关系的孩子是“聪明的”。(深入探讨这一点是离题的)

我想说的是:

  • 让模型单独学习新课程
  • 然后,让模型找到以前学习的班级和新班级之间的关系
为此,您需要培训两种不同的型号:

  • 学习在新类上分类的模型:该模型将是一个二进制分类器。如果样本属于11类,则预测为1;如果不属于11类,则预测为0。现在,您已经有了属于类11的样本的训练数据,但可能没有不属于类11的样本的数据。为此,您可以随机选择属于1到10类的样本。但请注意,属于类别11的样本与不属于类别11的样本的比率必须为1:1,以便正确训练模型。也就是说,50%的样本必须属于11类
  • 现在,你有两个9月
    for layer in model.layers[:-2]:
        layer.trainable = False