学习笔记1:神经网络实现手写识别(Python语言)


问题:

手写数字识别是一个多分类问题,有10个分类,每个手写数字图像的类别是0-9中的一个数。使用sklearn来训练一个简单的全连接神经网络,对数据集DBRHD进行识别



学习内容:

DBRHD数据集介绍:1、已经归一化为手写数字为中心的32*32规格的图片。2、去掉了图片颜色等复杂因素,将手写体数字图片转化为训练数据为大小32*32的文本矩阵。3、空白区于使用0代表,字迹区域使用1表示。

神经网络参数设置:设置1层隐藏层,该隐藏层含100个神经元。初始学习率为0.0001,迭代2000次。使用logistic激活函数和adam优化方法。

MLP:多层感知机识别

注:文末附有本文数据集文件,分享给大家一起学习

import numpy as np
from os import listdir       #用于访问本地文件
from sklearn.neural_network import MLPClassifier
import time

start = time.perf_counter()

## 定义img2vector函数,将加载的32*32的图片矩阵展开成一列向量
def img2vector(fileName):
    retMat = np.zeros([1024],int) #定义返回的矩阵,大小为1*1024,整数形式
    fr = open(fileName)   #打开包含32*32大小的数字文件
    lines = fr.readlines()   #读取文件的所有行,#readlines()从文件中一行一行地读数据,返回一个列表
    for i in range(32):      #遍历文件所有行
        for j in range(32):  #并将0-1数字存放在retMat中
            retMat[i*32+j]=lines[i][j]
    return retMat

## 定义加载训练数据的函数readDataSet,并将样本标签转化为one-hot向量
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

## 调用readDataSet和img2vector函数加载数据,将训练的图片存放在train_dataSet中,对应的标签则存在train_hwLabels中
train_dataSet, train_hwLabels = readDataSet('trainingDigits')


## 构建神经网络:设置网络的隐藏层数、各隐藏层神经元个数、激活函数、学习率、优化方法、最大迭代次数
clf = MLPClassifier(hidden_layer_sizes=(100,),     #1层隐藏层,设置含100个神经元的隐藏层,hidden_layer_sizes存放的是一个元组,表示第i层隐藏层里神经元的个数
                    activation='logistic', solver='adam',   #使用logistic激活函数和adam优化方法
                    learning_rate_init = 0.0001, max_iter=2000)  #令初始学习率为0.0001,迭代2000次

## 训练神经网络
print(clf)   #fit函数能够根据训练集及对应标签集自动设置多层感知机的输入与输出层的神经元个数
clf.fit(train_dataSet, train_hwLabels)

## 测试集评价
dataSet,hwLabels = readDataSet('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))
end = time.perf_counter()
t = end-start
print("所用时间为:", t)

运行结果:

本案例中使用的数据集文件分享给大家:

链接:百度网盘 请输入提取码 
提取码:ZiDa

将其中的训练手写图像文件夹命名为trainingDigits

将其中的测试手写图像文件夹命名为testDigits

保存到相应的工作区,运行本文代码即可

感谢阅读,欢迎大家一起交流分享!


你可能感兴趣的:(学习总结,python,神经网络,机器学习)