本篇是对测试集进行测试和相应结果的输出
比赛链接
https://www.tinymind.cn/competitions/47?rron=banner
输入信息
也就是我们的测试集
因为处理测试集的时候,我直接用的keras内置的图片生成器,所以数据需要手动处理一下。
将所有图片放入一个文件夹中,然后在旁边创建两个空文件夹就行,注意都用英文字母。
如下:
需要输出的信息
代码源码
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model
testgen_dir = './val_data/'
#测试集目录
fin_list = [0.1,0.2,0.5,1,2,5,10,50,100]
#相应标签对应的人民币面值
def get_result(directory):
file = open('fin_data.csv','w')
file.write('name, label\n')
end = False # 相当于一个开关,当Ture的时候程序结束
i = 0 #记录测试的图片数目
#创建图片生成器
test_datagen = ImageDataGenerator(
rescale=1. / 255 #归一化
)
test_generator = test_datagen.flow_from_directory(
directory=directory, #地址
target_size=(150, 150),#缩放大小
shuffle=False,#是否打乱顺序
batch_size=100,#一批次的图片数量
)
sample = (len(test_generator.classes)) #文件总数目
model = load_model('face_value.h5')#加载训练好的模型
for img_np_list,label_list in test_generator:
#得到图片特征和标签,这里的标签其实是文件夹名称,在这里没有意义
file_list = test_generator.filenames
#按照顺序获得所有图片的名字(按文件夹顺序)
pre_result_list = model.predict(img_np_list)
#输入图片特征,得出结果
if end == True:
break
for pre_result in pre_result_list:
result_list = pre_result.tolist() #将得到的结果转换为列表形式
label = fin_list[result_list.index(max(result_list))]
#获得对应的面值
try:
file.writelines('{},{}\n'.format(file_list[i][-12:],label))
#将得到的结果写入csv文件
i += 1
process = (i/sample) * 100
process = '进度:{:.2f}'.format(process)
print('{0}的辨别结果为:{1:<4}{2}%'.format(file_list[i][-12:],label,process))
#打印信息,只做监控用,没有实际意义
if (i >= sample):
end = True
break
except IndexError:
end = True
break
print('程序结束,一共{}个图片。'.format(i))
get_result(testgen_dir)
代码解释
输出结果转化为相应面值
当我们使用predict方法的时候,输出的结果可以看成一个大的列表,每个内容对应着每张图片的结果。
比如本篇代码:
pre_result_list = model.predict(img_np_list)
输入的img_np_list 是一百个图片特征值得列表,输出结果如下:
[
[3.55847442e-17 1.35232889e-19 1.00000000e+00 3.86394090e-24
4.66350807e-23 1.02240895e-26 3.57872519e-20 1.11766639e-25
6.87671646e-25]
[2.33116225e-07 1.12874788e-11 6.09181370e-07 2.96100256e-06
9.99995947e-01 2.37595941e-07 2.84623369e-09 6.99930391e-10
1.34186835e-12]
[2.69577765e-17 2.50899472e-18 1.21599753e-14 2.35449077e-20
9.55474129e-16 3.66628864e-21 1.00000000e+00 1.67536224e-15
9.30241652e-15]
[3.00150425e-11 1.00000000e+00 5.10399232e-13 1.05827571e-22
4.41341223e-18 5.25649206e-26 3.30642021e-14 5.78279898e-20
2.68468251e-18]
[1.00152242e-09 5.71124334e-20 8.31621751e-12 1.00000000e+00
1.02401955e-14 5.01156561e-10 5.99297462e-16 4.64759897e-14
3.05958253e-15]
[3.18150001e-07 2.87003519e-15 3.01540553e-07 9.99999166e-01
2.72866920e-11 6.63277859e-08 1.91618926e-11 1.54122395e-10
4.33708278e-12]
[2.39368319e-07 9.99999762e-01 1.89049434e-08 2.35017355e-13
5.28623933e-12 1.30647643e-15 1.90538629e-09 6.80907045e-13
2.46401424e-12]
[4.65856020e-10 9.23405954e-18 1.00000000e+00 1.40767012e-19
2.60643096e-21 2.13745873e-21 3.43351257e-18 1.37466739e-20
1.32132417e-20]
.........
]
[3.55847442e-17 1.35232889e-19 1.00000000e+00 3.86394090e-24 4.66350807e-23 1.02240895e-26 3.57872519e-20 1.11766639e-25 6.87671646e-25]这样一个数就代表这一个图片的识别结果,取其中最大的数,这个就是第三个数,化简一下就是[0,0,1,0,0,0,0,0,0],至于第三个数是什么,这就和我们训练的时候设定的有关系了,把设定的九个值写出来
fin_list = [0.1,0.2,0.5,1,2,5,10,50,100]
可以看出是0.5元,我们只需要获得上边列表中1所在的位置,然后对应到fin_list中就可以了,所以有了下边的函数
for pre_result in pre_result_list:
result_list = pre_result.tolist() #将得到的结果转换为列表形式
label = fin_list[result_list.index(max(result_list))]
#获得对应的面值
打印进度
i += 1
process = (i/sample) * 100
process = '进度:{:.2f}'.format(process)
print('{0}的辨别结果为:{1:<4}{2}%'.format(file_list[i][-12:],label,process))
#打印信息,只做监控用,没有实际意义
sample 是总照片数
process = (i/sample) * 100
就得到了不带百分号的进度,到时候只需要加个百分号就好了
process = '进度:{:.2f}'.format(process)
这是得出的结果保留两位小数点的意思
print('{0}的辨别结果为:{1:<4}{2}%'.format(file_list[i][-12:],label,process))
{1:<4}这个的意思是label的值向左填充4位,因为输出的结果有可能是1,也有可能是0.5,所以他们不齐,只是看起来不舒服
其实这都是字符串格式化的问题,可百度python format 就可以了。
这是打印出来的结果,很整齐
输出结果
得出来的结果就是这个样子,看起来挺不错的,这个比赛的提交窗口已经关了,所以也不知道是多少的正确率,但是我用两千个图片的验证集测试,正确率是100%的。