如何利用predict/predict_generator对测试数据进行预测?
采用预训练+微调的形式处理文件夹图像数据,常常使用ImageDataGenerator与flow_from_directory函数实现对文件夹内数据的增广扩充,用fit_generator函数训练扩充的数据(参考前述博客:https://blog.csdn.net/zhenyu_an/article/details/88621702)。那在训练后,如何预测单个图像的类别呢?有两种情况:
(1)一般而言,如果是对测试集中数据,假如测试数据生成为
// An highlighted block
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
那么,可以直接用predict_ generator函数处理测试图像,因此,如果我们在test_datagen中不打乱顺序的话(shuffle=Flase),则给出的预测结果与文件顺序是一致的。当然,即便打乱顺序,也是可以知道真实类别值的。
Labels=validation_generator.class_indices函数可以给出当前类别的真实值,Filenames = validation_generator.filenames给出对象的文件名。在以上知道文件名和类别真实值之后,直接使用predict_generator可以预测,并比较结果。
// An highlighted block
Pred = model.predict_generator(validation_generator, verbose=1)
(2)第二种情况,如果我们的预测对象是单个图像,无法通过generator函数生成,则需要通过直接读入图像,进行归一化(仅针对我的github中处理MSTAR数据代码)后,在利用训练好的模型通过predict函数直接预测。以https://github.com/azy1988/ML-CV/tree/master/MSTAR_ATR中sar_recog.py文件里面的模型为例,我们给出一个训练好的model2如何对单个图像进行识别,直接给出代码如下:
// 预测单个图片类别
from PIL import Image
import cv2
image = Image.open('C:\\Users\\Lenovo\\Desktop\\test\\2S1.jpg')
test = cv2.resize(np.array(image),(200,200))
test = test.astype('float32')
test = np.reshape(test,(1,200,200))
r = test;
g = test;
b = test;
rgb = np.vstack((r,g,b))
rgb = rgb/255.0
predict = model2.predict(rgb)
predict=np.argmax(predict,axis=1)
print(predict)
介绍下写这段代码时我碰到的一个小坑。
现象及原因:
由于在原始sar_recog.py中,我指定了采用theano作为keras后端(py文件的第23行),导致我的模型输入需要是shape=(3,img_width, img_height)的形式。而MSTAR图像均为单通道灰度图像,因此需要将单通道转换为RGB三通道。常规思路是采用cv2库中的cvtColor进行转换,然后再numpy中进行维度变换即可。
// 灰度转换为RGB
img_rgb = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB)
悲剧在这时发生了,RGB图像在python中是以(img_width, img_height, 3)的维度形式存放,不满足模型输入,因此只能转化为numpy数组,再reshape。但显然,这种reshape方式,已经不能保证每个通道中图片的完整性了,也就是说,直接reshape,打散了图片的行列格式。这时,无论模型在fit_generator还是predict_generator都可以达到很好效果,但在单个图片直接读入python预测时,都会出错。
解决方法:
解决方法很简单,就是不使用reshape函数,而是将每个通道都分别赋值给r g b,再利用vstack进行重组,这样才保证了图像的结构不被打散,结果就正确了。