matlab朴素贝叶斯手写数字识别_从“手写数字识别”学习分类任务

a4d8172361331e7a3dafe73fcf909d9c.png

机器学习问题可以分为回归问题和分类问题,回归问题已经在线性回归讲过,本文学习分类问题。分类问题跟回归问题有明显的区别,回归问题是连续的数值,而分类问题是离散的类别,比如将性别分为[男,女],将图片分为[猫,狗,兔]等。

学习分类问题用的最多的示例是LeCun的MNIST手写数字识别。

MNIST手写数字数据集介绍

MNIST手写数字数据集包含60000张训练图片和10000张测试图片,这些图片是从0~9的手写数字,分辨率为28*28,大致是下面这个样子:

afe861d5350c14e027a0b1bc75319f8d.png
MNIST数据集

该数据集广泛适用于各大机器学习平台入门程序,有非常成熟的处理方案。不过为了深入理解数据格式,我们先来手动下载并读取这些数据,数据格式详见。

手动读取MINST数据集:

import 

输出:

79a45d927ef4c245bc4817781db78085.png
预览MINIST数据集

分类任务的误差函数

前面说过回归型任务可以用MSE(Mean squared error)均方误差作为loss函数,分类任务的误差如何表示呢?比如手写数字识别任务需要将图片分成10类,既0~9每个数字一类,很容易想到的一个误差衡量方式是:如果分类正确误差是0,如果分类不正确误差是1。这样做人很容易理解,但对计算机来说作用不大,因为并没法表示出分类不正确的程度。

通常使用交叉熵(Cross Entropy)表示分类问题的loss函数,其定义如下:

  • 表示类别的个数,比如数字识别的类别是个数是10个
  • 表示真实的类别,如果属于当前类别
    ,则为值1,否则为值0
  • 表示预测输出属于类别
    的概率,如果有10个类别,则根据总概率为1的约束一定有:

特别的如果只有两个类别,比如性别[男,女]这种二分类问题,上述公式可以简写成:

TensorFlow实现手写数字识别(一)

可以用神经网络来做手写数字识别,一个只有一层全连接层的网络拓扑如下:

9307266ef54dfdb72b1441576d30d7d7.png
一层神经网络
注:图上全连接的线条没有全部画出,两层之间任意两点之间都有一条连线。

网络非常的简单,784个像素输入通过一个全连接层跟10个输出相连。网络所需参数个数为权重 784 * 10,外加10个bias。用公式表达就是:

  • 其中
    表示训练数据向量,对于MNIST就是(60000, 784)维的向量
  • 是权重矩阵,维度是(784, 10)
  • 是bias向量,维度是(10)
  • activation是激活函数,他是一个将线性空间向非线性空间映射的函数,用以增强网络的表达能力。常见的激活函数有relu, sigmoid, tanh等。
  • 表示预测属于各个类别的概率,最终将采用概率最大的那个类别作为最终类别。

为什么需要激活函数?

多个线性函数的组合仍然是线性函数,激活函数将线性空间映射到非线性空间,增强网络的表达能力。比如任意多个一元线性回归的加和是多元线性回归,无法表示抛物线、正弦曲线等非线性数据。而多个线性单元经过激活函数之后再做组合,理论上可以拟合任意复杂的公式。详见 https:// zhuanlan.zhihu.com/p/16 5849993

69d3e7831f42feda1fe09947250b8cba.png
常见激活函数

上述神经网络拓扑对应的代码实现如下,该版本的代码尽可能的展现细节,除了微分计算采用了tf自动求导其余的操作均手工完成,对理解原理很有帮助

import 

输出结果:

8d78f28d71c5d2648c843ebd6d1de5dd.png

8bf2a647bbdedbeda320a0f1b4fcec0c.png

这么简单的网络经过1000轮的训练,在测试集上取得了77.42%的识别正确率,且到后期随着训练轮数增加预测效果也不再增加,算是差强人意吧。

上图中看到训练误差在逐渐降低,预测效果在逐渐升高但有些波动,这根learning_rate的设置有关系,比如学习率设置过大导致训练效果来回抖动。学习率如何设置是一个单独的话题,感兴趣的话可以了解一下“优化器”。

TensorFlow实现手写数字识别(二)

上述网络只有一层表现力较弱,识别正确率只有77.42%,通过增加网络层数可以提高网络的表达能力,两层网络结构如下:

70c99bd231d2395f5f8308639be95bf2.png
两层神经网络
注:图上全连接的线条没有全部画出,两层之间任意两点之间都有一条连线。

代码如下:

import 

执行结果:

581660a06d22c69f8200340f1a5ce52f.png

识别效果达到了82.16%,比一层网络要好一些。

keras实现手写数字识别

深层网络比浅层有更好的表现力,不过手写深层网络显得很麻烦,keras大大简化网络构造的复杂度。

keras是一套针对模型的的极简API,可以用几行代码写出复杂的网络结构,完全屏蔽实现细节(那是具体后端的工作,比如tensorflow)

使用keras编写两层网络的手写数字识别:

import 

网络构建和训练超乎想象的简洁!最终训练效果如下:

注意:keras.datasets.mnist会从 https:// storage.googleapis.com/ tensorflow/tf-keras-datasets/mnist.npz 下载数据。可以手动下载这个数据并放在~/.keras/datasets,全路径名为 ~/.keras/datasets/mnist.npz

a4a6abf3396acf2c861e89e0ed5875d5.png
网络summary

20c505aaf0555e277a90f911e784adab.png
训练和预测结果

最终识别效果95%,效果比手写的示例有大幅提升。

keras实现手写数字识别——卷积神经网络

针对图像处理有专门的神经网络结构——卷积神经网络。使用keras可以很容易的搭建卷积神经网络:

卷积神经网络是一种专门用于处理图像的特殊的神经网络,他在传统神经网络中加入“卷积”和“池化”层模拟人的大脑对视觉的处理方式,大幅提升图片的识别准确度。
import 

输出:

b740b315287d4ed4d64b47b7c84814f6.png
网路summary

c95c19dfe114b40f0c3f40e9f595ec8b.png
训练和预测结果

识别精度高达99%,卷积神经网络处理图像分类果然有奇效!

总结

本文首先对MNIST数据集进行了介绍,之后用多种方式实现了手写数字识别的神经网络,对理解神经网络原理很有帮助。Keras是编写神经网络的利器,用几行代码就能构建出复杂的网络模型,极大简化编码复杂度。另外简单介绍了激活函数、keras、卷积神经网络等概念。

如有收获请直接点赞~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值