我有两个经过预训练和保存的初始模型。
模型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)
请给我您的解决方案,以小片段(代码)为例,以更好地理解。我对Keras相当陌生。
答案 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