人工智能作业:利用KNN实现手写汉字识别

目录

一、数据预处理

1.对文件实现批量改名

         2.将bmp图片转为numpy向量

3.划分训练集和测试集

二、训练,预测

1.训练

2.预测

总结


一、数据预处理

提供的数据集由两个文件夹组成,一个文件夹是“中”,另一个是“国”。每个图片命名如图所示,我的想法是对每个文件夹中的图片改名,使其成为“标签_序号”格式,方便后续划分数据集时填充标签。此处规定汉字“中”标签为0,汉字“国”标签为1。

1.对文件实现批量改名

    def rename(self,path,flag):
        # 批量改名,并设置标签,zhong-0 guo-1
        filelist = os.listdir(path)
        total_num = len(filelist)
        i = 0
        for item in filelist:
            if item.endswith('.bmp'):
                src = os.path.join(os.path.abspath(path), item)
                dst = os.path.join(os.path.abspath(path), str(flag) + '_' + str(i) + '.bmp')
                try:
                    os.rename(src, dst)
                    i += 1
                except:
                    continue
            print('total %d to rename & converted %d bmp' % (total_num, i))

2.将bmp图片转为numpy向量

对图片样本操作时,首先需要读取数据,将其转化为numpy向量,此处也可转化成数组。

原图:

转为向量:

代码:

    def img2vector(self,fileName):
        retMat = np.zeros([14700], int)
        img = Image.open(fileName, "r")
        array = np.array(img.getdata())
        for i in range(len(array)):  # 遍历文件所有行
            for j in range(3):
                retMat[i * 3 + j] = array[i][j]
        return retMat

设置向量长度为14700的原因是:本文的图片全部为70*70的黑白图片,rgb中有三个变量,14700=70*70*3。

3.划分训练集和测试集

首先规定split_rate=0.25,规定从所有图片中选择四分之一作为测试集,剩下的为训练集。

因为不同标签的数据集在两个文件夹中,可以依次对这两个文件夹进行划分,再进行拼接,得到训练集和测试集。

定义read_data方法,main函数调用时分别读取两个文件夹的数据,返回两个文件夹划分好的训练、测试数据。

    def read_data(self,path, split_rate):
        #从数据集中随机选取split_rate*nums作为测试集,剩下的作为训练集,split_rate=0.25
        fileList = os.listdir(path)
        total_num = len(fileList)
        dataSet = np.zeros([total_num, 14700], int)  # 用于存放所有的数字文件
        labels = np.zeros([total_num], str)  # 用于存放对应的标签(与神经网络的不同)
        for i in range(total_num):
            filePath = fileList[i]  # 获取文件名称/路径
            digit = str(filePath.split('_')[0])  # 通过文件名获取标签
            labels[i] = digit  # 直接存放数字,并非one-hot向量
            dataSet[i] = self.img2vector(path + '/' + filePath)  # 读取文件内容

        # split_rate*total_num
        index = [i for i in range(int(split_rate * total_num))]
        index1 = [i for i in range(int(split_rate * total_num), total_num)]
        np.random.shuffle(index)
        np.random.shuffle(index1)
        test_dataSet = dataSet[index]
        test_labels = labels[index]
        train_dataSet = dataSet[index1]
        train_labels = labels[index1]
        return train_dataSet, train_labels, test_dataSet, test_labels
if __name__=='__main__':
    demo = DataPreProcess()
    path = "data_set"
    path1 = path + "/guo"
    path2 = path + "/zhong"
    # demo.rename(path1,1)
    # demo.rename(path2,0)
    train_dataSet1, train_labels1, test_dataSet1, test_labels1 = demo.read_data(path1,0.25)
    train_dataSet2, train_labels2, test_dataSet2, test_labels2 = demo.read_data(path2, 0.25)

二、训练,预测

1.训练

其实很简单,直接调用方法就可以啦。

knn = neighbors.KNeighborsClassifier(algorithm='kd_tree', n_neighbors=8)
# algorithm设置分类器算法为kd_tree,改变n_neighbors的值改变所需要查询的最近邻数目
knn.fit(train_dataSet, train_labels)

2.预测

res = knn.predict(dataSet)  # 对测试集进行预测

error_num = np.sum(res != labels)  # 统计分类错误的数目
num = len(dataSet)  # 测试集的数目
print("Total num:", num, " Wrong num:", \
          error_num, "  WrongRate:", error_num / float(num))

总结

其实预测很鸡肋,自己画出的图片需要画的粗一点才可以预测出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值