Keras:融合不同的模型并使用自己的数据进行fine-tuning及预测(二)

上篇文章我们已经训练且得到了可以用于分类的模型:

那么接下来如何预测呢?

其实,大体上预测和训练和差不多的,因此你可以对照训练的时候来写预测程序!核心思想:在训练的时候用了几个模型来融合,测试的时候就用几个;并且模型融合的顺序是不能变的!


一.提取特征

a.修改保存特征代码

对测试图片也是需要提取特征的,但是这个时候是没有label标签的,标签就是需要我们预测的,因此保存为H5时,应修改代码为:

    test = model.predict_generator(test_generator, test_generator.samples//test_generator.batch_size)
    with h5py.File("newmaptest_%s.h5" % MODEL.__name__) as h:
        h.create_dataset("test", data=test)


b.修改图片生成器ImageDataGenerator

由于此时已经不要ImageDataGenerator来进行数据增强,而仅仅只是用来传递文件而已!所以,应修改为:
    gen = ImageDataGenerator()

    test_generator = gen.flow_from_directory(testdir, image_size, shuffle=False,
                                             batch_size=batch_size, class_mode=None)


c.将以上步骤写成函数复用

def get_feature(MODEL, image_size, lambda_func=None):
    width = image_size[0]
    height = image_size[1]
    input_tensor = Input((height, width, 3))
    x = input_tensor
    if lambda_func:
        x = Lambda(lambda_func)(x)
    base_model = MODEL(input_tensor=x, weights='imagenet', include_top=False)
    model = Model(base_model.input, GlobalAveragePooling2D()(base_model.output))

    gen = ImageDataGenerator()

    test_generator = gen.flow_from_directory(testdir, image_size, shuffle=False,
                                             batch_size=batch_size, class_mode=None)

    test = model.predict_generator(test_generator, test_generator.samples//test_generator.batch_size)
    with h5py.File("newmaptest_%s.h5" % MODEL.__name__) as h:
        h.create_dataset("test", data=test)


d.得到测试图片的特征

用训练模型时候的4个预训练模型来提取特征:
  • ResNet50
  • VGG19
  • InceptionResNetV2
  • Xception
print("正在提取第1个特征")  
get_feature(ResNet50, (224, 224))  
print("特征1已就绪")  
# # #  
print("正在提取第2个特征")  
get_feature(Xception, (299, 299), xception.preprocess_input)  
print("特征3已就绪")  
#  
print("正在提取第3个特征")  
get_feature(InceptionResNetV2, (299, 299), inception_resnet_v2.preprocess_input)  
print("特征4已就绪")  
  
print("正在提取第4个特征")  
get_feature(VGG19, (224, 224))  
print("特征5已就绪")
具体文件名为:

  • newmaptest_InceptionResNetV2.h5
  • newmaptest_VGG19.h5
  • newmaptest_ResNet50.h5
  • newmaptest_Xception.h5

二.载入特征文件以及模型


a.载入特征文件

np.random.seed(1993)

X_test = []

for filename in ["newmaptest_InceptionResNetV2.h5", "newmaptest_VGG19.h5", "newmaptest_ResNet50.h5", "newmaptest_Xception.h5"]:
    with h5py.File(filename, 'r') as h:
        X_test.append(np.array(h['test']))

X_test = np.concatenate(X_test, axis=1)


b.加载模型

model = load_model('my_model.h5')
y_pred = model.predict(X_test, verbose=1)


gen = ImageDataGenerator()
test_generator = gen.flow_from_directory(testdir, (224, 224), shuffle=False,
                                         batch_size=batch_size, class_mode=None)

三.进行预测


a.创建不同类别的文件夹,用以存放分类结果

在这里,我们只需要创建‘dogs’和‘cats’两个文件夹即可:

if os.path.exists(targetDir):
    input("文件夹已存在,请重新创建新文件夹!\n键入任意键以关闭")
    raise ValueError("正在关闭")
else:
    os.mkdir(targetDir)#创建地图文件夹

if os.path.exists(nottargetDir):
    input("文件夹已存在,请重新创建新文件夹!\n键入任意键以关闭")
    raise ValueError("正在关闭")
else:
    os.mkdir(nottargetDir)#创建非地图文件夹


b.得到预测的概率,并且设定分类阈值

对每一个不同的图片,都会由上面得到的模型输出一个0-1的概率值,既然只有两类图片,我们就只需要设定阈值threshold=0.5即可;

y_pred = model.predict(X_test, verbose=1)


c.将概率值P>0.5和P<0.5的两类分别移动到a中所创建的文件夹中

for i, fname in enumerate(test_generator.filenames):
    print(i, fname)
    filename.append(fname)
    prediction.append(float(y_pred[i]))

    if y_pred[i] >= 0.5:#训练模型中的第二类
        sourceDir = os.path.join(testdir,  fname)
        shutil.copy(sourceDir, nottargetDir)
    elif y_pred[i] < 0.5:#训练模型中的第一类
        sourceDir = os.path.join(testdir,  fname)
        shutil.copy(sourceDir, targetDir)


d.将每一个图片预测的概率值保存为一个Excel:

cc = {'filename': filename, 'prediction': prediction}
aa = pd.DataFrame(cc)
aa.to_excel(exceldir)

猜你喜欢

转载自blog.csdn.net/qq_15969343/article/details/79977137