贝叶斯分类,mnist手写体,提取数据、训练、测试,最终识别率83.68 %

本文介绍了一种基于MNIST数据集的手写数字识别方法,通过构建像素概率模型实现贝叶斯分类,提供了完整的Python代码实现及测试结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不说废话,也不解释原理了,请自行搜索。上代码!

# -*- coding: utf-8 -*-
import cv2
import numpy
import os
import time

for num in range(10):
    codebook_for_pixal=[]  #定义像素编码本
    for i in range(28):
        for j in range(28):
            codebook_for_pixal.append([])  #定义编码本结构,使编码本一维化

    path=r'/home/waking/Desktop/python/mnist/train/'+str(num)+'/'
    file_list=os.listdir(path)   #os.listdir()函数得到的是仅当前路径下的文件名,不包括子目录中的文件,所有需要使用递归的方法得到全部文件名。
    file_nums=len(file_list)  #用于展示百分比的的基数


    show_num=0               #用于展示百分比的的分子
    for filename in file_list:
        show_num+=1
        run_count=show_num/file_nums*100
        print(str(num)+'赋值列表运行完成:'+str(round(run_count,2))+'%')   #输出进度显示,round是四舍五入函数
        if run_count==100:
            print('~~~~~~~~~~~~~~~~~~~~~~~~~~~赋值列表已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
        image = cv2.imread(path+filename)
        #####灰度值版##############
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        ######二值化版############################
        # ret,thresh = cv2.threshold(gray,127,255,0)  #二值化函数
        count_num=0
        for i in range(28):
            for j in range(28):
                pixal_value=gray[i][j]   #获取像素值
                codebook_for_pixal[count_num].append(pixal_value)  #编码本赋值
                count_num+=1  #列表索引累加器,例遍编码本列表作用

    with open(r'/home/waking/Desktop/python/mnist/'+str(num)+'_codebook_for_pixal.txt','w') as f:
        f.write(str(codebook_for_pixal))
    print('~~~~~~~~~~~~~~~~~~~~~~~~~~~列表文件写入文件已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')

    with open(r'/home/waking/Desktop/python/mnist/'+str(num)+'_codebook_for_pixal.txt','r') as f:
        list_readed=f.read()
    print(str(num)+'读取文件结束:'+str(time.time()))
    codebook_for_pixal=eval(list_readed)
    print(str(num)+'翻译文件完毕:'+str(time.time()))


    codebook_for_pixal_dict=[]  #定义像素字典编码本
    for i in range(28):
        for j in range(28):
            codebook_for_pixal_dict.append({})  #定义字典编码本结构
    count_dict_num=0   #用于列表中字典的索引计数
    show_dic_num=0
    list_nums=len(codebook_for_pixal)
    print(str(num)+'开始赋值')

    for list_in_book in codebook_for_pixal:

        show_dic_num+=1
        run_count2=show_dic_num/list_nums*100
        print(str(num)+'赋值字典运行完成:'+str(round(run_count2,2))+'%')   #输出进度显示,round是四舍五入函数
        # print(show_dic_num)
        if run_count2==100:
            print('~~~~~~~~~~~~~~~~~~~~~~~~~~~赋值字典已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
        for pix_value_for_count in range(256):
            # print(time.time())
            count_result=list_in_book.count(pix_value_for_count)
            codebook_for_pixal_dict[count_dict_num][pix_value_for_count]=(count_result+1)/(file_nums+1)    #给像素统计字典赋值,直接求出每个像素值的概率(频率),但分子分母都要加上1(好像叫拉普拉斯常数)为了防止,有零的出现,要是为零,那么以后的相乘就没有意义了
        count_dict_num+=1


    with open(r'/home/waking/Desktop/python/mnist/'+str(num)+'_codebook_for_pixal_dict.txt','w') as f:
        f.write(str(codebook_for_pixal_dict))




    print('~~~~~~~~~~~~~~~~~~~~~~~~~~~字典写入文件已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
# print(codebook_for_pixal)


# print(gray[0][0])
# image[0][0][0]=8
# image[0][0][1]=8
# image[0][0][2]=8
# print(image[0][0])

# -*- coding: utf-8 -*-

from PIL import Image
import struct
import time
import os
path_num_pic_in=r'/home/waking/Desktop/python/mnist/'
for num_dir in range(10):
    if os.path.exists(path_num_pic_in+str(num_dir)):
        print('文件夹已经存在')
    else:
        os.makedirs(path_num_pic_in+str(num_dir))        #生成10个以数字命名的文件夹


def extract_save_mnist(filename_pics,filename_labels):
    index = 0
    index2 = 0
    with open(filename_pics, 'rb') as f:
        buf=f.read()
    with open(filename_labels, 'rb') as f2:
        buf2=f2.read()
    magic, labels = struct.unpack_from('>II' , buf , index)  #读出有多少个标签,为以后循环定量。
    index2 += struct.calcsize('>II')   #索引跟随
    magic, images, rows, columns = struct.unpack_from('>IIII' , buf , index)
    index += struct.calcsize('>IIII')


    for i in range(labels):
        image = Image.new('L', (columns, rows))
        for x in range(rows):    ## 把一维的数据赋值到二维中,每次读取一个byte,付给一个像素值 struct函数解码的应该是列表形式所以用[0]提取)
            for y in range(columns):
                image.putpixel((y, x), int(struct.unpack_from('>B', buf, index)[0]))
                index += struct.calcsize('>B')   #索引计数用的,主要方便记录读取到哪一个数据值了。
        label_num= struct.unpack_from('>B', buf2, index2)[0]   ##这个本身就是int类型的了,就没必要加int()了。
        index2 += struct.calcsize('>B')  #索引跟随
        image.save(path_num_pic_in+str(label_num)+'/'+str(label_num)+'_'+str(time.time()) + '.png')
if __name__ == '__main__':
    extract_save_mnist(r't10k-images.idx3-ubyte',r't10k-labels.idx1-ubyte')
# -*- coding: utf-8 -*-
import cv2
import numpy
import os
import time
from decimal import Decimal   #引用python高精度模块

def list_multiply(one_list):      #列表内所有元素相乘函数
    res=Decimal('1')                 #高精度模块赋值
    for i in one_list:
        i=Decimal(str(i))            #把列表中的数字也变成高精度模块数字,注意输入的是字符串形式,Python里传参基本都是字符串模式,因为没有真正意义的二进制,都是底层转换
        res*=i
    return res
###############定义几个常量############################################
final_test_dict={}      #建立一个测试结果字典,存放最终测试结果
model_list_list=[]    #用于存放模型list的list,节省读取文件时间,但是占用大量内存,试试!
##################一次性批量读取文件,并赋予列表值,节省运行时间######################

for num in range(10):
        with open(r'/home/waking/Desktop/python/mnist/model/'+str(num)+'_codebook_for_pixal_dict.txt','r') as f:
            model_readed=f.read()  #读数据
        eval_time_1=time.time()
        model_list=eval(model_readed) #把字符串数据翻译成列表数据
        eval_time_2=time.time()
        time_eval_diff=eval_time_2-eval_time_1
        print('eval所用时间为:'+str(time_eval_diff))
        model_list_list.append(model_list)
#################################################################################


for test_num in range(10):     #例遍每一个 test 测试数据的文件夹了(0----9)
    path=r'/home/waking/Desktop/python/mnist/test/'+str(test_num)+'/'


    file_list=os.listdir(path)   #os.listdir()函数得到的是仅当前路径下的文件名,不包括子目录中的文件,所有需要使用递归的方法得到全部文件名。
    file_nums=len(file_list)  #用于展示百分比的的基数

    #####最终测试用的变量定义################

    test_fail_num=0            #定义测试数据中没有识别准确的数字个数
    total_test_nums=file_nums
    ########################################

    show_num=0               #用于展示百分比的的分子
    for filename in file_list:

        show_num+=1
        # run_count=show_num/file_nums*100
        # print('赋值列表运行完成:'+str(round(run_count,2))+'%')   #输出进度显示,round是四舍五入函数
        # if run_count==100:
        #     print('~~~~~~~~~~~~~~~~~~~~~~~~~~~赋值列表已完成~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
        print('测试图片:~~~'+str(show_num))
        image = cv2.imread(path+filename)
        #####灰度值版##############
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        index_list=[]          #用于存放每个数字模型对应的图片总概率值
        for num in range(10):
            # with open(r'/home/waking/Desktop/python/mnist/model/'+str(num)+'_codebook_for_pixal_dict.txt','r') as f:
            #     model_readed=f.read()  #读数据
            # eval_time_1=time.time()
            # model_list=eval(model_readed) #把字符串数据翻译成列表数据
            # eval_time_2=time.time()
            # time_eval_diff=eval_time_2-eval_time_1
            # print('eval所用时间为:'+str(time_eval_diff))
            print('正在测试模型'+str(num))
            model_list=model_list_list[num]
            count_dict_num=0   #用于列表中字典的索引计数
            pic_probability_list=[]   #用于收集本图片,所有像素值的概率
            for i in range(28):
                for j in range(28):
                    pixal_value=gray[i][j]   #获取像素值
                    model_dict=model_list[count_dict_num]  #获取像素位置的各个像素值概率的字典
                    # print(model_dict)
                    value_probability=model_dict[pixal_value]  #获取本图片像素值在模型中的概率
                    # print(value_probability)
                    pic_probability_list.append(value_probability)
                    count_dict_num+=1
            # print('求得的概率列表元素个数为:'+str(len(pic_probability_list)))
            # print(pic_probability_list)
            pic_probability_value=list_multiply(pic_probability_list)    #列表所有元素相乘,得到改图片在对应模型中的概率值
            # print(len(pic_probability_list))
            # print('#######################::::::'+str(pic_probability_value))
            index_list.append(pic_probability_value)
        final_num=index_list.index(max(index_list))   #找到列表里最大概率值的所在列表中的位置,这里也巧,也就是对应的数字值
        if final_num==test_num:
            pass
        else:
            test_fail_num+=1
        # print('对应的概率为:'+str(index_list))
        print('测试文件夹为:'+str(test_num)+'~~~~~~~~~~~~~~~~~~~~最终经过贝叶斯分类得到的值为:~~~~~~~~~~~~~~~~~~'+str(final_num))
    accuracy_rate_test=(total_test_nums-test_fail_num)/total_test_nums*100
    print('数字'+str(test_num)+'测试的准确率为:'+str(accuracy_rate_test)+' %')
    final_test_dict['数字'+str(test_num)+'测试的准确率']=str(accuracy_rate_test)+' %'
print(final_test_dict)
with open(r'/home/waking/Desktop/python/mnist/final_test_result.txt','w') as f:
    f.write(str(final_test_dict))




共三段代码,路径问题自己定义,有问题请留言,大家一起讨论,吃饭去了,拜!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

弗洛伊佛

如果能启发到您,请给点动力,谢

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

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

打赏作者

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

抵扣说明:

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

余额充值