在TensorFlow中编程

英文原文:https://torres.ai/research-teaching/tensorflow/first-contact-with-tensorflow-book/first-contact-with-tensorflow/#cap1

在简要描述了算法识别数字的功能之后,我们可以在TensorFlow中实现它。为此,我们可以快速了解张量  应如何  存储我们的数据和模型的参数。为此,下面的模式描述了数据结构及其关系(以帮助读者轻松回忆我们的每个问题):

image066

首先,我们创建两个变量来包含权重  W  和偏差  b:

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

这些变量是使用tf.Variable  函数和变量的初始值创建  的; 在这种情况下,我们用包含零的常数张量初始化张量。

我们看到W的形状为  [Dimension(784),Dimension(10)],  由其参数定义,恒定张量  tf.zeros [784,10]的  尺寸与W相似  。偏见  b也是如此,它的论证形成为  [Dimension(10)]

矩阵W具有该大小,因为我们想要为10个可能的数字中的每一个乘以784个位置的图像矢量,并在添加b之后产生张量的证据  。

在使用MNIST进行研究的情况下,我们还创建了两个维度的张量来保持x  点的信息  ,使用以下代码行: 

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

张量  x  将用于将MNIST图像存储为784个浮点值的向量(使用  None  我们指示维度可以是任何大小;在我们的情况下,它将等于学习过程中包含的元素数量) 。

现在我们定义了张量,我们可以实现我们的模型。为此,TensorFlow提供了几个操作,即  tf.nn.softmax(logits,name = None)  其中一个可用的操作,实现了前面描述的  softmax  函数。参数必须是张量,并且可选地是名称。该函数返回与参数传递的张量相同类型和形状的张量。

在我们的例子中,我们为这个函数提供了乘以图像向量x  和权重矩阵  W的结果张量    加上   

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

一旦指定了模型实现,我们就可以 使用迭代训练算法指定必要的代码来获得W  和偏差  b的权重  。对于每次迭代,训练算法获得训练数据,应用神经网络并将获得的结果与预期结果进行比较。

要确定模型何时足够好,我们必须定义“足够好”的含义。正如在前面的章节中所看到的,通常的方法是定义相反的方式:模型使用成本  函数的“坏”  程度。在这种情况下,目标是获得W  和  b的值,   其最小化指示模型“坏”的函数。

结果输出与培训数据的预期输出之间的误差程度有不同的度量标准。一个常见的指标是  均方误差  或  欧几里德平方距离,这是以前见过的。尽管如此,一些研究线在神经网络中为此目的提出了其他指标,例如在我们的例子中使用的  交叉熵误差。此指标的计算方式如下:

image068

其中  y  是预测的概率分布,y'是实际分布,从训练数据集的标记中获得。我们不会详细讨论交叉熵背后的数学及其在神经网络中的位置,因为它远比本书的预期范围复杂得多; 只是表明当两个分布相同时获得最小值。同样,如果读者想要了解这个功能的见解,我们建议阅读  神经网络和深度学习  [36]

要实现  交叉熵  测量,我们需要一个新的占位符来表示正确的标签:

y_ = tf.placeholder("float", [None,10])

使用这个占位符,我们可以 使用以下代码行实现  交叉熵,代表我们的成本函数: 

cross_entropy = -tf.reduce_sum(y_*tf.log(y))

首先,我们 使用TensorFlow tf.log()中的内置函数  计算每个元素y的对数  ,然后将它们与每个y_  元素相乘  。最后,使用  tf.reduce_sum  我们对张量的所有元素求和(稍后我们将看到图像以束的形式被访问,在这种情况下,  交叉熵的值  对应于图像束  y  而不是单个图像) 。

迭代地,一旦确定了样本的误差,我们必须纠正模型(在我们的例子中修改参数  W  和  b)以减少下一次迭代中计算输出和预期输出之间的差异。

最后,它仍然只是指定这个迭代最小化过程。在神经网络中有几种用于此目的的算法; 我们将使用  反向传播  (误差的向后传播)算法,并且如其名称所示,它向后传播在输出处获得的误差以重新计算W的权重,这  对于多层神经网络尤其重要。

该方法与先前看到的梯度下降方法一起使用,该方法使用交叉熵成本函数允许我们计算每次迭代时参数必须改变多少以便在每个时刻使用可用的本地信息来减少错误。在我们的例子中,直观地说,它包括在 每次迭代时稍微改变权重  W(这一点由  学习率  超参数表示,表示变化的速度)以减少误差。

由于在我们的例子中我们只有一层神经网络,我们不会进入反向传播方法。只记得TensorFlow知道整个计算图,允许它应用优化算法来找到训练模型的成本函数的正确梯度。

因此,在我们使用MNIST图像的示例中,以下代码行表明我们使用反向传播算法来 使用梯度下降  算法最小化  交叉熵,  并且获得率为  0.01:

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

 在这里,我们已经指定了所有问题,我们可以通过实例化tf.Session()  来负责在系统,CPU或GPU上的可用设备中执行TensorFlow操作来开始计算  :

sess = tf.Session()

 接下来,我们可以执行初始化所有变量的操作:

sess.run(tf.initialize_all_variables())

从现在开始,我们可以开始训练我们的模型。train_step的返回参数  在执行时将梯度下降应用于所涉及的参数。因此,可以通过重复train_step  执行来实现对模型的训练  。假设我们想要迭代我们的train_step的 1.000倍  ; 我们必须指出以下代码行:

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})

循环内的第一行指定,对于每次迭代,挑选从训练数据集中随机采样的100个数据输入的束。我们可以在每次迭代时使用所有训练数据,但为了使第一个示例更加灵活,我们每次都使用一个小样本。第二行表示先前获得的输入必须馈送相应的占位符。

最后,只需提及基于梯度下降的机器学习算法可以利用TensorFlow自动区分的功能。TensorFlow用户只需定义预测模型的计算体系结构,将其与目标函数组合,然后只需添加数据即可。

TensorFlow已经管理了学习过程背后的衍生品相关微积分。当  最小化()  方法被执行,TensorFlow标识所述一组的上哪些变量  损失 函数  依赖,并计算梯度为每个这些。如果您想知道如何实现区分,可以检查  ops / gradients.py  文件  [37]。

模型评估
必须在训练后评估模型,以查看“好”(或“坏”)有多少。例如,我们可以计算预测中命中和未命中的百分比,看看哪些例子是正确预测的。在前面的章节中,我们看到  tf.argmax(y,1)  函数返回根据给定轴的张量的最高值的索引。实际上,  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"))

例如,  [True,False,True,True]  将变为  [1,0,1,1]  ,平均值将为0.75,表示准确度的百分比  。现在我们可以使用mnist.test  作为feed_dict  参数来询问我们的测试数据集  的  准确性:

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

我获得了大约91%的价值。这些结果好吗?我认为它们太棒了,因为这意味着读者已经能够使用TensorFlow编程和执行她的第一个神经网络。

另一个问题是其他模型可能提供更好的准确性,这将在下一章中介绍包含更多层的神经网络。

读者可以在本书的  github  [38]中找到RedNeuronalSimple.py文件中本章使用的全部代码  。为了提供它的全局视图,我将把它放在一起:
 

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

import tensorflow as tf

x = tf.placeholder("float", [None, 784])
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))

matm=tf.matmul(x,W)
y = tf.nn.softmax(tf.matmul(x,W) + b)
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)

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

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})
    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})

猜你喜欢

转载自blog.csdn.net/taotaobaobei/article/details/83313475