上篇文章我们已经训练且得到了可以用于分类的模型:
那么接下来如何预测呢?
其实,大体上预测和训练和差不多的,因此你可以对照训练的时候来写预测程序!核心思想:在训练的时候用了几个模型来融合,测试的时候就用几个;并且模型融合的顺序是不能变的!
一.提取特征
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)