手写数字识别系统学习(1)

从这一章起,我们将通过手写数字识别这一非常经典的机器学习项目接着来学习神经网络

一、数据数据和测试数据

​ 我们在上一章提到了权重和偏置的概念,这是一个相当繁琐的数据集,我们当然不可能人工的去设定每一个神经元所对应权重和偏置,所以我们需要计算机自己去思考并自调节权重和偏置,其中蕴含的数学知识我们会在这一章着重介绍

​ 在机器学习中,我们一般把数据分为训练数据测试数据两部分来训练模型,其中前者我们也称为监督数据。系统会对训练数据的学习中不断调整参数,寻找最优的参数;然后我们再通过对测试数据来评估模型的实际能力。

​ 我们将数据分为两部分的目的也是为了寻求模型的泛化能力,这就好比我们从小读书学习,不考试怎么知道自己的实际水平呢doge

二、损失函数

​ 损失函数是用来评估神经网络性能的“恶劣程度”的指标。神经网络会以某个指标为线索寻找最优权重参数,所用的指标就称为损失函数,损失函数可以使用任意函数,在这我们介绍均分误差交叉熵误差两个函数

1.均方误差

​ 均方误差是非常著名的损失函数,方程如下

​ 其中yk表示神经网络的输出,tk是监督数据,k表示数据的维度。例如下面设置10个数据来实际演示一下

>>>y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
>>>t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]

​ 其中y是softmax函数的输出,也是就表示为数据的概率;t是监督数据,只把正确的解作为1,其余的都作为0,我们在设置的时候可以用one-hot方法来表示,下面我们会讲

​ 现在我们用python来实现均方误差函数

def mean_squared_error(y, t):return 0.5 * np.sum((y - t) ** 2)       # **表示乘方

​ 其中y和t也是NumPy多维数组,现在我们使用函数来带入数据试试

# 其中只有索引“2”为正确解
>>>t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
# 其中索引“2”在数组中概率最高为0.6
>>>y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
>>>mean_squared_error(np.array(y), np.array(t))
0.097500000000031
# 现在将索引“7”设为概率最高为0.6
>>>y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
>>>mean_squared_error(np.array(y), np.array(t))
0.5975000000000003

​ 我们这里剧的两个例子一个是最高概率正好对应正解,第二个不是对应正解,我们明显发现第一个输出的值会更小,和监督数据之间的误差较小。也就是说。均方误差越小,输出结果与监督数据就更加吻合。

2.交叉熵误差

​ 除了均方误差函数之外,交叉熵误差也经常被用作损失函数,式子如下

​ 其中log以e为底数,yk是神经网络的输出,tk是正确解标签。tk和上面一样采用one-hot方法,即只有正确的解为1,其余为0。

​ 下面我们用代码来实现交叉熵误差函数

def cross_entrory_error(y, t):delta = 1e-7return -np.sum(t * np.log(y + delta))

​ 我们在python中的写法似乎有些不同,平白无故冒出来的delta是啥。是因为当y=0即log(0)的情况出现的时候,会报错对吧,delta是一种保护机制,纺织报错,而且我们在后面介绍偏导数的时候还会再遇到delta这一微小值

​ 接下来我们还是通过例子来实际演示交叉熵误差函数

# 其中只有索引“2”为正确解
>>>t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
# 其中索引“2”在数组中概率最高为0.6
>>>y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
>>>cross_entrory_error(np.array(y), np.array(t))
0.5108254570933802
# 现在将索引“7”设为概率最高为0.6
>>>y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
>>>mean_squared_error(np.array(y), np.array(t))
2.3025840929945458

​ 第一个对应正确解的例子输出为0.51,第二个未对应正解的例子输出的值为2.3。我们能看出功能和均方误差函数是相同的

3.mini-batch学习

​ MNIST数据集中一共有60000张图片,我们在进行数据训练学习的时候肯定不会一个一个读入,我们会从一片数据中随机挑选一些数据中进行学习,所以对上面的损失函数需要进行修改来满足多个数据的处理,以交叉熵误差方程为例

​ 这里我们假设监督数据有N个,tnk表示第n个数据的第k个元素的值,ynk是神经网络的输出,tnk是监督数据。通过这个式子,我们就可以求出单个数据的“平均误差函数”。通过这样的方法,我们就可以方便快速的求出误差。

​ 神经网络的学习就是从训练数据中挑选一部分数据进行训练,这种学习方法我们称为mini-batch学习

​ 在介绍mini-batch学习之前,我们先来看一下我们是如何从MNIST数据集中读取数据的

import sys, os
sys.path.append(os.pardir)
import numpy as np
from dataset.mnist import load_mnist
(x_train, t_train), (x_test, t_test) = \load_mnist(normal = True, one_hot_label = True)
print(x_train.shape)        # (60000, 784)
print(t_train.shape)        # (60000, 10)

​ 其中MNIST数据集在dataset文件夹下,我把文件的分享地址放在这:资源

​ 我们通过load_mnist函数来读入所有的数据,on_hot_label参数是我们上面提到的one_hot形式,即只有正确结果设为1,其余为0

​ 同时通过读取可以发现训练数据一共有60000个,输入数据是782维

(28*28)的图像数据,监督数据是10位的数据(0~9)

​ 接下来我们通过代码来实现从训练数据中随机抽取100个数据,运用NumPy中的np.rand.choice()函数来实现

train_size = x_train.shape[0]   # 获取数组最外层的形状
batch_size = 100
batch_mask = np.rand.choice(train_size, batch_size)
x_batch = x_train[batch_mack]
t_batch = t_train[batch]

​ choice函数可以实现从选定的数据中随机提取我们需要的数据量,例如上面的函数就是从0~59999的数据中随机挑选100个数据,得到的就是数据的索引batch_mask,我们再用索引找到各个数据就可以实现数据的随机挑选(这里的batch_mask是一有100个元素的array数组)

4.mini-batch版交叉熵误差

​ 我们介绍完了mini_batch,只要稍作修改,就可以来实现mini-batch版的误差函数了,如下

def cross_entropy_error(y, t):if y.ndim == 1:t = t.reshape(1, t.size)y = y.reshape(1, y.size)batch_size = y.shape[0]return -np.sum(t * np.log(y + 1e-7)) / batch_size

​ 来解析一下代码,首先是y.ndim,这个函数是用来返回y的维度的,我们已经介绍了很多查看数组形状的函数了,建议大家去看这篇博客来区别一下shape,ndim等函数的用法和区别。

​ 通过确认数组形状,我们可以判断是单个数据还是多个数据的计算,当多个数据的时候我们需要改变数组的形状来进行计算单个数据的平均交叉熵误差

​ 上面的是当监督数据是one_hot形式的,因为one_hot形式除了正确数据为1其余都为0,我们可以忽略这些数据的计算,下面是监督数据是标签形式的代码

def cross_entropy_error(y, t):if y.ndim == 1:t = t.reshape(1, t.size)y = y.reshape(1, y.size)batch_size = y.shape[0]return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size

​ 其中上面的np.arange(batch_size)函数会生成一个0到batch_size - 1的数组。例如batch_size为5的时候,会生成一个[0, 1, 2, 3, 4]的NumPy数组。t中的数据是以[2, 7, 0, 9, 4]这样的形式储存的,第n个元素表示在第n个数据中第几个为正解,我们运用y[np.arange(batch_size), t]函数就可以生成[y[0, 1], y[1, 7], y[2, 0], y[3, 9], y[4, 4]]这样的NumPy数组了

三、偏导与梯度

1.偏导数

​ 我们都知道导数的概念,曲线某点上的导数即为该点在曲线上的切线斜率。那何为偏导数,例如让我们求一个三维坐标中某曲面的导数或是多个自变量,我们似乎很难用普通求导的知识来解决,至此,我们引入了偏导数的概念,用∂来标记。

​ 具体的数学原理我不多赘述,我们直接来看求解方法,例如我们对下面这一函数来求偏导数

​ 在这个式子上有两个自变量,我们要对两个变量分别去导数,用数学式表示的话我们可以写成 ∂x0 , ∂x1的形式

​ 我们先实现求导的函数方法

def numerical_diff(f, x):h = 1e-4return (f(x + h) - f(x - h) / (2 * h))

​ 以上的代码我们可以发现代码是直接用导数的定义来计算导数

2.梯度

​ 我们上面介绍了偏导数的概念,我们将这些一些偏导数这样的向量集合称为梯度,我们可以用以下代码来实现

 def numerical_gradient(f, x):h = 1e-4  #0.0001grad = np.zeros_like(x)for idx in range(x.size):tmp_val = x[idx]# f(x+h)的计算x[idx] = tmp_val + hfxh1 = f(x)# f(x-h)的计算x[idx] = tmp_val - hfxh2 = f(x)grad[idx] = (fxh1 - fxh2) / (2*h)x[idx] = tmp_val  # 还原值return grad

​ 以上的代码我们通过python画出图像我们可以发现所有的向量都指向同一个最低点,梯度指向的方向是各点处的函数值最小值减少最多的方向(请记住这个非常重要的性质)

3.梯度法

​ 机器学习的主要任务是学习是寻找最优参数。同样我们在神经网络的学习中也必须在学习时找到最优参数(权重和偏置)

​ 我们再次强调,梯度表示的是各点处的函数值减少最多的方向,并不是最小值,而且在复杂函数中,梯度指示的方向基本上都是不是函数的最小值。虽然梯度的方向并不是指向最小值,但我们还是要以梯度的信息为线索,来了决定前进的方向

​ 像这样,通过这样不断地沿梯度放心前进,逐渐减少函数值的过程就是梯度法。梯度法是解决机器学习中最优化问题的常用方法,特别是在神经网络的学习中经常被使用。我们用梯度法来寻找最小值的方法被梯度下降法

​ 我们现在用数学式子来表示梯度法

​ 式子中的η在深度学习中被称为学习率,用来每一次传递更新数据用

​ 学习率我们需要实现设置一个值,比如0.01, 0.001,下面我们用代码来实现更新代码

def gradient_descent(f, init_x, lr = 0.01, step_num = 100):x = init_xfor i in range(step_num):grad = numerical_gradient(f, x)x -= lr * gradreturn x

​ 其中参数f是要进行最优化的函数,init_x是初始值,lr是学习率learning rate,step_num是梯度法的重复次数。运用这个函数,我们就可以求函数的极小值

4.神经网络的梯度

​ 下面,我们以一个非常简单的神经网络函数来实现求梯度的代码

import sys, os
sys.path.append(os.pardir)
import numpy as np
from common.function import softmax, cross_entropy_error
from common.gradient import numerical_gradientclass simpleNet:def __init__(self):self.W = np.random.randn(2, 3)    # 用高斯分布来进行权重的初始化def predict(self, x):return np.dot(x, self.W)def loss(self, x, t):z = self.predict(x)y = softmax(z)loss = cross_entropy_error(y, t)return loss

またお会いしましょう

编辑者:Ice Man

手写数字识别系统学习(1)相关推荐

  1. 深度学习笔记:01快速构建一个手写数字识别系统以及张量的概念

    深度学习笔记:01快速构建一个手写数字识别系统 神经网络代码最好运行在GPU中,但是对于初学者来说运行在GPU上成本太高了,所以先运行在CPU中,就是慢一些. 一.安装keras框架 使用管理员模式打 ...

  2. MATLAB实现数字识别系统,基于人工神经网络的MATLAB手写数字识别系统

    <基于人工神经网络的MATLAB手写数字识别系统>由会员分享,可在线阅读,更多相关<基于人工神经网络的MATLAB手写数字识别系统(8页珍藏版)>请在人人文库网上搜索. 1.基 ...

  3. Python(TensorFlow框架)实现手写数字识别系统

    手写数字识别算法的设计与实现 本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统.这是本人的本科毕业论文课题,当然,这个也是机器学习的基本问题 ...

  4. Python TensorFlow框架 实现手写数字识别系统

    手写数字识别算法的设计与实现 本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统.这是本人的本科毕业论文课题,当然,这个也是机器学习的基本问题 ...

  5. 完整代码及解析!!手写数字识别系统(手写数字测试识别 + pytoch实现 + 完整代码及解析)

    基于深度学习的手写数字识别系统 一.实验目的 ​ 1.任选实验环境及深度学习框架,实现手写数字识别系统: ​ 2.掌握所采用的深度血迹框架构建方式. 二.实验理论基础 1.MNIST数据集 ​ MNI ...

  6. k-近邻算法实现手写数字识别系统

    k-近邻算法实现手写数字识别系统 一.实验介绍 1.1 实验内容 本实验将会从电影题材分类的例子入手,详细讲述k-近邻算法的原理.在这之后,我们将会使用该算法实现手写数字识别系统. 1.2 课程来源 ...

  7. 手写数字识别系统 基于python

    环境基于Python3.6和Tensorflow框架 实现手写数字识别系统 本文使用python基于TensorFlow设计手写数字识别算法,并编程实现GUI界面,构建手写数字识别系统.文中首先对如何 ...

  8. 【机器学习/人工智能】 大作业:手写数字识别系统

    写在前面 参考的是https://zh.d2l.ai/index.html 一.大作业设计目的与要求 (1)利用所学习的聚类算法完成简单的图像分割系统. (2)编程并利用相关软件完成大作业测试,得到实 ...

  9. 【手写数字识别】基于matlab GUI BP神经网络单个或连续手写数字识别系统【含Matlab源码 2296期】

    ⛄一.手写数字识别技术简介 1 案例背景 手写体数字识别是图像识别学科下的一个分支,是图像处理和模式识别研究领域的重要应用之一,并且具有很强的通用性.由于手写体数字的随意性很大,如笔画粗细.字体大小. ...

最新文章

  1. c++中的基本知识点
  2. 中国移动研究院2020春招技术综合JAVA在线编程题第二题
  3. 搭建Servlet在线视频
  4. Oracle下的Databse,Instance,Schemas
  5. matlab共享变量,matlab如何编写共享参数拟合程序 - 程序语言 - 小木虫 - 学术 科研 互动社区...
  6. Bailian2676 整数的个数【入门】(POJ NOI0105-11)
  7. excel 两组数据交点_让科研人相见恨晚的技巧,用Excel做柱状图、箱型图及数据分析!(转载自ZSCI)...
  8. 宝塔mysql主从复制_MySQL主从复制
  9. 高德地图,百度地图坐标系GPS的转化
  10. mshtml 解析html c,使用MSHTML解析HTML代码
  11. CR网络和主网络的认知无线电切换算法
  12. 获取Bootcamp 6 下载地址(mac装win10)
  13. Edge浏览器无法登录Microsoft账户
  14. c语言单片机编程 实例教程,51单片机的C语言编程基础及实例教程
  15. 新浪批量短网址生成php源码,最新新浪短网址API接口与短网址在线批量生成工具的使用方法...
  16. 一辈子交186万五险一金!退休你能拿回多少?算完惊呆……
  17. 基于circom、snarkjs实现零知识证明不透漏具体地理位置的区域监控
  18. Java中同包和不同包类进行相互访问的问题
  19. 【飞凌嵌入式 OK3399-C+开发板试用体验】开箱上电
  20. 笔记本电脑显示以太网未连接_如何向笔记本电脑添加以太网连接

热门文章

  1. 快速打点工具——Aopo工具
  2. Java毕业设计 社区疫情防控管理系统
  3. 高通平台USB 2.0和USB 3.0接口充电器识别原理
  4. [矩阵计算]Lanczos方法:求稀疏矩阵特征值
  5. KNIME的学习使用心得
  6. torch.utils.tensorboard用法
  7. 在计算机桌面如何切换成大图标,win7系统桌面图标怎么设置大小 win7电脑桌面图标大小更改方法...
  8. 地表真实温度,辐射温度,亮度温度的区别
  9. 文档查看器(Open XML)格式工具
  10. html+css写三角形