HDU杭电--机器学习实验报告(五)

一、实验目的

• 1、理解图像识别、手写识别的原理;

• 2、掌握Sklearn实现基于MLP的手写识别;

• 3、掌握Sklearn实现基于KNN的手写识别。

二、实验内容与要求

【实验内容】基于MLP的手写识别

手写数字识别是一个多分类问题,共有10个分类,每个手写数字图像的类别标签是0~9中的其中一个数。例如下面这三张图片的标签分别是0,1,2。

利用sklearn来训练一个简单的全连接神经网络,即多层感知机 (Multilayer perceptron,MLP)用于识别数据集DBRHD的手写数字。

MLP的输入:

DBRHD数据集的每个图片是一个由0或1组成的32*32的文本矩阵; 多层感知机的输入为图片矩阵展开的1*1024个神经元。

MLP输出:“one-hot vectors”

一个one-hot向量除了某一位的数字是1以外其余各维度数字都是0。图片标签将表示成一个只有在第n维度(从0开始)数字为1的10维向量。比如,标签0将表示成[1,0,0,0,0,0,0,0,0,0,0]。即,MLP输出层具有10个神经元。

MLP结构:

MLP的输入与输出层,中间隐藏层的层数和神经元的个数设置都将影响该MLP模型的准确率。在本实验中,只设置一层隐藏层,将在后续实验中比较该隐藏层神经元个数为50、100、200时的MLP效果。

【任务介绍】

本实验利用sklearn来训练一个K最近邻(k-Nearest NeighborKNN)

分类器,用于识别数据集DBRHD的手写数字。比较KNN的识别效果与多层感知机的识别效果。

【KNN手写识别实体构建】

• 步骤1:建立工程并导入sklearn包

• 步骤2:加载训练数据

• 步骤3:构建KNN分类器

• 步骤4:测试集评价

三、实验程序与结果

import numpy as np    
from os import listdir
from sklearn.neural_network import MLPClassifier
from sklearn.neighbors import KNeighborsClassifier
def img2vector(fileName):
    retMat = np.zeros([1024],int)
    fr = open(fileName)    
    lines = fr.readlines()   
    for i in range(32):     
        for j in range(32):  
            retMat[i*32+j] = lines[i][j]
    return retMat
def readDataSet(path):
    '''加载训练数据,并将样本标签转化为one-hot向量'''
    fileList = listdir(path)   
    numFiles = len(fileList)   
    dataSet = np.zeros([numFiles,1024],int)
    hwLabels = np.zeros([numFiles,10])     
    for i in range(numFiles):  
        filePath = fileList[i]
        digit = int(filePath.split('_')[0])
        hwLabels[i][digit] = 1.0     
        dataSet[i] = img2vector(path +'/'+filePath)
    return dataSet,hwLabels
#读取训练集
train_dataSet, train_hwLabels = readDataSet('D:\python\pythonproject\pythonproject1\\trainingDigits')
clf = MLPClassifier(hidden_layer_sizes=(100,),
                    activation='logistic', solver='adam',
                    learning_rate_init = 0.0001, max_iter=2000)
clf.fit(train_dataSet,train_hwLabels)
#KNN
#knn = KNeighborsClassifier(algorithm='kd_tree', n_neighbors=3)
#knn.fit(train_dataSet, train_hwLabels)
#读取测试集
dataSet,hwLabels = readDataSet('D:\python\pythonproject\pythonproject1\\testDigits')
res = clf.predict(dataSet)  
error_num = 0            
num = len(dataSet)    
for i in range(num):   
    if np.sum(res[i] == hwLabels[i]) < 10:
        error_num += 1
print("总数:",num," 错误数量:", \
      error_num,"  错误率:",error_num / float(num))

四、实验结果分析

基于MLP的分析:增加隐藏层神经元个数可能增强MLP模型的学习能力,使其能够更好地捕捉手写数字图像中的特征和模式。但过小的隐藏层神经元个数可能导致模型无法表达足够的复杂性,从而会影响模型的性能;过大的隐藏层神经元个数会导致过拟合。迭代次数影响模型的训练时间和最终收敛状态。

基于KNN的分析:KNN算法中的K值决定了模型考虑的邻居数量,较小的K值可能导致模型对噪声敏感,容易产生过拟合;而较大的K值可能导致模型欠拟合。KNN算法中常用的距离度量方式包括欧氏距离、曼哈顿距离等,不同的距离度量方式可能对模型性能产生影响。

上述实验采用的隐藏层为1层,可发现KNN算法运行时间短于MLP,更快得到了结果。MLP的输入层神经元个数为1024,输出层神经元个数为10,在总数为946的情况下,MLP算法的错误数量为39,错误率为0.0412,KNN算法的错误数量为13,错误率为0.0137。MLP模型具有更强的表达能力和学习能力,但训练时间较长,而KNN模型则简单直观,训练时间较短。

MLP

神经元个数

50

100

200

500

错误数量

47

40

37

37

错误率

0.0497

0.0423

0.0391

0.0391

学习率

500

1000

1500

2000

错误数量

50

41

41

40

错误率

0.0529

0.0433

0.0433

0.0423

过小的迭代次数可能会使得MLP早停,造成较低的正确率。迭代次数100以上时,正确率基本不变,剩余的迭代次数不再进行,MLP在1000迭代时已收敛。

学习率

0.1

0.01

0.001

0.0001

错误数量

946

57

41

41

错误率

1.0000

0.0602

0.4333

0.4333

较小的学习率带来了更低的正确率,较小学习率无法在2000次送代内完成收敛,而步长较大的学习率使得MILP在2000次送代内快速收敛到最优解。可知,较小的学习率一般要配备较大的迭代次数以保证其收敛。

领居数量K

1

3

5

7

错误数量

13

13

20

24

错误率

0.0137

0.0137

0.0211

0.0235

K=1、3时正确率相同,但当K>3时正确率开始下降,这是由于当样本为稀疏数据集时(总样本数量只有946个),其第k个邻居点可能与测试点距离较远,从而投出了错误的一票来影响了最终预测结果。

五、实验问题解答与体会

通过实验发现,MLP和KNN在手写数字识别任务中的性能差异较大。MLP模型具有更强的表达能力和学习能力,但训练时间较长,而KNN模型则简单直观,训练时间较短。

此次试验我掌握了Sklearn实现基于MLP和KNN的手写识别。 可知KNN的准确率远高于MIP分类器,这是由于MIP在小数据集上容易过拟合的原因,MLP对于参数的调整比较敏感,若参数设置不合理容易得到较差的分类效果,因此参数的设置对于MLP至关重要。

在调参过程中发现,MLP模型的性能受到隐藏层神经元个数、迭代次数和学习率的影响较大。需要通过交叉验证等方法来选择最佳参数,以避免过拟合或欠拟合。

对于KNN模型,邻居数量K和距离度量方式是影响性能的重要因素,合适的K值和距离度量方式可以提高模型的性能。

此次试验让我明白了,在编写代码之前,务必仔细检查文件路径和文件名,确保它们是正确的。在处理数据时,要格外注意数据的质量和完整性,以避免在后续的分析和建模过程中出现问题。对于模型训练效果不佳的情况,需要耐心和细心地调整模型参数、优化数据预处理步骤,并且不断尝试不同的方法,直到找到合适的解决方案。通过不断学习和尝试代码算法,才会得到实用的经验和教训。所以,在以后的工作中,我们要保持持续学习的态度,不断改进和优化模型,提高工作效率和质量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值