手写数字识别(1)---- Softmax回归模型

Tensorflow发布也有一段时间了,经常听周围的同学们提起,最近打算学习一下。
跟着官方教程,我过了一遍手写数字识别的教程。

原文:Build a Softmax Regression Model

前提

  • tensorflow r0.9
  • python 2.7

下载数据

tensorflow里面已经有现成的下载和读取脚本,直接运行下面的代码就可以了。

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

创建交互Session

tensorflow提供了两种运行模式,一种是构建好模型的「图」,然后交给Session去执行;另一种可以在构建「图」的过程中运行某个组件。这个教程就选用了第二种方式。(更多细节

import tensorflow as tf
sess = tf.InteractiveSession()

构建Softmax回归模型

放置变量的占空符(placeholders)

这个给我的感觉就像是做电路板时候,你在这放一个引脚,为以后引入数据做了个接口。下面两个「引脚」,一个是样本的特征输入x,一个是样本的类别标签y。其中shape=[None, 784]是因为每个样本用一个784维的向量表示,但不确定有多少个训练样本。所以shape的第一维是None。y同理。

x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])

待求变量

在获得模型的过程中,我们要一步步得到一些函数的权重和偏置量。tensorflow里面的变量设置形式如下:

W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

其中,W784 * 10的矩阵,是因为我们输入的样本有784维特征,待分的类有10类。同理,b的维度是10。

变量初始化

上一步中,我们设置了变量,而且还给它们设置了值。但是在图中还是要初始化一下。

sess.run(tf.initialize_all_variables())

调用这个一次就可以把所有的Variable类型初始化。

这个地方不太理解,这个是指的把这次调用之前的Variable初始化成指定的值,还是说上下所有的Variable都初始化了?
另外,它的意思是不是说初始化到图之前还要先给它分配初值,如上面的Wb都初始化为了零。

结果预测与损失函数

预测函数

y = tf.nn.softmax(tf.matmul(x,W) + b)

关于softmax的详细说明,请看Softmax
通过Softmax回归,将logistic的预测二分类的概率的问题推广到了n分类的概率的问题。通过公式

可以看出当月分类的个数变为2时,Softmax回归又退化为logistic回归问题。

损失函数

在这里选用的损失函数是交叉熵错误率模型(关于它的优点可以参考here,我觉得还不错,翻译了一下here),实现如下:

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), 
                                                reduction_indices=[1]))

训练模型

Tensorflow有一些最优化算法,在这个例子中使用了梯度下降的方法。
设置好损失函数之后,tensorflow就可以使用它来计算损失函数对应到每个要更新的变量的偏导数。此时,设置学习率为0.5

train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

这一步算是给我们构建的图里面加了一个功能组件,它实现的功能是:计算损失函数的偏导数,计算待更新的参数的更新量,更新参数。
然后,每运行一次train_step就重复一次上面的运算。

for i in range(1000):
  batch = mnist.train.next_batch(50)
  train_step.run(feed_dict={x: batch[0], y_: batch[1]})

评估分类结果

在进行评估分类结果之前,我们要先在tensorflow的图中「画出」用于评估的组件。tf.argmax(input, dimension, name=None)可以帮助评估。它的三个输入分别是:

- input:输入的张量,在本例中就是样本的标签张量或预测张量。
- demension:这里是一维
- name:给这个部件起个名字。。可以不用起。
这个函数的作用是给出预测出来的10个结果(对应的每个类别的分类概率)中的最大值的下标。

然后,我们的组件如下:

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

运行这个组件,会生成一组向量,如:[True, False, True, True]。我们把它映射成浮点数,然后,计算它们的均值,如下:

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

然后,将结果打印出来:

print accuracy.eval(feed_dict = {x: mnist.test.images, y_: mnist.test.labels})

最后,我们来运行一下结果(我在这里只训练了100次),如下:

cslzy (master *) mnist $ python mnist.py 
Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
training... 0
training... 10
training... 20
training... 30
training... 40
training... 50
training... 60
training... 70
training... 80
training... 90
0.8834

后来又测试了10000次训练,效果有一定提升。下一步试试CNN网络的模型。

点击查看本次测试完整代码

总结

tensorflow里面强调的「图」的概念很有意思。
使用tensorflow的框架在搭建模型的时候就有画流程图的感觉。感觉只要思路通顺,就可以实现你想要的模型,而不必去过度纠结与模型实现的具体结节上。对于我这样偏向于具象思维的人来说,「画图」的过程中,就仿佛能「看到」我所定义的模型一样。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值