1 任务介绍

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

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

2 MLP的输入

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

3 MLP的输出

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个神经元。

4 MLP结构

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

5 MLP手写识别实例构建

本实例的构建步骤如下:
步骤1:建立工程并导入sklearn包
步骤2:加载训练数据
步骤3:训练神经网络
步骤4:测试集评价

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

1)创建sklearnBP.py文件
2)在sklearnBP.py文件中导入sklearn相关包

import numpy as np #导入numpy工具包
from os import listdir #使用listdir模块,用于访问本地文件
from sklearn.neural_network import MLPClassifier
  • 1
  • 2
  • 3

5.2 步骤2:加载训练数据

1)在sklearnBP.py文件中,定义img2vector函数,将加载的32*32的图片矩阵展开成一列向量

def img2vector(fileName):retMat = np.zeros([1024],int) #定义返回的矩阵,大小为1*1024fr = 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2)在sklearnBP.py文件中定义加载训练数据的函数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标签置1dataSet[i] = img2vector(path +'/'+filePath) #读取文件内容   return dataSet,hwLabels
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3)在sklearnBP.py文件中,调用readDataSet和img2vector函数加载数据,将训练的图片存放在train_dataSet中,对应的标签则存在train_hwLabels中

#read dataSet
train_dataSet, train_hwLabels = readDataSet('trainingDigits')
  • 1
  • 2

5.3 步骤3:训练神经网络

1)在sklearnBP.py文件中,构建神经网络:设置网络的隐藏层数、各隐藏层神经元个数、激活函数、学习率、优化方法、最大迭代次数。
设置含100个神经元的隐藏层。
hidden_layer_sizes存放的是一个元组,表示第i层隐藏层里神经元的个数
使用logistic激活函数和adam优化方法,并令初始学习率为0.0001

clf = MLPClassifier(hidden_layer_sizes=(100,),activation='logistic', solver='adam',learning_rate_init = 0.0001, max_iter=2000)
  • 1
  • 2
  • 3

2)在sklearnBP.py文件中,使用训练数据训练构建好的神经网络fit函数能够根据训练集及对应标签集自动设置多层感知机的输入与输
出层的神经元个数。
例如train_dataSet为n*1024的矩阵,train_hwLabels为n*10的矩阵,则fit函数将MLP的输入层神经元个数设为1024,输出层神经元个数为10:

clf.fit(train_dataSet,train_hwLabels)
  • 1

5.4 步骤4:测试集评价

1)在sklearnBP.py文件中,加载测试集

dataSet,hwLabels = readDataSet('testDigits')
  • 1

2)使用训练好的MLP对测试集进行预测,并计算错误率:

res = clf.predict(dataSet)   #对测试集进行预测
error_num = 0                #统计预测错误的数目
num = len(dataSet)           #测试集的数目
for i in range(num):         #遍历预测结果#比较长度为10的数组,返回包含01的数组,0为不同,1为相同#若预测结果与真实结果相同,则10个数字全为1,否则不全为1if np.sum(res[i] == hwLabels[i]) < 10: error_num += 1
print("Total num:",num," Wrong num:", \error_num,"  WrongRate:",error_num / float(num))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6 实验效果

6.1 隐藏层神经元个数影响

运行隐藏层神经元个数为50、100、200的多层感知机,对比实验效果:

随着隐藏层神经元个数的增加,MLP的正确率持上升趋势;
大量的隐藏层神经元带来的计算负担与对结果的提升并不对等,因此,如何选取合适的隐藏神经元个数是一个值得探讨的问题。

6.2 迭代次数影响分析

我们设隐藏层神经元个数为100,初始学习率为0.0001,最大迭代次数分别为500、1000、1500、2000, 结果如下:

过小的迭代次数可能使得MLP早停,造成较低的正确率。
当最大迭代次数>1000时,正确率基本保持不变,这说明MLP在第1000迭代时已收敛,剩余的迭代次数不再进行。

6.3 学习率影响分析

改用随机梯度下降优化算法即将MLPclassifer的参数( solver=‘sgd’, ),设隐藏层神经元个数为100,最大迭代次数为2000,学习率分别为:0.1、0.01、0.001、0.0001,结果如下:

结论:较小的学习率带来了更低的正确率,这是因为较小学习率无法在2000次迭代内完成收敛,而步长较大的学习率使得MLP在2000次迭代内快速收敛到最优解。因此,较小的学习率一般要配备较大的迭代次数以保证其收敛。

MLP手写数字识别实现相关推荐

  1. MLP 之手写数字识别

    0. 前言 前面我们利用 LR 模型实现了手写数字识别,但是效果并不好(不到 93% 的正确率). LR 模型从本质上来说还只是一个线性的分类器,只不过在线性变化之后加入了非线性单调递增 sigmoi ...

  2. 【MLP实战】001:基于Minist数据集的手写数字识别

    本文又是一篇基于Minist数据集的手写数字识别. 首先,mnist数据集: 链接:https://pan.baidu.com/s/1z7R7_jnDKZm9F7M6n8hiIw 提取码:rn8z 首 ...

  3. 卷积神经网络(cnn) 手写数字识别

    1. 知识点准备 在了解 CNN 网络神经之前有两个概念要理解,第一是二维图像上卷积的概念,第二是 pooling 的概念. a. 卷积 关于卷积的概念和细节可以参考这里12,卷积运算有两个非常重要特 ...

  4. 用MXnet实战深度学习之一:安装GPU版mxnet并跑一个MNIST手写数字识别 (zz)

    用MXnet实战深度学习之一:安装GPU版mxnet并跑一个MNIST手写数字识别 我想写一系列深度学习的简单实战教程,用mxnet做实现平台的实例代码简单讲解深度学习常用的一些技术方向和实战样例.这 ...

  5. 卷积神经网络CNN 手写数字识别

    1. 知识点准备 在了解 CNN 网络神经之前有两个概念要理解,第一是二维图像上卷积的概念,第二是 pooling 的概念. a. 卷积 关于卷积的概念和细节可以参考这里,卷积运算有两个非常重要特性, ...

  6. Java软件研发工程师转行之深度学习(Deep Learning)进阶:手写数字识别+人脸识别+图像中物体分类+视频分类+图像与文字特征+猫狗分类

    本文适合于对机器学习和数据挖掘有所了解,想深入研究深度学习的读者 1.对概率基本概率有所了解 2.具有微积分和线性代数的基本知识 3.有一定的编程基础(Python) Java软件研发工程师转行之深度 ...

  7. TensorFlow 2.0 快速上手教程与手写数字识别例子讲解

    文章目录 TensorFlow 基础 自动求导机制 参数优化 TensorFlow 模型建立.训练与评估 通用模型的类结构 多层感知机手写数字识别 Keras Pipeline * TensorFlo ...

  8. 动手学PaddlePaddle(4):MNIST(手写数字识别)

    本次练习将使用 PaddlePaddle 来实现三种不同的分类器,用于识别手写数字.三种分类器所实现的模型分别为 Softmax 回归.多层感知器.卷积神经网络. 您将学会 实现一个基于Softmax ...

  9. CNN 手写数字识别

    1. 知识点准备 在了解 CNN 网络神经之前有两个概念要理解,第一是二维图像上卷积的概念,第二是 pooling 的概念. a. 卷积 关于卷积的概念和细节可以参考这里,卷积运算有两个非常重要特性, ...

  10. 用PyTorch进行手写数字识别

    目录 数据准备 网络模型 完整实现 数据准备 torch.utils.data.Datasets是PyTorch用来表示数据集的类,它是用PyTorch进行手写数字识别的关键. 下面是加载mnist数 ...

最新文章

  1. java 字符转化字符串_【转载】java字符串的各种编码转换
  2. 文华软件登录显示请选择服务器,文华财经提示先登录云服务器
  3. 【LeetCode】回文数
  4. HTMLCSS————块元素与内联元素
  5. 30岁女子跟程序员相亲,结果见面后秒拒:秃顶工资再多也不要
  6. 指定输出路径_新版Creo输入输出配置不用愁,果断收藏本文就对了
  7. LeetCode(595)——大的国家(MySQL)
  8. 洛谷P2770 航空路线问题(费用流)
  9. 【图论】拓扑排序:一个名字高大上的实际很简单的算法(图文详解)
  10. 计算机通过镜子测试,镜子测试
  11. Unity Editor 判断在哪个视图选中对象(Hierachy, Porject)
  12. word标题序号变为黑色方块解决方案
  13. OpenAI 开源语音识别模型 Whisper 初体验
  14. 设计模式08—模板方法模式
  15. S3C2440时钟体系 - SOC裸机
  16. 64位系统,定义int* a[2][3],占几个字节?
  17. 5G科普——CU和DU分离
  18. 迁移学习系列--领域泛化
  19. 中山LED芯片IC方案!JLC1041, JLK105系列两款超实用
  20. Android 进阶17:Fragment FragmentManager FragmentTransaction 深入理解

热门文章

  1. cad生成最小包围盒lisp_cad.net 葛立恒凸包算法和面积最小包围盒
  2. 计算机处理器基础原理笔记
  3. 将数据与OpenLayers结合在一起
  4. 摄影测量+元宇宙!虚拟校园还有哪些值得我们期待的?
  5. 虚拟现实技术虚拟校园解决方案
  6. 聚类算法的原理是什么?
  7. 处理Cookie ( from http://edu.chinaz.com )
  8. ubantu 搭建我的世界java服务器 spigot核心
  9. netbean java_netbean 生成 Java 桌面数据库应用程序
  10. windows下用linux系统,如何在Windows下使用Linux操作系统