mnist机器学习入门

xiaoyh xiaoyh     2022-12-07     620

关键词:

  在前一个博客中,我们已经对MNIST 数据集和TensorFlow 中MNIST 数据集的载入有了基本的了解。本节将真正以TensorFlow 为工具,写一个手写体数字识别程序,使用的机器学习方法是Softmax 回归。

一、Softmax回归的原理

  Softmax 回归是一个线性的多类分类模型,实际上它是直接从Logistic回归模型转化而来的。区别在于Logistic 回归模型为两类分类模型,而Softmax 模型为多类分类模型。

  在手写体识别问题中, 一共有10 个类别( 0~9 ),我们希望对输入的图像计算它属于每个类别的概率。如属于9 的概率为70% ,属于1 的概率为10%等。最后模型预测的结果就是概率最大的那个类别。

  先来了解什么是Softmax 函数。Softmax 函数的主要功能是将各个类别的“打分”转化成合理的概率值。例如,一个样本可能属于三个类别:第一个类别的打分为a,第二个类别的打分为b,第三个类别的打分为c。打分越高代表属于这个类别的概率越高,但是打分本身不代表概率,因为打分的值可以是负数,也可以很大,但概率要求值必须在0~ 1 ,并且三类的概率加起来应该等于1 。那么,如何将(a, b, c)转换成合理的概率值呢?方法就是使用Softmax 函数。例如,对(a, b, c)使用Softmax 函数后,相应的值会变成

  技术图片

  也就是说,第一类的概率可以用第一个值表示,第二类的概率可以用第二个值表示,第三类的概率可以用第三个值表示。显然,这三个数值都在0~1之间,并且加起来正好等于1,是合理的概率表示。

  假设x 是单个样本的特征, W、b 是Softmax 模型的参数。在MNIST 数据集中, x 就代表输入图片,它是一个784 维的向量,而W 是一个矩阵, 它的形状为(784, 10),b 是一个10 维的向量, 10 代表的是类别数。Softmax 模型的第一步是通过下面的公式计算各个类别的Logit:Logit = WTx + b。

  Logit 同样是一个10 维的向量,它实际上可以看成样本对应于各个类别的“打分” 。接下来使用Softmax 函数将包转换成各个类别的概率值:y = Softmax(Logit)

  Softmax 模型输出的y 代表各个类别的概率,还可以直接用下面的式子来表示整个Softmax 模型:y = Softmax(Logit = WTx + b)

二、Softmax回归在TensorFlow中的实现

  本节对应的程序为softmax_regression.py ,在该程序中,使用TensorFlow定义了一个Softmax 模型,实现了MNIST 数据集的分类。首先导入TensorFlow 模块:

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)

  下面的步骤是非常关键的几步,先来看代码:

# 创建x,x是一个占位符(placeholder),代表待识别的图片
x = tf.placeholder(tf.float32,[None,784])

# w是Softmax模型的参数,将一个784维的输入转换为10维的输出
# 在TensorFlow中,模型的参数用tf.Variable表示
w = tf.Variable(tf.zeros([784,10]))
# b是又一个Softmax模型的参数,一般叫做“偏置顶”(bias)
b = tf.Variable(tf.zeros([10]))

# y 表示模型的输出
y = tf.nn.softmax(tf.matmul(x,w)+b)

# y_是实际的图像标签,同样以占位符表示
y_ = tf.placeholder(tf.float32,[None,10])

  这里定义了一些占位符和变量(Variable )。在TensorFlow 中,无论是占位符还是变量, 它们实际上都是“ Tensor”。从TensorFlow 的名字中,就可以看出Tensor 在整个系统中处于核心地位。TensorFlow 中的Tensor 并不是具体的数值, 它只是一些我们“希望” TensorFlow 系统计算的“节点’。

  这里的占位符和变量是不同类型的Tensor 。先来讲解占位符。占位符不依赖于其他的Tensor ,它的值由用户自行传递给TensorFlow ,通常用来存储样本数据和标签。如在这里定义了x = tf.placeholder(tf. float32, [None, 784]),它是用来存储训练图片数据的占位符。它的形状为[None, 784], None 表示这一维的大小可以是任意的,也就是说可以传递任意张训练图片给这个占位符,每张图片用一个784 维的向量表示。同样的, y_= tf.placeholder(tf.float32,[None, 10])也是个占位符,它存储训练图片的实际标签。

  再来看什么是变量。变量是指在计算过程中可以改变的值,每次计算后变量的值会被保存下来,通常用变量来存储模型的参数。如这里创建了两个变量: W = tf.Variable(tf.zeros([784, 10 ])) 、b = tf.Variable(tf. zeros([10])) 。它们都是Softmax 模型的参数。创建变量时通常需要指定某些初始值。这里W的初始值是一个784 × 10 的全零矩阵, b的初始值是一个10 维的0向量。

  除了变量和占位符之外,还创建了一个y = tf.nn.softmax(tf.matmul(x, W)+ b) 。这个y 就是一个依赖x、 W 、b 的Tensor 。如果要求TensorFlow 计算y的值,那么系统首先会获取x、 W、b 的值,再去计算y 的值。

  y 实际上定义了一个Softmax 回归模型,在此可以尝试写出y 的形状。假设输入x 的形状为(N, 784),其中N 表示输入的训练图像的数目。W 的形状为(784,10), b 的形状为(10,) 。那么, Wx + b 的形状是(N, 10)。Softmax函数不改变结果的形状,所以得到y 的形状为(N, 10) 。也就是说, y 的每一行是一个10 维的向量,表示模型预测的样本对应到各个类别的概率。

  模型的输出是y ,而实际的标签为y_ , 它们应当越相似越好。在Softmax回归模型中,通常使用“交叉熵”损失来衡量这种相似性。损失越小,模型的输出就和实际标签越接近,模型的预测也就越准确。

  在TensorFlow 中,这样定义交叉熵损失:

# 至此,我们得到了两个重要的Tensor:y和y_。
# y是模型的输出,y_是实际的图像标签,不要忘了y_是独热表示的
# 下面我们就会根据y和y_构造损失

# 根据y和y_构造交叉熵损失
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y)))

  构造完损失之后,下面一步是如何优化损失,让损失减小。这里使用梯度下降法优化损失,定义为:

# 有了损失,我们就可以用随机梯度下降针对模型的参数(w和b)进行优化
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

  TensorFlow 默认会对所有变量计算梯度。在这里只定义了两个变量W和b ,因此程序将使用梯度下降法对W 、b 计算梯度并重新它们的值。tf.train.GradientDescentOptimizer(0.01)中的0.01 是梯度下降优化器使用的学习率( Learning Rate )。

# 创建一个Session。只有在Session中才能运行优化步骤train_step
sess = tf.InteractiveSession()
# 运行之前必须要初始化所有变量,分配内存
tf.global_variables_initializer().run()
print("start training...")

  会话(Session)是Tensor Flow 的又一个核心概念。前面提到Tensor 是“希望”Tensor Flow 进行计算的结点。而会话就可以看成对这些结点进行计算的上下文。之前还提到过,变量是在计算过程中可以改变值的Tensor ,同时变量的值会被保存下来。事实上,变量的值就是被保存在会话中的。在对变量进行操作前必须对变量进行初始化,实际上是在会话中保存变量的初始值。初始化所高变量的语句是tf.global_variables initializer().run()。

  有了会话,就可以对变量W 、b 进行优化了,优化的程序如下:

# 进行1000步梯度下降
for _ in  range(1000):
    # 在mnist.train中取100个训练数据
    # batch_xs是形状为(100, 784)的图像数据,batch_ys是形如(100, 10)的实际标签
    # batch_xs, batch_ys对应着两个占位符x和y_
    batch_xs,batch_ys = mnist.train.next_batch(100)
    # 在Session中运行train_step,运行时要传入占位符的值
    sess.run(train_step,feed_dict=x:batch_xs,y_:batch_ys)

  每次不使用全部训练数据,而是每次提取100 个数据进行训练,共训练1000 次。batch_xs, batch _ys 分别是100 个训练图像及其对应的标签。在训练时,需要把它们放入对应的占位符x, y_中,对应的语句是feed_dict=x:batch_ xs, y_:batch_ys 。

  在会话中,不需要系统计算占位符的值,而是直接把占位符的值传递给会话。与变量不同的是,占位符的值不会被保存,每次可以给占位符传递不同的值。

  运行完梯度下降后,可以检测模型训练的结果,对应的代码如下:

# 正确的预测结果
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
# 计算预测准确率,它们都是Tensor
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
# 在Session中运行Tensor可以得到Tensor的值
# 这里是获取最终模型的准确率
print(sess.run(accuracy,feed_dict=x:mnist.test.images,y_:mnist.test.labels))   # 0.9149

  技术图片

  模型预测y 的形状是(N,10), 而实际标签y_的形状是(N, 10),其中N 为输入模型的样本个数。tf. argmax(y, 1) 、tf. argmax(y_, 1)的功能是取出数组中最大值的下标,可以用来将独热表示以及模型输出转焕为数字标签。假设传入四个样本,它们的独热表示y_为(需要通过sess.run(y_)才能获取此Tensor的值,下同):

[[1,0,0,0,0,0,0,0,0,0],
[0,0,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0]]

  tf.argmax(y_,1)就是:

[0,2,9,0]

  也就是说,取出每一行最大值对应的下标位置, 它们是输入样本的实际标签。假设此时模型的预测输出y 为:

[[0.91, 0.01, 0.01, 0.01, 0.01 , 0.01, 0.01, 0.01, 0.01, 0.01],
[0.91, 0.01, 0.01, 0.01, 0.01 , 0.01, 0.01, 0.01, 0.01, 0.01],
[0.91, 0.01, 0.01, 0.01, 0.01 , 0.01, 0.01, 0.01, 0.01, 0.01],
[0.91, 0.01, 0.01, 0.01, 0.01 , 0.01, 0.01, 0.01, 0.01, 0.01]]

  tf.argmax(y_,1)就是:

[0,0,0,0]

  得到了预测的标签和实际标签,接下来通过tf.equal 函数来比较它们是否相等,并将结果保存到correct_prediction 中。在上述例子中,correct_prediction 就是:

[True,False,False,True]

  即第一个样本和最后一个样本预测是正确的,另外两个样本预测错误。可以用tf.cast(correct_prediction, tf. float32)将比较值转换成float32 型的变量,此时True 会被转换成1, False 会被转接成0 。在上述例子中,tf.cast(correct_prediction, tf.float32)的结果为:

[1., 0., 0., 1.]

  最后,用tf.reduce_mean 可以计算数组中的所有元素的平均值,相当于得到了模型的预测准确率,如[1., 0., 0., 1.]的平均值为0.5 ,即50% 的分类准确率。

  在程序softmax_regression. py 中,传入占位符的值是feed_dict=x:moist.test.images, y_: mnist.test.labels。也就是说,使用全体测试样本进行测试。测试图片一共高10000 张,运行的结果为0.9149 ,即91.49% 的准确率。因为Softmax 回归是一个比较简单的模型,这里预测的准确率并不高,假如使用卷积神经网络的话会将预测的准确率提高到99% 。

  这篇博文主要来自《21个项目玩转深度学习》这本书里面的第一章,内容有删减,还有本书的一些代码的实验结果。随书附赠的代码库链接为:https://github.com/hzy46/Deep-Learning-21-Examples

  

mnist机器学习入门

一、简介  首先介绍MNIST数据集。如图1-1所示,MNIST数据集主要由一些手写数字的图片和相应的标签组成,图片一共有10类,分别对应从0~9,共10个阿拉伯数字。    原始的MNIST数据库一共包含下面4个文件,见表1-1。  ... 查看详情

tensflow框架学习之mnist机器学习入门

前言:初学TensorFlow和机器学习,MNIST算法的每条语句都不是很清楚,通过查阅资料,将每句代码的基本用法差不多理解了。希望能够帮助正在学习的你  [python]viewplaincopy <span style="font-size:32px;">from tensorflow.e... 查看详情

mnist机器学习入门(代码片段)

1.1.1简介下载MNIST数据集,并打印一些基本信息:pythondownload.py#从tensorflow.examples.tutorials.mnist引入模块,这是TensorFlow为了教学MNIST而提前编制的程序fromtensorflow.examples.tutorials.mnistimportinput_data#从MNIST_data/中读取MNIST数据。这条语句在... 查看详情

keras入门实战:手写数字识别

...方面都成功得到了应用,尤其是在图像识别和分类领域,机器识别图像的能力甚至超过了人类。本文用深度学习Python库Keras实现深度学习入门教程mnist手写数字识别。mnist手写数字识别是机器学习和深度学习领域的“helloworld”,MNIS... 查看详情

tensorflow实战计算机视觉之mnist数据集

...这篇文章:零基础入门深度学习(4)-卷积神经网络MNIST机器学习入门:http://www.tensorfly.cn/tfdoc/tutorials/mnist_beginners.html卷积神经网络改善MNIST数据集识别准确率MNIST机器学习入门中,MNIST上只有91%正确率。 查看详情

tensorflow之mnist解析

...深度学习简单介绍首先要简单区别几个概念:人工智能,机器学习,深度学习,神经网络。这几个词应该是出现的最为频繁的,但是他们有什么区别呢?人工智能:人类通过直觉可以解决的问题,如:自然语言理解,图像识别,... 查看详情

机器学习入门实践——线性回归&非线性回归&mnist手写体识别(代码片段)

把一本《白话深度学习与tensorflow》给啃完了,了解了一下基本的BP网络,CNN,RNN这些。感觉实际上算法本身不是特别的深奥难懂,最简单的BP网络基本上学完微积分和概率论就能搞懂,CNN引入的卷积,池化等也是数字图像处理中... 查看详情

mnist机器学习数据集

介绍在学习机器学习的时候,首当其冲的就是准备一份通用的数据集,方便与其他的算法进行比较。在这里,我写了一个用于加载MNIST数据集的方法,并将其进行封装,主要用于将MNIST数据集转换成numpy.array()格式的训练数据。直... 查看详情

matlab基于mnist数据集的图像识别(深度学习入门卷积神经网络附完整学习资料)(代码片段)

...基础入门的帮助。本文所用参考书:《MATLAB深度学习机器学习、神经网络与人工智能》【美】PhilKim著敖富江杜静周浩译清华大学出版社ISBN:978-7-302-49638-0水平有限,本文仅作学习交流,笔记分享所用。工程文件由上述... 查看详情

matlab基于mnist数据集的图像识别(深度学习入门卷积神经网络附完整学习资料)(代码片段)

...基础入门的帮助。本文所用参考书:《MATLAB深度学习机器学习、神经网络与人工智能》【美】PhilKim著敖富江杜静周浩译清华大学出版社ISBN:978-7-302-49638-0水平有限,本文仅作学习交流 查看详情

juedaiyuermnist机器学习

    MNIST是一个入门级的计算机视觉数据集,它包含各种手写数字图片:650)this.width=650;"src="https://images2015.cnblogs.com/blog/838132/201705/838132-20170510192333863-1390211391.png"style="border:0px;"alt="8381 查看详情

机器学习-knn识别mnist(代码片段)

代码 https://github.com/s055523/MNISTTensorFlowSharp数据的获得数据可以由http://yann.lecun.com/exdb/mnist/下载。之后,储存在trainDir中,下次就不需要下载了。///<summary>///如果文件不存在就去下载///</summary>///<paramname="urlB 查看详情

深度学习入门:报错modulenotfounderror:nomodulenamed‘dataset.mnist‘(代码片段)

深度学习入门:报错ModuleNotFoundError:Nomodulenamed'dataset.mnist'在学习《深度学习入门:基于pythom的理论与实验》时,3.6.1MNIST数据集这一节有这么一段代码importsys,ossys.path.append(os.pardir)#为了导入父目录中的文件而进行... 查看详情

机器学习项目实战识别mnist数据集识别图片数字(代码片段)

目录1机器学习分析步骤2问题定义2数据的收集和预处理3选择机器学习模型4训练机器,确定参数5超参数调试和性能优化5.1训练集、验证集和测试集5.2K折验证5.3模型的优化和泛化5.4验证预测结果1机器学习分析步骤机器学习项... 查看详情

机器学习实战——分类(代码片段)

3.1MNIST数据集本章使用MNIST数据集(一组美国高中生和人口调查局员工有些的70000个数字的图片)。获取该数据集的代码如下:fromsklearn.datasetsimportfetch_openmlmnist=fetch_openml('mnist_784',version=1)print(mnist.keys( 查看详情

机器学习框架tensorflow数字识别mnist

SoftMax回归 http://ufldl.stanford.edu/wiki/index.php/Softmax%E5%9B%9E%E5%BD%92我们的训练集由  个已标记的样本构成: ,其中输入特征。(我们对符号的约定如下:特征向量  的维度为 ,其中  对应截距项。)... 查看详情

机器学习-tensorflowsharp简单使用与knn识别mnist流程(代码片段)

机器学习是时下非常流行的话题,而Tensorflow是机器学习中最有名的工具包。TensorflowSharp是Tensorflow的C#语言表述。本文会对TensorflowSharp的使用进行一个简单的介绍。本文会先介绍Tensorflow的一些基本概念,然后实现一些基本操作例... 查看详情

机器学习算法专题(蓄力计划)二十实操代码mnist数据集(代码片段)

...手写的70000个数字的图片每张图片都用其代表的数字标记机器学习领域的“helloworld”,广泛使用于分类算法#sklearn提供datasets功能来下 查看详情