博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tensorflow实现Softmax Regression识别手写数字
阅读量:5750 次
发布时间:2019-06-18

本文共 5062 字,大约阅读时间需要 16 分钟。

一、MNIST数据集

  MNIST数据集是一个非常简单的机器视觉数据集,由几万张28*28像素的手写数字组成,且这些数字只包含灰度值信息。

二、TensorFlow代码实现

1 # -*- coding: utf-8 -*- 2 """ 3 Created on Thu May 16 21:39:25 2019 4  5 @author: CFF 6 """ 7 import tensorflow as tf 8 from tensorflow.examples.tutorials.mnist import input_data 9 mnist = input_data.read_data_sets("MNIST_data", one_hot=True)10 batch_size = 10011 X_holder = tf.placeholder(tf.float32)12 y_holder = tf.placeholder(tf.float32)13 14 Weights = tf.Variable(tf.zeros([784, 10]))15 biases = tf.Variable(tf.zeros([1,10]))16 predict_y = tf.nn.softmax(tf.matmul(X_holder, Weights) + biases)17 loss = tf.reduce_mean(-tf.reduce_sum(y_holder * tf.log(predict_y), 1))18 optimizer = tf.train.GradientDescentOptimizer(0.5)19 train = optimizer.minimize(loss)20 21 session = tf.Session()22 init = tf.global_variables_initializer()23 session.run(init)24 25 for i in range(500):26     images, labels = mnist.train.next_batch(batch_size)27     session.run(train, feed_dict={X_holder:images, y_holder:labels})28     if i % 25 == 0:29         correct_prediction = tf.equal(tf.argmax(predict_y, 1), tf.argmax(y_holder, 1))30         accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))31         accuracy_value = session.run(accuracy, feed_dict={X_holder:mnist.test.images, y_holder:mnist.test.labels})32         print('step:%d accuracy:%.4f' %(i, accuracy_value))

三、原理分析

  ①、图像的取值:空白部分全部为0,有笔迹部分根据颜色深浅有0-1之间取值。每一张图片有784维的特征,即由28*28个像素点(28*28=784)展开成1维的结果。故丢弃了图片的二维结构方面的信息,直接把一张图片变成一个很长的1维向量。

  ②、整个数据集的特征是一个55000*784的Tensor,同时训练的数据Label是一个55000*10维的Tensor,对10个种类进行one-hot编码,Label是一个10维向量。例如对于数字0的标签就是[1,0,0,0,0,0,0,0,0,0]。

  ③、使用Softmax Regression的算法训练手写数字识别的分类模型,Softmax Regression的原理就行对每一种类别估算一个概率,然后取概率最大的那个数字作为模型的输出结果。即将可以判定为某一类的特征相加,再将这些特征转化为判定这一类的概率。例如某个像素的灰度值大代表很可能是数字n时,这个像素的权值就很大,反之,这个像素的权值就很小。特征的公式表示如下:

featureijWi,j*xj+bi

  对所有特征计算softmax,即都计算一个exp函数,再进行标准化(即让所有类别输出的概率值为1)。公式如下:

softmax(x)=normalize(exp(x))

  判断第i类的概率可以有下列公式计算:

softmax(x)i=exp(xi)/Σjexp(xj)

  先对各个类的特征求exp函数,再进行标准化,使得和为1,特征的值越大的类,最后输出的概率就越大,反之,特征的值越小的类,最后输出的概率就越小。Softmax Regression流程如下:

 

  上图对应公式如下:Softmax Regression元素的乘法

  变成对应的矩阵乘法如下:

  最后变成y=softmax(Wx+b)。

  ④、使用TensorFlow实现一个softmax regression,首先导入TensorFlow库并创建一个新的InteractiveSession,使用这个命令将这个session注册为默认的session,之后的运算默认在这个session里面跑。接下来创建一个Placeholder,用来输入数据,Placeholder的第一个参数是数据类型,第二个参数[None,784]表示Tensor的shape,None表示输入条数不限,每条输入是一个784维的向量。

1 import tensorflow as tf2 sess = tf.InteractiveSession()3 x = tf.placeholder(tf.float32,[None,784])

  ⑤、给Softmax Regression模型中的weights和biases创建Variable对象,Variable是用来存储模型参数,不同于存储数据的tensor一旦使用掉就会消失,而Variable在模型训练迭代中是持久化的(比如一直存放在显存中),可以长期存在并且在每一轮迭代中被更新。weights和biases全部初始化为0,因为模型训练时会自动学习合适的值。对于这个简单的模型,初始化值不太重要,但对于复杂的卷积网络、循环网络或者比较深的全连接网络,初试值的方法比较重要。W的shape是[784,10],784是特征的维数,10表示有10类,因为Label在one-hot编码后是10维的向量。

1 W=tf.Variable(tf.zeros([784,10]))2 b=tf.Variable(tf.zeros([10])) 3 y=tf.nn.softmax(tf.matmul(x,w)+b)

  Softmax是tf.nn下面的一个函数,tf.nn包含了大量神经网络的组件,tf.matmul是TensorFlow中的矩阵乘法函数。TensorFlow将forward和backward的内容都自动实现。只要接下来定义好loss,训练时将会自动求导并进行梯度下降,完成对Softmax Regression模型参数的自动学习。

  ⑥、为了训练模型,需要定义loss function来描述模型对问题的分类精度。loss越小,表示模型的分类结果与真实值的偏差越小,即模型精度越高。首先给模型填充全零的参数,模型就有一个初始的loss,训练的目的就是不断将这个loss减小,直到到达一个全局最优或局部最优解。对于多分类,通常使用cross-entropy作为loss function。cross-entropy最早出自信息论中的信息熵(与压缩比率等有关)。Cross-entropy的定义如下:

Hy'(y)=-Σiyilog(yi)

  其中y是预测的概率分布,y'是真实的概率分布(即Label的one-hot编码),通常使用这个来判断模型对真实概率分布估计的准确程度。

1 y_ = tf.placeholder(tf.float32,[None,10])2 cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y),reduction_indices=[1]))

  先定义一个placeholder,输入是真实的label,用来计算cross-entropy。y_*tf.log(y)是y’ilog(yi),tf.reduce_sum也就是求和Σ,而tf.reduce_mean用来对每个batch数据结构求均值。

  ⑦、定义优化算法,常见的随机梯度SGD,定义好优化算法后,TensorFlow就可以根据定义的整个计算图自动求导,并根据方向传播算法进行训练,每一轮迭代时更新参数来减小loss。TensorFlow会自动在后台添加许多运算操作来实现反向传播和梯度下降,每轮迭代时feed数据放入优化器就可以了。直接调用tf.train.GradientDescentOptimizer,并设置学习率为0.5,优化目标设定为cross-entropy,得到进行训练的操作train_step。

1 train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)2 # 使用全局优化器tf.global_variables_initializer,并直接执行run()方法3 tf.global_variables_initializer().run()

  ⑧、开始迭代训练操作train_step。每次随机从训练集中抽取100条样本构成一个mini-batch,并feed给placeholder,如何调用train_step对这些样本进行训练。使用一小部分样本进行训练称为随机梯度下降。如果每次训练都使用全部样本,计算量太大,有时也不容易跳出局部最优。对于大部分机器学习问题,都只使用一小部分数据进行随机梯度下降,这种方法收敛速度快很多。

1 for i in range(1000):2     batch_xs,batch_ys=mnist.train.next_batch(100)3    train_step.run({x:batch_xs,y_:batch_ys})

  ⑨、完成训练后,对模型的准确率进行验证。tf.argmax是从tensor中寻找最大的序号,tf.argmax(y,1)就是求各个预测的数字中概率最大的那一个。tf.argmax(y_,1)是找样本的真实数字的类别。tf.equal方法用来判断预测的数据类别是否就是正确的类别,返回计算类别是否正确的操作correct_predition

1 correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))2 accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))3 print(accuracy.eval({x:mnist.test.images,y_:mnist.test.labels}))

  先用tf.cast将输出的bool值转换为float32,再求平均值。将测试数据的特征和label输入评测流程accuracy,计算模型在测试集上的准确性,再将结果打印出来。

  ⑩、总结,使用TensorFlow实现一个简单的机器学习算法Softmax Regression,这是一个没有隐藏层的最浅的神经网络。主要分为四个步骤:

  (1)定义算法公式,即神经网络forward时的计算

  (2)定义loss,选定优化器,并指定优化器优化loss

  (3)迭代地对数据进行训练

  (4)在测试集或验证集上对准确度进行评测

转载于:https://www.cnblogs.com/chenfeifen/p/10878708.html

你可能感兴趣的文章
刷题笔记
查看>>
iOS app exception的解决方案
查看>>
对<<寒江独钓---Windows内核安全编程>>中第3章<<串口过滤>>的改进
查看>>
Mongodb启动命令mongod参数说明
查看>>
TCP&UDP压力测试工具
查看>>
Linux使用Shell脚本实现ftp的自动上传下载(转)
查看>>
卷轴式游戏地图实现
查看>>
[IOI1999]花店橱窗布置(DP路径记录)
查看>>
oracle 导入数据
查看>>
js 闭包 原型
查看>>
首个5G智慧机场落地广州 速度是4G的50倍
查看>>
持续集成是什么
查看>>
JavaScript设计模式之面向对象编程
查看>>
Android 最简单的自定义Dialog之一
查看>>
磨刀不误砍柴 - 配置适合工作学习的桌面环境
查看>>
自己动手写docker-3
查看>>
Java笔记-反射机制(一)
查看>>
OpenCV在Android中的集成与简单使用
查看>>
redux v3.7.2源码解读与学习之 applyMiddleware
查看>>
【React】为什么我不再使用setState?
查看>>