Google开源框架之MNIST入门

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

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。 
那么你就可以像下面的代码一样使用该脚本

<code class="hljs python has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> input_data
mnist = input_data.read_data_sets(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"MNIST_data/"</span>, one_hot=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">True</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

这段代码作用将数据集分为训练集和测试集,分别为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

然后将所求得的和进行概率统计。 
y=softmax(evidence)

根据概率最大的值就很可能能为对应的标签。 
softmax(x)=normalize(exp(x))

展开 
softmax(x)i=exp(xi)jexp(xj)

简单神经网络模型

我们根据矩阵,可以将其展开成: 
这里写代码片

最后,更一般的: 
这里写图片描述

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

y=softmax(Wx+b)

实现回归模型

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

<code class="hljs haskell has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-import" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> tensorflow <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> tf</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

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

<code class="hljs mathematica has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">x = tf.placeholder(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"float"</span>, [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">None</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">784</span>])</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

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

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

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">W = tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Variable</span>(tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.zeros</span>([<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">784</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>]))
b = tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Variable</span>(tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.zeros</span>([<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>]))</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

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

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span> = tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.nn</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.softmax</span>(tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.matmul</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">x</span>,W) + b)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

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

训练模型

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

Hy(y)=iyilog(yi)

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

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">y_ = tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.placeholder</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"float"</span>, [None,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>])
cross_entropy = -tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reduce</span>_sum(y_*tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.log</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span>))</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

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

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">train_step = tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.train</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.GradientDescentOptimizer</span>(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.01</span>)<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.minimize</span>(cross_entropy)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

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

<code class="hljs fix has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">init </span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;"> tf.initialize_all_variables()</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

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

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">sess = tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Session</span>()
sess<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.run</span>(init)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

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

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">for i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1000</span>):
  batch_xs, batch_ys = mnist<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.train</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.next</span>_batch(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>)
  sess<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.run</span>(train_step, feed_dict={<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">x</span>: batch_xs, y_: batch_ys})</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

评估我们的模型

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

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

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">correct_prediction = tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.equal</span>(tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.argmax</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>), tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.argmax</span>(y_,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>))
accuracy = tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.reduce</span>_mean(tf<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.cast</span>(correct_prediction, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"float"</span>))</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

最后将正确率输出:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">print sess<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.run</span>(accuracy, feed_dict={<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">x</span>: mnist<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.test</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.images</span>, y_: mnist<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.test</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.labels</span>})</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

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

总结

学会了使用tensorflow构建简单的浅层网络,并将整个浅层网络搭建起来,并将代码放在github中。接下来使用卷积神经网络。

目录
相关文章
|
6月前
|
数据挖掘 API 网络安全
如何使用Google Compute Engine入门指南快速创建和配置您的云虚拟机实例
Google Compute Engine(GCE)是 Google Cloud Platform(GCP)的一部分,它为用户提供了高度可扩展的虚拟机实例,用于运行各种工作负载,从简单的网站托管到复杂的数据分析。本文将引导您完成使用 Google Compute Engine 的入门过程,以便您可以轻松开始使用这一强大的云计算平台。
172 0
Google Bard的暂时从入门到放弃
Google Bard的暂时从入门到放弃
103 0
Google Bard的暂时从入门到放弃
|
JavaScript 前端开发
GEE(Google Earth Engine)——JavaScript 入门(3)
GEE(Google Earth Engine)——JavaScript 入门(3)
159 0
|
存储 JavaScript 前端开发
GEE(Google Earth Engine)——JavaScript 入门(2)
GEE(Google Earth Engine)——JavaScript 入门(2)
224 0
|
机器学习/深度学习 Web App开发 传感器
GEE(Google Earth Engine)——JavaScript 入门(1)
GEE(Google Earth Engine)——JavaScript 入门(1)
446 0
GEE(Google Earth Engine)——JavaScript 入门(1)
|
机器学习/深度学习 存储 知识图谱
GNN入门必看!Google Research教你如何从毛坯开始搭建sota 图神经网络(下)
图神经网络近几年的发展十分火热,主要原因还是图能够表示连通关系,例如知识图谱等更贴切现实应用!Google Research最近发了一篇博客,从零开始教学GNN的发展路程,不熟悉的同学可以查缺补漏啦!
160 0
GNN入门必看!Google Research教你如何从毛坯开始搭建sota 图神经网络(下)
|
机器学习/深度学习 存储 自然语言处理
GNN入门必看!Google Research教你如何从毛坯开始搭建sota 图神经网络(上)
图神经网络近几年的发展十分火热,主要原因还是图能够表示连通关系,例如知识图谱等更贴切现实应用!Google Research最近发了一篇博客,从零开始教学GNN的发展路程,不熟悉的同学可以查缺补漏啦!
234 0
GNN入门必看!Google Research教你如何从毛坯开始搭建sota 图神经网络(上)
|
Web App开发 UED Python