本文写给机器学习和tensorflow的初学者。如果你已经知道mnist,softmax(multinomial logistic)regression,你可以会想看这个faster paced tutorial.不过,首先得确认你已经 install TensorFlow .
初学编程,一般都会学习写一个“hello world!”的程序,MNIST就相当于机器学习领域的“hello world!”
MNIST是一个机器图像数据集。它包含像下面的一些手写的数据图像:
在本教程中,我们要训练一个模型来识别图像并预测他们是什么数字。我们的目标不是训练一个真的精准的模型,达到极强的性能 — — 虽然我们以后会给你代码来做到 !— — 而是要以之为引字让大家初步了解如何使用TensorFlow。因此,我们要开始与一个非常简单的模型,称为 Softmax 回归。
在本教程中的实际代码是非常短的和所有有趣的事情发生只需要三行代码。然而,了解其背后的理念很重要 ︰ TensorFlow 的工作原理和核心机器学习的概念。正因为如此,我们要非常认真地学习这些代码。
The MNIST DataMNIST 数据Yann LeCun's website网站上。为了方便,我们已经包括一些 python 代码来自动下载并安装数据。你可以要么下载的代码和将其导入如下,或简单地复制并粘贴它。
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
正如前面提到的每个 MNIST 数据点有两个部分 ︰ 图像的手写的数字和相应的标签。我们将调用图像"xs"和标签"ys"。训练集和测试集包含 x 和 y 们,例如训练图像是 mnist.train.images 训练的标签是 mnist.train.labels。
每个图像是 28 x 28 像素。我们可以把这解读为一大系列的数字 ︰
其结果是,mnist.train.images 是一个形状 [55000,784]的张量(n 维数组)。第一维是图像和第二个维度是每个图像的像素。在张量的每个条目是 0 和 1 之间,为某个特定的图像中像素点的像素强度。
MNIST 中的相应标签是数字 0 至 9,描述给定的图像是哪个数字。出于本教程的目的,我们要想我们作为一个"one-hot"的标签。one-hot矢量是一个由多个0和一个1组成的向量。在这种情况下,第 n 个数字将被表示为一个向量中第 n 个元素为1。例如,3 将是[0,0,0,1,0,0,0,0,0,0]。这样,mnist.train.labels 是 [55000,10]阵列的浮点数。
现在我们就可以真正开始建立我们的模型了!
Softmax Regressions这是一个经典的案例,其中 softmax 回归是一个自然、 简单的模型。如果你想要将概率分配给一个或者几个不同的可能时,softmax 就可以完成这样的事情。甚至后来,当我们训练更复杂的模型,最后一步也将是softmax一层。
Softmax 回归有两个步骤 ︰ 首先我们要把这些输入的特征加起来,然后我们将这些特征转换成概率。
为了总结了给定的图像的特征,我们把这些像素强度做加权求和。权重的大小表明该特征在确定它为正确分类时候的作用大小。
下面的关系图显示了学到的每个类的权重一个模型。红色代表负的权重,而蓝色表示正的权重。
We also add some extra evidence called a bias. Basically, we want to be able to say that some things are more likely independent of the input. The result is that the evidence for a class i given an input x is:
我们还添加了一些额外的证据,被称为一种偏见。基本上,就指独立于输入的特征。结果是对于i这一类据,我给出了输入 x,结果就是︰
其中Wi是权重,bi是类i的偏见,,j是输入x像素。我们可以通过softmax函数把这些变成预测的概率如下:
这里 softmax 担任"激活"或"链接"的功能,把我们的线性函数输出变成我们想要的结果 — — 在这种情况下,概率分布为 10 例。你可以认为它是把输入的证据转换成可能是某一类的可能性。它被定义为 ︰
softmax(x)=normalize(exp(x))
展开方程你会得到如下的公式:
你能想象 softmax 回归作为类似下面的内容,虽然现实中会有更多的 xs。对于每个输出,我们计算 xs 的加权的和,添加一个bias,然后应用 softmax。
如果把它写成方程,就可以得到 :
然后我们可以把这个过程“标量化”,变成矩阵相乘和向量相加。这会让计算更加快速。(也是一种简化思考的方法)
更加简化一下,我们可以把它写成:
若要使用 TensorFlow,我们需要将其导入。
import tensorflow as tf
这些交互式的操作需要符号变量。我们先来创建一个:
x = tf.placeholder(tf.float32, [None, 784])
x并不是一个特定的值,它是一个placeholder,一个我们需要输入数值当我们需要tensorflow进行运算时。我们想要输入任意数量的mnist图片,每一个都展开成一个784维的向量。我们用一个二维的[None, 784]浮点张量代表。 (这里的None表示维度可以是任意的长度.)
我们的模型中也需要权重和bias。我们可以把它们看成是额外的输入,Tensorflow有更加好的方法来表示它: Variable. Variable是一个Tensorflow图交互操作中一个可以修改的张量。 它可以在计算中修改。对于机器学习的,一般都有一些Variable模型参数。
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
注意,W 的形状 [784,10] ,是因为我们想要 784 三维图像向量乘以它输出10 维向量以标识的不同类。b形状是 [10],这样我们可以将其和输出相加。
现在,我们可以实现我们的模型。它只需要一行代码 !
y = tf.nn.softmax(tf.matmul(x, W) + b)
就是这样。我们只花了一行代码来定义我们的模型。不是因为 TensorFlow 旨在简化 softmax 回归︰ 它只是想通过非常灵活的方式来描述很多各种各样的数值计算,从机器学习模型到物理模拟。定义后,可以在不同的设备上运行我们的模型︰您的计算机的CPU、Gpu、甚至手机 !
一个很常见的很好的成本函数是"cross-entropy交叉熵"。出人意料的是,交叉熵虽然产生于对信息压缩码信息理论的思考,但它最终被在很多方面,从赌博到机器学习。它的定义是︰
这里y是我们预测的概率分布,而y′ 是真正的分布(那个我们要输入的one-hot标题).某种理解下,交叉熵可以衡量我们的预测是多少的低效。本文不会更加详细地深入交叉熵,但它很值得去理解-> understanding.
为了使用交叉熵,我们要先增加一个新的placeholder来放正确的结果:
y_ = tf.placeholder(tf.float32, [None, 10])
然后设置交叉熵, −∑y′log(y):
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
现在,我们知道我们想要我们的模型做什么,它是很容易通过 TensorFlow 去训练它。因为TensorFlow 了解整个图的计算,它可以自动使用反向传播算法有效地确定你的变量是如何影响成本函数并把它最小化。然后,它可以应用您所选择的优化算法来修改变量和降低成本函数。
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
现在,我们设置好了我们的模型。最后一件事在我们启动它之前,我们要添加一个操作来初始化我们创建的变量︰
init = tf.initialize_all_variables()
现在我们可以启动一个会话,然后运行初始化变量的操作:
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})
Each step of the loop, we get a "batch" of one hundred random data points from our training set. We runtrain_step feeding in the batches data to replace the placeholders.
Using small batches of random data is called stochastic training -- in this case, stochastic gradient descent. Ideally, we'd like to use all our data for every step of training because that would give us a better sense of what we should be doing, but that's expensive. So, instead, we use a different subset every time. Doing this is cheap and has much of the same benefit.
使用随机数据进行小批量称为随机训练 — — 在这种情况下,随机的梯度下降法。理想情况下,我们想使用我们所有的数据训练的每一步,因为这会给我们感觉是更好的方法,但这样代价太大。相反,每次我们使用一个不同的子集,这样做代价更小而且可以达到相同的效果。
模型评价How well does our model do?
Well, first let's figure out where we predicted the correct label. tf.argmax is an extremely useful function which gives you the index of the highest entry in a tensor along some axis. For example, tf.argmax(y,1) is the label our model thinks is most likely for each input, while tf.argmax(y_,1) is the correct label. We can use tf.equalto check if our prediction matches the truth.
好吧,先让我们弄清楚我们预测正确的标签在哪里。tf.argmax 是项的极其有益的函数,它给返回在一个标题里最大值的索引。例如,tf.argmax(y,1) 是我们的模型输出的认为是最有可能是的那个值,而 tf.argmax(y_,1) 是正确的标签的标签。如果我们的预测与匹配真正的值,我们可以使用 tf.equal来检查。
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
这会返回我们一个布尔值的列表.为了确定哪些部分是正确的,我们要把它转换成浮点值,然后再示均值。 比如, [True, False, True, True] 会转换成 [1,0,1,1] ,从而它的准确率就是0.75.
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
最后我们在测试数据上求准确率的值:
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
应该会是大约 92%.
然而重要的是我们学会了使用这个模型。不过,如果你对于这个结果还是不太满意,查阅the next tutorial我们通过一个教程和学习如何通过TensorFlow构建更复杂的模型,它会达到更高的精度哦!
欢迎访问网站:奇趣儿 – 到天边外去…
欢迎关注微信号:奇趣儿beta
欢迎扫描二维码: