您的位置:首页 > 编程语言 > Go语言

Google开源框架之MNIST入门

2015-12-08 19:46 267 查看

Google开源框架之MNIST入门

本博客基于google开源框架tensorflow所做的笔记,便于以后参考。这段代码放在github中github/hadxu

介绍tensorflow

入门MNIST

2015年11月,google公司开源了人工智能框架Tensorflow,发布当天,其github就超过10k的star,可见nb程度。本人抱着学习的心态,入门一下该开源框架的学习,如有不足之处,还望大家评论。

MNIST数据集入门

MNIST是计算机视觉的入门数据集 —— [ MNIST ]



人眼直接看图片直接就可以知道数字为多少,我们的任务就是让计算机能够看懂数字。

MNIST数据集

这里官方提供了一个获取数据的脚本,我将其放在我的github中input_data.py

那么你就可以像下面的代码一样使用该脚本

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


这段代码作用将数据集分为训练集和测试集,分别为60000与10000。

Softmax回归介绍

这里我引用极客学院的关于这个回归的介绍:

我们知道MNIST的每一张图片都表示一个数字,从0到9。我们希望得到给定图片代表每个数字的概率。比如说,我们的模型可能推测一张包含9的图片代表数字9的概率是80%但是判断它是8的概率是5%(因为8和9都有上半部分的小圆),然后给予它代表其他数字的概率更小的值。

这是一个使用softmax回归(softmax regression)模型的经典案例。softmax模型可以用来给不同的对象分配概率。即使在之后,我们训练更加精细的模型时,最后一步也需要用softmax来分配概率。

softmax回归(softmax regression)分两步:第一步

为了得到一张给定图片属于某个特定数字类的证据(evidence),我们对图片像素值进行加权求和。如果这个像素具有很强的证据说明这张图片不属于该类,那么相应的权值为负数,相反如果这个像素拥有有利的证据支持这张图片属于这个类,那么权值是正数。

evidencei=∑jWi, jxj+bi\text{evidence}_i = \sum_j W_{i,~ j} x_j + b_i

然后将所求得的和进行概率统计。

y=softmax(evidence)y = \text{softmax}(\text{evidence})

根据概率最大的值就很可能能为对应的标签。

softmax(x)=normalize(exp(x))\text{softmax}(x) = \text{normalize}(\exp(x))

展开

softmax(x)i=exp(xi)∑jexp(xj)\text{softmax}(x)_i = \frac{\exp(x_i)}{\sum_j \exp(x_j)}



我们根据矩阵,可以将其展开成:



最后,更一般的:



将其写成一般化数学公式为:

y=softmax(Wx+b)y = \text{softmax}(Wx + b)

实现回归模型

现在到了我们实现的步骤了,tensorflow提供了大量的数值计算的库,准确的来说,并不是数值计算,而是符号计算,对于符号计算,我也是刚刚才了解这种符号化计算方式。连google最新的支持的API是python的,所以当时决定学习python作为脚本语言是明智的选择,臭美中。。。

首先我们先导入该框架:

import tensorflow as tf


接下来,我们通过操作符号变量来描述这些可交互的操作单元,可以用下面的方式创建一个:

x = tf.placeholder("float", [None, 784])


x不是一个特定的值,而是一个占位符placeholder,我们在TensorFlow运行计算时输入这个值。我们希望能够输入任意数量的MNIST图像,每一张图展平成784维的向量。我们用2维的浮点数张量来表示这些图,这个张量的形状是[None,784 ]。(这里的None表示此张量的第一个维度可以是任何长度的。 )

我们的模型也需要权重值和偏置量,当然我们可以把它们当做是另外的输入(使用占位符),但TensorFlow有一个更好的方法来表示它们:Variable 。 一个Variable代表一个可修改的张量,存在在TensorFlow的用于描述交互性操作的图中。它们可以用于计算输入值,也可以在计算中被修改。对于各种机器学习应用,一般都会有模型参数,可以用Variable表示。

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


现在,我们可以实现我们的模型啦。只需要一行代码!

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


首先,我们用tf.matmul(​​X,W)表示x乘以W,对应之前等式里面的(Wx),这里x是一个2维张量拥有多个输入。然后再加上b,把和输入到tf.nn.softmax函数里面。

训练模型

对于接触过机器学习的同学来说,交叉熵作为损失评估是再也常见不过了

Hy′(y)=−∑iy′ilog(yi)H_{y'}(y) = -\sum_i y'_i \log(y_i)

为了计算交叉熵,我们首先需要添加一个新的占位符用于输入正确值:

y_ = tf.placeholder("float", [None,10])
cross_entropy = -tf.reduce_sum(y_*tf.log(y))


下面我们就用上面的代码构建训练算法,这里使用了反向传播算法,对于算法的细节我们不需要理解太多,我们首先会使用即可。

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


现在,我们已经设置好了我们的模型。在运行计算之前,我们需要添加一个操作来初始化我们创建的变量:

init = tf.initialize_all_variables()


现在我们可以在一个Session里面启动我们的模型,并且初始化变量:

sess = tf.Session()
sess.run(init)


然后开始训练模型,这里我们让模型循环训练1000次!

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


评估我们的模型

训练模型已经完成,那我们怎么知道该模型的好坏呢?

首先让我们找出那些预测正确的标签。tf.argmax 是一个非常有用的函数,它能给你在一个张量里沿着某条轴的最高条目的索引值。比如,tf.argmax(y,1) 是模型认为每个输入最有可能对应的那些标签,而 tf.argmax(y_,1) 代表正确的标签。 我们可以用 tf.equal 来检测我们的预测是否真实标签匹配。

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))


最后将正确率输出:

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




最后在我的阿里云服务器上得到的结果为91.8%,看起来不是特别好,别着急,我们接下来会使用卷积神经网络来构建模型。

总结

学会了使用tensorflow构建简单的浅层网络,并将整个浅层网络搭建起来,并将代码放在github中。接下来使用卷积神经网络。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: