将两个训练有素的模型与2个不同的类(数据集)结合起来进行预测

时间:2019-02-06 07:12:48

标签: python keras

我有两个经过预训练和保存的初始模型。

模型1 =具有Imagenet类的初始模型-它可以预测1000个类中的图像。

模型2 =具有我自己的分类法的初始模型(20个类别)-它可以预测20个类别的图像。执行转移学习并保存模型。

我想将两者结合起来以预测1020个类别的图像。

Model1 = inception_v3.InceptionV3(weights='imagenet')

预测1000个类别的图像

predictions1 = Model1.predict(processed_image)

Model2 = InceptionV3(weights='imagenet',
              include_top=False,
              input_shape=(224, 224, 3))

我已经在20堂课上进行过迁移学习。两个模型的输入形状相同。预测20个类别的图像

predictions = Model2.predict_classes(precessed_image)

如何结合2个预训练的初始模型来预测Imagenet类(1000个)和我自己的分类器(20个类)=预测1020个类上的图像?

请给我您的解决方案,以小片段(代码)为例,以更好地理解。我对Keras相当陌生。

2 个答案:

答案 0 :(得分:1)

这里没有正确的答案。例如,您可以做的是通过两个分类器运行图像,并查看其最佳预测具有较高的置信度。其他选择可能是创建一个简单的分类器,通过它您可以运行图像,并且其预测将是二进制的,并会告诉您要使用哪种模型(1-inception,0-your模型)。另一个选择是查看预测分布。例如,如果通过分类器运行一些图像,如果图像中的对象不在这20个类别中,则预测分布将大致平均地分散在几个类别之间,而没有一个类别会脱颖而出,所有类别都会有更多或更少的信心。这通常意味着图像不在分类器的范围内-模型不知道将图像放置在哪里,因为该图像不是它以前见过的对象,所以无法确定。

编辑

让我们说model是简单的二进制分类器,它将图像分类为1中的初始图像,并将图像分类为0中的模型。然后您可以执行以下操作:

# open image
img = Image.open(path_to_image)

if model.predict(img): # positive case (classifier classified img to class '1')
  prediction = inception_model.predict(img)
else: # negative case (classifier classified img to class '0')
  prediction = my_model.predict(img)

现在,预测结果在变量prediction中。在这里,我使用了一个简单的分类器(model)来预测将实际使用哪个模型对图像进行分类(初始或您的模型)。在使用初始状态的情况下,prediction将是1000维矢量,如果使用my_model,则prediction将是20维矢量。但这并不重要,因为无论向量大小如何,您都可以获得最高的预测值。

答案 1 :(得分:0)

您希望将预训练的模型标签与自己的标签结合起来,换句话说,您正在使用新的类扩展预训练的模型。实用的方法是利用迁移学习的基础。

但是让我告诉你,这仍然是一个热门的研究主题。使用您自己的课程进行重新培训比添加其他课程要容易。努力,并非不可能!

您应该做的:一种方法是更改​​最后一个softmax层,以识别比其设计的标签更多的类。 网络手术。您将不得不再次训练模型,这将花费更多时间。

另一种方法是使用所有1020个标签创建一个新的自定义模型,然后在整个数据集上对其进行训练,这种方法效率不高,您无法利用预训练模型的权重,而必须再次进行全面训练。

黑客可以使用已经预测了1000个类的检查点。添加新类的数据。现在,您应该将新类别的数据与Imagenet数据集结合起来,为所有1020个类别创建TFRecords,然后从网络检查点进行训练。

您尝试做的事情叫做“ 学习而不会忘记”。有关如何执行此操作的更多信息,请参阅以下论文。

https://arxiv.org/abs/1606.09282

此处提供了matlab代码。

https://github.com/lizhitwo/LearningWithoutForgetting

您也可以尝试调整以下文件以获得所需的结果。

https://github.com/tensorflow/hub/blob/master/examples/image_retraining/retrain.py

另外, 要获得有关使用预训练模型进行再训练的更多信息,请参考以下链接。

https://www.tensorflow.org/tutorials/images/hub_with_keras

现在来回答,

我们如何做到这一点:

在最终分类层中使用增加的标签数量重建相同的模型,然后从最终层中恢复除最终层之外的所有初始权重,并对模型进行微调。

我们需要为此指定两个标志:

1. --pretrained_model_checkpoint_path
2. --fine_tune

代码将如下所示。

# Build the model. Note that we need to make sure the TensorFlow is ready to
# use before this as this command will not build TensorFlow.
cd tensorflow-models/inception
bazel build //inception:custom_train

# Path to the downloaded Inception-v3 model.
MODEL_PATH="${INCEPTION_MODEL_DIR}/inception-v3/model.ckpt-1456935"

# Directory where the data resides.
DATA_DIR=/tmp/custom-data/

# Directory where to save the checkpoint and events files.
TRAIN_DIR=/tmp/custom_train/

# Run the fine-tuning on the flowers data set starting from the pre-trained
# Imagenet-v3 model.
bazel-bin/inception/flowers_train \
  --train_dir="${TRAIN_DIR}" \
  --data_dir="${DATA_DIR}" \
  --pretrained_model_checkpoint_path="${MODEL_PATH}" \
  --fine_tune=True \
  --initial_learning_rate=0.001 \
  --input_queue_memory_factor=1

有关更多信息,请参阅以下文档。

https://github.com/tensorflow/models/tree/master/research/inception