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