前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Softmax 识别手写数字

Softmax 识别手写数字

作者头像
用户1147447
发布2019-05-26 00:31:01
2.2K0
发布2019-05-26 00:31:01
举报
文章被收录于专栏:机器学习入门机器学习入门

TensorFlow 入门(二):Softmax 识别手写数字

MNIST是一个非常简单的机器视觉数据集,如下图所示,它由几万张28像素x28像素的手写数字组成,这些图片只包含灰度值信息。我们的任务就是对这些手写数字的图片进行分类,转成0~9一共十类。

这里写图片描述
这里写图片描述

基本步骤

引包侠

代码语言:javascript
复制
from tensorflow.examples.tutorials.mnist import input_data

加载数据

代码语言:javascript
复制
mnist = input_data.read_data_sets('MNIST_data/', one_hot = True)

注意:若提示你的主机中的软件中止了一个已建立的连接,请关闭杀毒软件,以防误报。

你也可以直接从这里下载数据集,并在根目录下建立MNIST_data文件夹。再运行上述代码即可。

数据集探查

代码语言:javascript
复制
print(mnist.train.images.shape, mnist.train.labels.shape)
print(mnist.test.images.shape, mnist.test.labels.shape)
print(mnist.validation.images.shape, mnist.validation.labels.shape)

# 输出
(55000, 784) (55000, 10)
(10000, 784) (10000, 10)
(5000, 784) (5000, 10)

可以看到训练集有55000个样本,测试集有10000个样本,同时验证集有5000个样本。每一个样本都有对应的标注信息,即label。我们将在训练集上训练模型,在验证集上检验效果并决定何时完成训练,最后我们在测试集评测模型的效果(可通过准确率,召回率,F1-score等评测。)

每一张图片包含28像素X28像素。我们可以用一个数字数组来表示这张图片:

这里写图片描述
这里写图片描述

我们把这个数组展开成一个向量,长度是 28x28 = 784。如何展开这个数组(数字间的顺序)不重要,只要保持各个图片采用相同的方式展开。从这个角度来看,MNIST数据集的图片就是在784维向量空间里面的点, 并且拥有比较复杂的结构 (提醒: 此类数据的可视化是计算密集型的)。

这里手写数字识别为多分类问题,因此我们采用Softmax Regression模型来处理。关于Softmax,可以参看这里。你也可以认为它是二分类问题Sigmoid函数的推广。具体形式如下:

yi=ezi∑Kj=1ezjyi=ezi∑j=1Kezj

y_i = \frac{e^{z_i}}{\sum_{j = 1}^K{e^{z_j}}}

表示第i类模型预测的概率(总共有K类),zjzjz^j表示上一层的输出,可以是任意实数。Softmax的好处在于可以把每个类归一化到[0, 1]之间,且所有类的概率之和为1,这样我们可以从中选择最大概率的jjj,来表示模型的输出类别。

关于Softmax的推导可以参看这里。符号不是很严格,但基本能看明白。

咱们继续

这里写图片描述
这里写图片描述

我们第一层采用Logistic Regression,一张图片总共有(28 x 28)784个特征,每个特征与一个参数相乘,代表这个特征在此类别上的贡献,可以参看上图。

所以有

zj=∑i=1784wjixi+bjzj=∑i=1784wjixi+bj

z_j =\sum_{i = 1}^{784}w_{ji} x_i + b_j

定义输入向量和会话 首先载入TensorFlow库,并创建一个新的InteractiveSession,使用这个命令将这个session注册为默认的session,之后的运算也默认跑在这个session里,不同session之间的数据和运算应该都是相互独立的。接下来创建一个Placeholder,即输入数据的地方。Placeholder的第一个参数是数据类型,第二个参数[None, 784]代表tensor的shape,也就是数据的尺寸,这里None代表不限条数的输入,784代表每条输入是一个784维的向量。

代码语言:javascript
复制
import tensorflow as tf
sess = tf.InteractiveSession()
x = tf.placeholder(tf.float32, [None, 784])

创建变量 定义Sotfmax Regression模型中的weights和biases对象,注意这里的变量是全局性质的,所以使用TensorFlow中的Variable对象。

代码语言:javascript
复制
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

实现Sotfmax Regression算法

代码语言:javascript
复制
y = tf.nn.softmax(tf.matmul(x, W) + b)

定义损失函数 采用交叉信息熵,公式如下:

Loss=−∑iy′ilog(yi)Loss=−∑iyi′log⁡(yi)

Loss = -\sum_{i} y'_i \log(y_i) 其中y′iyi′y'_i表示真实值,yiyiy_i表示预测的概率。

代码语言:javascript
复制
y_ = tf.placeholder(tf.float32, [None, 10])
loss = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices = [1]))

先定义一个placeholder,输入真实的label,用来计算cross entropy。tf.reduce_sum也就是求和的∑∑\sum, 而tf.reduce_mean则用来对每个batch数据结果求平均。

定义优化算法 类似与梯度下降算法,此处我们采用随机梯度下降SGD,能够更快的收敛,且容易跳出局部最优解。

代码语言:javascript
复制
# 学习速率为0.5
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss)

运行

代码语言:javascript
复制
tf.global_variables_initializer().run()

一切准备就绪,喂数据

代码语言:javascript
复制
for i in range(1000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    train_step.run({x : batch_xs, y_ : batch_ys})

模型验证

代码语言:javascript
复制
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x : mnist.test.images, y_ : mnist.test.labels}))

# 输出
0.922

注意:前两行都只是定义,还未真正的执行,最后eval才是执行的代码。0.922的准确率,对于只有一层的Logistic Regression多分类已经不错了。

总结

  • 定义算法公式,也就是神经网络forward时的计算。
  • 定义loss,选定优化器,并指定优化器优化loss。
  • 迭代地对数据进行训练。
  • 在测试集或验证集上对准确率进行评测。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年02月06日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TensorFlow 入门(二):Softmax 识别手写数字
    • 基本步骤
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档