如何在保存的 keras 序列模型中添加新类 [英] How add new class in saved keras sequential model

查看:38
本文介绍了如何在保存的 keras 序列模型中添加新类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是我做的

model.pop()base_model_layers = 模型.输出pred = Dense(11, activation='softmax')(base_model_layers)模型=模型(输入=模型.输入,输出=预测)# 编译和拟合步骤

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

解决方案

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

但是只有在重新训练后保存模型并在下一次重新训练中使用新保存的模型时才会出现错误.

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

我推荐以下解决方案:

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

model = load_my_trained_model_function()# 创建一个新模型模型_2 = 顺序()# 获取除输出层以外的所有层for layer in model.layers[:-1]: # 只从复制中排除最后一层model_2.add(层)# 防止已经训练好的层再次被训练#(你可以使用layers[:-n]来只冻结模型层直到第n层)对于 model_2.layers 中的层:layer.trainable = 假# 添加新的输出层,name参数很重要# 否则,您将添加一个 Dense_1 命名层,该层通常已经存在,从而导致错误model_2.add(Dense(num_neurons_you_want, name='new_Dense', activation='softmax'))

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

model_2.compile(loss='categorical_crossentropy',优化器='亚当',指标=['准确度'])# model.fit 训练模型model_history = model_2.fit(x_train, y_train,批量大小=批量大小,时代=时代,详细=1,验证_拆分=0.1)

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

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

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

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

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

# weights_training[0] = 层权重# weights_training[1] = 层偏差weights_training = model.layers[-1].get_weights()

现在您应该指定新输出层的权重.例如,您可以将权重的平均值用于新类的权重.这取决于你.

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

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

I have 10 class dataset with this I got 85% accuracy, got the same accuracy on a saved model. now I want to add a new class, how to add a new class To the saved model. I tried by deleting the last layer and train but model get overfit and in prediction every Images show same result (newly added class).

This is what I did

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

I have trained model with 10 class I want to load the model train with class 11 data and give predictions.

解决方案

Using the model.pop() method and then the Keras Model() API will lead you to an error. The Model() API does not have the .pop() method, so if you want to re-train your model more than once you will have this error.

But the error only occurs if you, after the re-training, save the model and use the new saved model in the next re-training.

Another very wrong and used approach is to use the model.layers.pop(). This time the problem is that function only removes the last layer in the copy it returns. So, the model still has the layer, and just the method's return does not have the layer.

I recommend the following solution:

Admitting you have your already trained model saved in the model variable, something like:

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

Now you should specify the compile and fit methods to train your model and it's done:

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)

EDIT:

Note that by adding a new output layer we do not have the weights and biases adjusted in the last training.

Thereby we lost pretty much everything from the previous training.

We need to save the weights and biases of the output layer of the previous training, and then we must add them to the new output layer.

We also must think if we should let all the layers train or not, or even if we should allow the training of only some intercalated layers.

To get the weights and biases from the output layer using Keras we can use the following method:

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

Now you should specify the weights for the new output layer. You can use, for example, the mean of the weights for the weights of the new classes. It's up to you.

To set the weights and biases of the new output layer using Keras we can use the following method:

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

这篇关于如何在保存的 keras 序列模型中添加新类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆