2·MNIST机器学习入门

MNIST数据集

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
  • 60000行的训练数据集和10000行的测试数据集
    每一个MNIST数据单元有两部分组成:一张包含手写数字的图片和一个对应的标签。我们把这些图片设为“xs”,把这些标签设为“ys”。
    每一张图片包含28X28个像素点。
    我们把这个数组展开成一个向量,长度是 28x28 = 784。
    展平图片的数字数组会丢失图片的二维结构信息。这显然是不理想的,最优秀的计算机视觉方法会挖掘并利用这些结构信息,我们会在后续教程中介绍。
  • 因此,在MNIST训练数据集中,**mnist.train.images **是一个形状为 [60000, 784] 的张量,第一个维度数字用来索引图片,第二个维度数字用来索引每张图片中的像素点。在此张量里的每一个元素,都表示某张图片里的某个像素的强度值,值介于0和1之间。
  • 相对应的MNIST数据集的标签是介于0到9的数字,用来描述给定图片里表示的数字。我们使标签数据是"one-hot vectors"。 一个one-hot向量除了某一位的数字是1以外其余各维度数字都是0。标签0将表示成([1,0,0,0,0,0,0,0,0,0,0])。mnist.train.labels 是一个 [60000, 10] 的数字矩阵。

Softmax回归介绍

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

  • 下面的图片显示了一个模型学习到的图片上每个像素对于特定数字类的权值。红色代表负数权值,蓝色代表正数权值。

  • 也需要加入一个额外的偏置量(bias),因为输入往往会带有一些无关的干扰量。因此对于给定的输入图片 x 它代表的是数字 i 的证据可以表示为
  • 其中Wij代表权重,bi 代表数字 i 类的偏置量,xj 代表给定图片 x 的像素索引用于像素求和。然后用softmax函数可以把这些证据转换成概率 y
  • softmax可以看成是一个激活(activation)函数



  • 假设模型里的权值不可以是0值或者负值。Softmax然后会正则化这些权重值,使它们的总和等于1,以此构造一个有效的概率分布。
  • 可以写成更加紧凑的方式:

实现回归模型

  • TensorFlow把复杂的计算放在python之外完成。Tensorflow不单独地运行单一的复杂计算,而是让我们可以先用图描述一系列可交互的计算操作,然后全部一起在Python之外运行。(这样类似的运行方式,可以在不少的机器学习库中看到。)
  • 导入tensorflow:
import tensorflow as tf
  • 通过操作符号变量来描述这些可交互的操作单元,可以用下面的方式创建一个:
x = tf.placeholder(tf.float32, [None, 784])

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

  • 我们的模型也需要权重值和偏置量,也可以用占位符,但是有更好的表达方式:
W = tf.Variable(tf.zeros([784,10]))#W的维度是[784,10],因为我们想要用784维的图片向量乘以它以得到一个10维的证据值向量
b = tf.Variable(tf.zeros([10]))#b的形状是[10],所以我们可以直接把它加到输出上面。

一个Variable代表一个可修改的张量,存在在TensorFlow的用于描述交互性操作的图中。它们可以用于计算输入值,也可以在计算中被修改。对于各种机器学习应用,一般都会有模型参数,可以用Variable表示。

  • 现在,我们可以实现我们的模型啦。只需要一行代码!
y = tf.nn.softmax(tf.matmul(x,W) + b)#输出的y跟x保持同样的第一维的个数

tf.matmul(​​x,W)表示x乘以W,这里x是一个2维张量拥有多个输入。然后再加上b,把和输入到tf.nn.softmax函数里面。

训练模型

  • 为了训练我们的模型,我们首先需要定义一个指标来评估这个模型是好的。指标称为成本(cost)或损失(loss),然后尽量最小化这个指标。
  • 一个非常常见的,非常漂亮的成本函数是“交叉熵”(cross-entropy)

y 是我们预测的概率分布, y' 是实际的分布(我们输入的one-hot vector)。
比较粗糙的理解是,交叉熵是用来衡量我们的预测用于描述真相的低效性。

  • 为了计算交叉熵,我们首先需要添加一个新的占位符用于输入正确值:
y_ = tf.placeholder("float", [None,10]) # y_就是上面的y',是一个输入的固定的值
  • 计算交叉熵:
cross_entropy = -tf.reduce_sum(y_*tf.log(y))# 是一个y的函数

tf.log计算 y 的每个元素的对数。
接下来,我们把y_的每一个元素和tf.log(y) 的对应元素相乘。
最后,用 tf.reduce_sum 计算张量的所有元素的总和。
注意,这里的交叉熵不仅仅用来衡量单一的一对预测和真实值,而是所有100幅图片的交叉熵的总和。对于100个数据点的预测表现比单一数据点的表现能更好地描述我们的模型的性能。

  • 用TensorFlow来训练它是非常容易的。因为TensorFlow拥有一张描述你各个计算单元的图,它可以自动地使用反向传播算法(backpropagation algorithm)来有效地确定你的变量是如何影响你想要最小化的那个成本值的。然后,TensorFlow会用你选择的优化算法来不断地修改变量以降低成本。
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)#定义了一个训练方法,在后面作为session.run()的参数

这里TensorFlow用梯度下降算法(gradient descent algorithm)0.01的学习速率最小化交叉熵
当然TensorFlow也提供了其他许多优化算法:只要简单地调整一行代码就可以使用其他的算法。

TensorFlow在这里实际上所做的是,它会在后台给描述你的计算的那张图里面增加一系列新的计算操作单元用于实现反向传播算法和梯度下降算法。然后,它返回给你的只是一个单一的操作,当运行这个操作时,它用梯度下降算法训练你的模型,微调你的变量,不断减少成本。

  • 现在,我们已经设置好了我们的模型。在运行计算之前,我们需要添加一个操作来初始化我们创建的变量:
init = tf.initialize_all_variables()#定义一个初始化的函数动作,将前面定义的W和b初始化为零
  • 现在我们可以在一个Session里面启动我们的模型,并且初始化变量:
sess = tf.Session()#定义一个session
sess.run(init)#启动这个session并初始化变量

会话(session):
客户端通过创建 会话 (session)和 TensorFlow 系统进行交互。一个由会话接口提供的主要的操作就是 Run ,以需要计算的输出名称和替换某些输出节点的张量的操作集合作为其参数输入。通过控制 Run 的参数,TensorFlow 的实现可以计算所有节点的必须执行传递闭包来计算需要的输出,然后安排执行合适节点来保证他们的依赖关系(即如果要计算到参数那一步,前面必须的步骤会自动完成)。大多数 TensorFlow 的使用都是针对一个图启动一个会话,然后执行整个图或者通过 Run 调用来执行分离的子图数千或者数百万次。

  • 然后开始训练模型,这里我们让模型循环训练1000次!
for i in range(1000):
      batch_xs, batch_ys = mnist.train.next_batch(100)#随机抓取训练数据mnist中的100个批处理数据点
      sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})#用这些数据点作为参数替换之前的占位符来运行train_step

设计placeholder节点的唯一的意图就是为了提供数据供给(feeding)的方法。placeholder节点被声明的时候是未初始化的, 也不包含数据, 如果没有为它供给数据, 则TensorFlow运算的时候会产生错误, 所以千万不要忘了为placeholder提供数据。

评估我们的模型

  • 首先让我们找出那些预测正确的标签。tf.argmax 是一个非常有用的函数,它能给出某个tensor对象在某一维上的其数据最大值所在的索引值(就是对应的数字)。

  • tf.argmax(y,1)返回的是模型对于任一输入x预测到的标签值,而 tf.argmax(y_,1)代表正确的标签,我们可以用 tf.equal来检测我们的预测是否真实标签匹配(索引位置一样表示匹配)。

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))#比较两个有y和y_对应的标签序列,返回一个bool类型的序列
  • 这行代码会给我们一组布尔值。为了确定正确预测项的比例,我们可以把布尔值转换成浮点数,然后取平均值。例如,[True, False, True, True]会变成[1,0,1,1],取平均值后得到0.75.
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))#cast()转换类型,reduce_mean()获得平均值
  • 最后,我们计算所学习到的模型在测试数据集上面的正确率。
print (sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

我再来解读一下最后的run函数。
首先函数方法是accuracy,往前看发现引用了一个correct_prediction函数。查看correct_prediction函数,里面有两个参数yy_。往前看,y_是一个placeholdery_确定要传参数进来了。而y是一个函数式,查看此函数式发现需要用到x,再往前找到x定义的地方发现x是一个placeholder,也需要传参数进来,就此终于形成闭包。最终是两个placeholder,并且次序是先xy_,因此用feed_dict={x: mnist.test.images, y_: mnist.test.labels}

按照教程一步一步操作,每输进一行代码都要问一句为什么。不懂得地方仔细琢磨,要想会用tensorflow,必须先读懂它!最重要的一点就是理解tensorflow的闭包的概念!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 简单线性回归 import tensorflow as tf import numpy # 创造数据 x_dat...
    CAICAI0阅读 3,538评论 0 49
  • 一.目的 类似学习开发语言的第一个代码,Hello World! 机器学习中,我们通过MNIST来学习手写输入法的...
    Coming0524阅读 6,467评论 2 8
  • 你隐在一角,静立又默默无语 周边是一片灯光――暖色的光亮 所有的目光,都朝向一个方向 唯独我,死死盯着有你的地方 ...
    扁舟一片阅读 122评论 0 0
  • “耶路撒冷的众女子啊,这是我的良人,这是我的朋友。”(雅歌 5:16) 当你没有把你的妻子当成好朋友时,她就会觉得...
    Roena阅读 1,542评论 0 1
  • “小子,今天你有福了,我带你去个好地方!”艾略特一边拉着我一边自顾自的说着,完全无视路过学生们惊诧的眼神,“喂,我...
    考拉凶猛阅读 244评论 0 0