MNIST数据集
MNIST是一个包含数字0-9的手写体图片数据集,图片已归一化为以手写数字为中心的28*28规格的图片。MNIST由训练集与测试集两个部分组成,各部分规模如下:
- 训练集:60000个手写体图片及对应标签
- 测试集:10000个手写体图片及对应标签
DBRHD数据集
DBRHD数据集包含大量的数字0-9的手写体图片,这些图片来源于44位不同的人的手写数字,图片已归一化为以手写数字为中心的32*32规格的图片。DBRHD的训练集与测试集组成如下:
- 训练集:7494个手写体图片及对应标签,来源于40位手写者
-
测试集:3498个手写体图片及对应标签,来源于14位手写者
MLP手写识别
MLP(Multilayer preceptron),多层感知机用于识别数据集DBRHD的手写数字。
MPL输出:“one-hot vectors”
- 一个one-hot向量除了某一位的数字是1以外其余各维度数字都是0。
-
图片标签将表示成一个只有在第n维度(从0开始)数字为0的10维向量。比如,标签0将表示成[1,0,0,0,0,0,0,0,0,0,0]。即MLP输出层具有10个神经元。
import numpy as np #导入numpy工具包
from os import listdir #使用listdir模块,用于访问本地文件
from sklearn.neural_network import MLPClassifier
def img2vector(fileName):
retMat = np.zeros([1024],int) #定义返回的矩阵,大小为1*1024
fr = open(fileName) #打开包含32*32大小的数字文件
lines = fr.readlines() #读取文件的所有行
for i in range(32): #遍历文件所有行
for j in range(32): #并将01数字存放在retMat中
retMat[i*32+j] = lines[i][j]
return retMat
def readDataSet(path):
fileList = listdir(path) #获取文件夹下的所有文件
numFiles = len(fileList) #统计需要读取的文件的数目
dataSet = np.zeros([numFiles,1024],int) #用于存放所有的数字文件
hwLabels = np.zeros([numFiles,10]) #用于存放对应的one-hot标签
for i in range(numFiles): #遍历所有的文件
filePath = fileList[i] #获取文件名称/路径
digit = int(filePath.split('_')[0]) #通过文件名获取标签
hwLabels[i][digit] = 1.0 #将对应的one-hot标签置1
dataSet[i] = img2vector(path +'/'+filePath) #读取文件内容
return dataSet,hwLabels
#read dataSet
train_dataSet, train_hwLabels = readDataSet('sklearn/digits/trainingDigits')
clf = MLPClassifier(hidden_layer_sizes=(100,),
activation='logistic', solver='adam',
learning_rate_init = 0.0001, max_iter=2000)
print(clf)
clf.fit(train_dataSet,train_hwLabels)
#read testing dataSet
dataSet,hwLabels = readDataSet('sklearn/digits/testDigits')
res = clf.predict(dataSet) #对测试集进行预测
error_num = 0 #统计预测错误的数目
num = len(dataSet) #测试集的数目
for i in range(num): #遍历预测结果
#比较长度为10的数组,返回包含01的数组,0为不同,1为相同
#若预测结果与真实结果相同,则10个数字全为1,否则不全为1
if np.sum(res[i] == hwLabels[i]) < 10:
error_num += 1
print("Total num:",num," Wrong num:", \
error_num," WrongRate:",error_num / float(num))
MLPClassifier(activation='logistic', learning_rate_init=0.0001, max_iter=2000)
MLPClassifier(activation='logistic', hidden_layer_sizes=(200,),
learning_rate_init=0.0001, max_iter=2000)
Traceback (most recent call last):
File
PS E:\coding> python -u "e:\coding\sklearn\minst_mlp.py"
MLPClassifier(activation='logistic', hidden_layer_sizes=(200,),
learning_rate_init=0.0001, max_iter=2000)
Total num: 946 Wrong num: 40 WrongRate: 0.042283298097251586
PS E:\coding> python -u "e:\coding\sklearn\minst_mlp.py"
MLPClassifier(activation='logistic', hidden_layer_sizes=(400,),
learning_rate_init=0.0001, max_iter=2000)
Total num: 946 Wrong num: 35 WrongRate: 0.03699788583509514
随着隐藏神经元数目从100到200再到400,判断错误次数从41下降到40,再下降到36。
KNN手写识别
KNN(k-Nearest Neighbor),k近邻分类器,用于识别数据集DBRHD的手写数字。
之后比较KNN的识别效果与多层感知机的识别效果。
- DBRHD数据集的每个图片是一个由0或1组成的32*32的文本矩阵。
- KNN的输入为图片矩阵展开的一个1024维的向量。
import numpy as np #导入numpy工具包
from os import listdir #使用listdir模块,用于访问本地文件
from sklearn import neighbors
def img2vector(fileName):
retMat = np.zeros([1024],int) #定义返回的矩阵,大小为1*1024
fr = open(fileName) #打开包含32*32大小的数字文件
lines = fr.readlines() #读取文件的所有行
for i in range(32): #遍历文件所有行
for j in range(32): #并将01数字存放在retMat中
retMat[i*32+j] = lines[i][j]
return retMat
def readDataSet(path):
fileList = listdir(path) #获取文件夹下的所有文件
numFiles = len(fileList) #统计需要读取的文件的数目
dataSet = np.zeros([numFiles,1024],int) #用于存放所有的数字文件
hwLabels = np.zeros([numFiles])#用于存放对应的标签(与神经网络的不同)
for i in range(numFiles): #遍历所有的文件
filePath = fileList[i] #获取文件名称/路径
digit = int(filePath.split('_')[0]) #通过文件名获取标签
hwLabels[i] = digit #直接存放数字,并非one-hot向量
dataSet[i] = img2vector(path +'/'+filePath) #读取文件内容
return dataSet,hwLabels
#read dataSet
train_dataSet, train_hwLabels = readDataSet('sklearn/digits/trainingDigits')
knn = neighbors.KNeighborsClassifier(algorithm='kd_tree', n_neighbors=3)
knn.fit(train_dataSet, train_hwLabels)
#read testing dataSet
dataSet,hwLabels = readDataSet('sklearn/digits/testDigits')
res = knn.predict(dataSet) #对测试集进行预测
error_num = np.sum(res != hwLabels) #统计分类错误的数目
num = len(dataSet) #测试集的数目
print("Total num:",num," Wrong num:", \
error_num," WrongRate:",error_num / float(num))
PS E:\coding> python -u "e:\coding\sklearn\minst_knn.py"
Total num: 946 Wrong num: 12 WrongRate: 0.012684989429175475
PS E:\coding> python -u "e:\coding\sklearn\minst_knn.py"
Total num: 946 Wrong num: 13 WrongRate: 0.013742071881606765
PS E:\coding> python -u "e:\coding\sklearn\minst_knn.py"
Total num: 946 Wrong num: 18 WrongRate: 0.019027484143763214
PS E:\coding> python -u "e:\coding\sklearn\minst_knn.py"
Total num: 946 Wrong num: 22 WrongRate: 0.023255813953488372
在K=3的时候效果最好,之后增加K错误率反而继续上升。