图片2分类卷积神经网络模型训练、分类预测案例全过程(2)

上一篇博客内容讲述了卷积神经网络模型构建、训练以及模型的保存,包括训练样本数据的预处理和喂给网络。 本篇博客内容讲述训练好的模型的应用和实际图片数据的分类预测。

图片2分类卷积神经网络模型训练、分类预测案例全过程(2)


前言

训练好的模型的调用和实际图片的分类预测,这里包括数据预处理和模型调用。


# 一、数据预处理

用于开展分类预测的数据量一般不是很大,这里就没有再制作tfrecord格式数据,直接使用文件夹里面的图片开展分类预测。
这里需要一个加载读取单张图片的函数,具体如下。用于后期文件夹中所有图片的读取。

def load_preprocess_image_for_prediction(img_path):
    '''图像加载、预处理for predictation, 参数为图像绝对路径'''
    img_da = tf.io.read_file(img_path)
    img_da = tf.image.decode_jpeg(img_da, channels=3)
    img_da = tf.image.resize(img_da, [256, 256])
    img_da = tf.cast(img_da, tf.float32)
    img_da = img_da/255
    return img_da

二、混淆矩阵计算及其图片绘制

1.混淆矩阵计算

代码如下:

def predict_result_confused_matrix(y_true, y_predict):
    '''混淆矩阵函数
    两个输入参数分别为真实结果、预测结果
    return----t_n              True Negative/真阴性
                f_p              False Positive/假阳性
                f_n              False Negative/假阴性
                t_p              True Postive/真阳性
                accuracy         预测正确的所有结个数所占比例
                precision        精准率
                recall           召回率'''
    t_n, f_p, f_n, t_p = confusion_matrix(y_true, y_predict, labels=None, sample_weight=None, normalize=None).ravel()
    accuracy = round((t_n + t_p)/(t_n + f_p + f_n + t_p), 4)
    precision = round(t_n/(t_n + f_n), 4)
    recall = round(t_n/(t_n + f_p), 4)
    F1_measure = round(2*precision*recall/(precision + recall), 4)
    return [t_n, f_p, f_n, t_p, accuracy, precision, recall, F1_measure]

2.混淆矩阵图片绘制

代码如下:

def draw_confusion_matrix(_input_excel_data, _sheet_name='Predicted_result', dpi_value=100):
    '''_input_excel_data是excel文件的绝对路径
    _sheet_name='Predicted_result是excel文件中存放实测值、预测值的sheet名
    dpi_value是导出的图片的分辨率大小,默认值是100
    混淆矩阵图片导出位置与输入excel文件路径相同'''
    excel_df = pd.read_excel(_input_excel_data, sheet_name=_sheet_name)
    _y_true = excel_df[['True_labels']].values.flatten()
    _y_pred = excel_df[['Predict_labels']].values.flatten()
    _classes = list(set(_y_pred))
    _confusion_matrix_resluts = confusion_matrix(_y_true, _y_pred, labels=None, sample_weight=None, normalize=None).ravel().reshape(2, 2)
    _text_list = [['dis预测为dis','dis预测为undis'],['undis预测为dis','undis预测为undis']]
    
    # 解决plt中文显示乱码问题
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False

    plt.figure(dpi=dpi_value)
    plt.imshow(_confusion_matrix_resluts, cmap=plt.cm.tab20c)
    _indices=range(len(_confusion_matrix_resluts))
    plt.title(str(os.path.basename(_input_excel_data).split(".")[0]), fontsize=13)
    plt.xticks(_indices, _classes, fontsize=12)
    plt.yticks(_indices, _classes, fontsize=12)
    plt.colorbar()
    plt.xlabel('Predict value', fontsize=15)
    plt.ylabel('True value', fontsize=15)
    for first_index in range(len(_confusion_matrix_resluts)):
        for second_index in range(len(_confusion_matrix_resluts[first_index])):
            str1 = _confusion_matrix_resluts[first_index][second_index]
            str2 = _text_list[first_index][second_index]
            strs = str2 + ':' + str(str1)
            plt.text(first_index, second_index, strs, horizontalalignment="center",fontsize=10)
    # plt.show()
    # 生成图片导出的绝对路径
    _path = os.path.dirname(_input_excel_data)
    _name = os.path.basename(_input_excel_data).split(".")[0] + '__混淆矩阵结果' + '.png'
    _png_save_abspath = os.path.join(_path, _name)
    plt.savefig(_png_save_abspath)

在这里插入图片描述

三、模型调用及图片分类预测函数

模型调用我直接写到一个函数中,这样方便使用。具体看如下代码:

def predict_one_folder_images_perbatch_return_results(folder_abspath, predicted_result_save_path, trained_model_abspath, batchSize: int = 128, isKnowClassify: int = 1):
    '''对一个【已知分类的】文件夹图片一个batch一个batch的进行预测,速度更快
    函数返回值如下:
    true_labels                  图片真实标签
    predict_label_list           图片预测标签
    predict_probability_list     图片预测概率
    picture_name_list            图片名称(无后缀)
    result_confused_matrix       混淆矩阵相关计算结果(详见函数confused_matrix)
    ——————————————————————————————————————————————————————————————————————————————————————
    函数参数                      参数含义
    folder_abspath               需要预测图片所在文件夹绝对路径
    predicted_result_save_path   预测分类结果保存路径
    trained_model_path           训练好的模型(.h5)绝对路径
    batchSize                    每批次预测数量的大小,默认值为128
    isKnowClassify               预测的数据真实标签是否知道
                                 如果知道则为1(默认值),如果不知道则为0'''
    index2label = {0: 'dis', 1: 'undis'}
    # 获取预测文件夹下所有文件列表
    imgs_test_folder_path = glob.glob(os.path.join(folder_abspath, '*.jpg'))
    # 获取文件名列表
    picture_name_list = [os.path.basename(a_image).split('.')[0] for a_image in imgs_test_folder_path]
	# 生成预测数据slices
    imgs_ds = tf.data.Dataset.from_tensor_slices(imgs_test_folder_path)
    AUTOTUNE = tf.data.experimental.AUTOTUNE
    # 批量读取并解析预测文件图片
    imgs_ds = imgs_ds.map(load_preprocess_image_for_prediction, num_parallel_calls=AUTOTUNE)
    imgs_ds = imgs_ds.batch(batch_size=batchSize)
	# 加载训练好的模型,可以使用间断点训练结果也可以调用h5文件
    trained_model = tf.keras.models.load_model(trained_model_abspath)
	# 设置两个空列表,一个用于保存预测图片的标签、一个用于保存预测图片的预测概率
    predict_label_list = []
    predict_probability_list = []
	# 分批次循环对所有预测图片进行分类预测
    for i, imgs_batch in enumerate(imgs_ds):
        total_batch = round(len(imgs_test_folder_path)/batchSize, 2)
        processing_batch = round(100*i/total_batch, 2)
        sys.stdout.write('\r程序运行到第{}个batch,总共需要运行{}个batch,进度为{}%......' .format(i, total_batch, processing_batch))
        sys.stdout.flush()

        predict_result = trained_model.predict(imgs_batch)

        for per_predict_result in predict_result:
            probability___dis = per_predict_result[0]
            probability_undis = per_predict_result[1]

            if probability___dis >= probability_undis:
                predict_index = 0
                predict_probability = probability___dis
                predict_label = index2label.get(predict_index)
            else:
                predict_index = 1
                predict_probability = probability_undis
                predict_label = index2label.get(predict_index)
            predict_label_list.append(predict_label)
            predict_probability_list.append(round(predict_probability, 4))
    print()
    saveFileName = '预测分类结果' + get_cunrrent_datetime_mark()
    if isKnowClassify == 1:
        # 如果是分类标签已知的数据
        true_labels = [os.path.basename(a_image).split('_')[0] for a_image in imgs_test_folder_path]
        dis_num = 0
        for one_label in true_labels:
            if one_label == 'dis':
                dis_num += 1
        undis_num = len(true_labels) - dis_num
        # 混淆矩阵结果计算
        result_confused_matrix = predict_result_confused_matrix(true_labels, predict_label_list)
        # 相关预测结果写入到excel
        xls_save_path = os.path.join(predicted_result_save_path, (saveFileName + '.xls'))
        _file = xlwt.Workbook(encoding='utf-8')
        _sheet = _file.add_sheet('Predicted_result', cell_overwrite_ok=True)
        _sheet.write(0, 0, 'True_labels')
        _sheet.write(0, 1, 'Predict_labels')
        _sheet.write(0, 2, 'Predict_probability')
        _sheet.write(0, 3, 'File_name')
        _sheet.write(0, 4, '预测结果')
        for i_xls in range(len(true_labels)):
            _sheet.write(i_xls + 1, 0, str(true_labels[i_xls]))
            _sheet.write(i_xls + 1, 1, str(predict_label_list[i_xls]))
            _sheet.write(i_xls + 1, 2, str(predict_probability_list[i_xls]))
            _sheet.write(i_xls + 1, 3, str(picture_name_list[i_xls]))
            if str(true_labels[i_xls]) == str(predict_label_list[i_xls]):
                _sheet.write(i_xls + 1, 4, '正确')
            else:
                _sheet.write(i_xls + 1, 4, '错误')
        _sheet_1 = _file.add_sheet('混淆矩阵', cell_overwrite_ok=True)
        _sheet_1.write(0, 0, '已知分类数据总共:')
        _sheet_1.write(0, 1, dis_num + undis_num)
        _sheet_1.write(1, 0, '其中dis区域有:')
        _sheet_1.write(1, 1, dis_num)
        _sheet_1.write(2, 0, '其中undis区域有:')
        _sheet_1.write(2, 1, undis_num)
        _sheet_1.write(3, 0, '1、实际为  dis区域,预测为  dis区域个数有:')
        _sheet_1.write(3, 1, str(result_confused_matrix[0]))
        _sheet_1.write(4, 0, '2、实际为  dis区域,预测为undis区域个数有:')
        _sheet_1.write(4, 1, str(result_confused_matrix[1]))
        _sheet_1.write(5, 0, '3、实际为undis区域,预测为undis区域个数有:')
        _sheet_1.write(5, 1, str(result_confused_matrix[3]))
        _sheet_1.write(6, 0, '4、实际为undis区域,预测为  dis区域个数有:')
        _sheet_1.write(6, 1, str(result_confused_matrix[2]))
        _sheet_1.write(7, 0, '预测准确率为:')
        _sheet_1.write(7, 1, str(round(result_confused_matrix[4], 4)))
        _sheet_1.write(8, 0, '预测精确率(查准率)为:')
        _sheet_1.write(8, 1, str(round(result_confused_matrix[5], 4)))
        _sheet_1.write(9, 0, '召回率(查全率)【扰动样本预测为扰动样本】为:')
        _sheet_1.write(9, 1, str(round(result_confused_matrix[6], 4)))
        _sheet_1.write(10, 0, 'F方法值为:')
        _sheet_1.write(10, 1, str(round(result_confused_matrix[7], 4)))
        _file.save(xls_save_path)
        # 生成混淆矩阵图片并导出
        if os.path.exists(xls_save_path):
            draw_confusion_matrix(xls_save_path, 'Predicted_result', 150)

    else:
        # 如果是:分类标签未知的数据
        xls_save_path = os.path.join(predicted_result_save_path, (saveFileName + '.xls'))
        _file = xlwt.Workbook(encoding='utf-8')
        _sheet_2 = _file.add_sheet('预测结果', cell_overwrite_ok=True)
        _sheet_2.write(0, 0, 'Predict_labels')
        _sheet_2.write(0, 1, 'Predict_probability')
        _sheet_2.write(0, 2, 'File_name')
        for i_xls in range(len(predict_label_list)):
            _sheet_2.write(i_xls + 1, 0, str(predict_label_list[i_xls]))
            _sheet_2.write(i_xls + 1, 1, str(predict_probability_list[i_xls]))
            _sheet_2.write(i_xls + 1, 2, str(picture_name_list[i_xls]))
        _file.save(xls_save_path)
        return predict_label_list, predict_probability_list, picture_name_list

四、上述函数的调用及实际图片分类预测

假设有一个文件夹是带有分类标签的,只是用于对训练模型的精度测试,那么上述函数调用如下:
该文件夹的绝对路径为:folder_abspath = r’’
此外,分类预测文件保存路径为predicted_result_save_path,训练好的模型绝对路径为trained_model_abspath
batchsize可根据实际情况自行调整。
这里是已知图片的实际分类标签,所以参数isKnowClassify=1。
调用如下函数即可:

predict_one_folder_images_perbatch_return_results(folder_abspath, predicted_result_save_path, trained_model_abspath, batchSize=128, isKnowClassify=1):

上述分类后保存一个excel分类文件,具体如下。如果是标签未知的情况,也就是isKnowClassify=0的情况,excel表格中就没有第一列和最后一列数据。
在这里插入图片描述

假设有一个文件夹是未知分类的,也就是图片名字中没有分类标签,需要对每个图片的分类进行预测,那么上述函数调用如下:
该文件夹的绝对路径为:folder_abspath = r’’
此外,分类预测文件保存路径为predicted_result_save_path,训练好的模型绝对路径为trained_model_abspath
这里是已知图片的实际分类标签,所以参数isKnowClassify=0。
调用如下函数即可:

predict_one_folder_images_perbatch_return_results(folder_abspath, predicted_result_save_path, trained_model_abspath, batchSize=128, isKnowClassify=0):

总结

上述为训练好的模型进行调用、预测分类的全部操作。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

John H.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值