深度学习(二)

来源:互联网 发布:淘宝买东西警察还查吗 编辑:程序博客网 时间:2024/05/18 21:50

只是用作学习笔记使用,所以很多部分是直接粘的TensorFlow中文社区的话!!!

MNIST数据集

1.每一个MNIST数据单元有两部分组成:一张包含手写数字的图片和一个对应的标签。我们把这些图片设为“xs”,把这些标签为“ys”。训练数据集和测试数据集都包含xs和ys,比如训练数据集的图片是 mnist.train.images ,训练数据集的标签是 mnist.train.labels每一张图片包含28像素X28像素。我们可以用一个数组来表示这张图片。
因此,在MNIST训练数据集中,mnist.train.images 是一个形状为 [60000, 784] 的张量,第一个维度数字用来索引图片,第二个维度数字用来索引每张图片中的像素点。在此张量里的每一个元素,都表示某张图片里的某个像素的强度值,值介于0和1之间。
相对应的MNIST数据集的标签是介于0到9的数字,用来描述给定图片里表示的数字。数字n将表示成一个只有在第n维度(从0开始)
数字为1的10维向量。比如,标签0将表示成([1,0,0,0,0,0,0,0,0,0,0])。因此, mnist.train.labels 是一个 [60000, 10] 的数字矩阵。

2.Softmax回归
softmax模型可以用来给不同的对象分配概率。即使在之后,我们训练更加精细的模型时,最后一步也需要用softmax来分配概率。
softmax回归(softmax regression)分两步:(1)为了得到一张给定图片属于某个特定数字类的证据(evidence),我们对图片像素值进行加权求和。如果这个像素具有很强的证据说明这张图片不属于该类,那么相应的权值为负数,相反如果这个像素拥有有

利的证据支持这张图片属于这个类,那么权值是正数。

我们也需要加入一个额外的偏置量(bias),因为输入往往会带有一些无关的干扰量。因此对于给定的输入图片 x 它代表的是数字 i 的证据可以表示为

其中  代表图片对第i类数字的权重, 代表数字第 i 类的偏置量,j 代表给定图片 x 的每个像素点(为1或者0)。然后用softmax函数表示概率 y

因此,给定一张图片,它对于每一个数字的吻合度可以被softmax函数转换成为一个概率值。softmax函数可以定义为:

展开等式右边的子式,可以得到:

对于softmax回归模型可以用下面的图解释,对于输入的xs加权求和,再分别加上一个偏置量,最后再输入到softmax函数中:

如果把它写成一个等式,我们可以得到:

(这张图有错,每一行应分别为X1,X2,X3)

我们也可以用向量表示这个计算过程:用矩阵乘法和向量相加。这有助于提高计算效率。(也是一种更有效的思考方式)

更进一步,可以写成更加紧凑的方式:

3.回归模型实现

TensorFlow也把复杂的计算放在python之外完成,但是为了避免前面说的那些开销,它做了进一步完善。Tensorflow不单独地运行

单一的复杂计算,而是让我们可以先用图描述一系列可交互的计算操作,然后全部一起在Python之外运行。

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

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

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

W = tf.Variable(tf.zeros([784,10]))
#想要用784维(每个像素平铺)的图片向量乘以W以得到一个10维的证据值向量,每一位对应不同数字类。b = tf.Variable(tf.zeros([10]))
#偏移量可以直接把它加到输出上面
y = tf.nn.softmax(tf.matmul(x,W) + b)
#用tf.matmul(​​X,W)表示x乘以W,对应之前等式里面的,这里x是一个2维张量(二维张量指第几张图对应的哪个像素点)拥有多个输入。然后再加上b,把和输入到tf.nn.softmax函数里面。


4.训练模型

首先需要定义一个指标来评估这个模型是好的。其实,在机器学习,我们通常定义指标来表示一个模型是坏的,这个指标称为成本(cost)或损失(loss),然后尽量最小化这个指标。但是,这两种方式是相同的。

一个常用的的成本函数是“交叉熵”。它的定义如下:

y 是我们预测的概率分布, y' 是实际的分布。(具体交叉熵性质参考http://blog.csdn.net/u012162613/article/details/44239919)

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

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

然后我们可以用  计算交叉熵:

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

注意,这里的交叉熵是所有100幅图片的交叉熵的总和。对于100个数据点的预测表现比单一数据点的表现能更好地描述我们的模型的性能。


因为TensorFlow拥有一张描述各个计算单元的图,它可以自动地使用反向传播算法(backpropagation algorithm)来有效地确定你的变量是如

何影响你想要最小化的那个成本值的。然后,TensorFlow会用你选择的优化算法来不断地修改变量以降低成本。


#梯度下降算法(gradient descent algorithm)以0.01的学习速率最小化交叉熵

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

这一行代码实际上是用来往计算图上添加一个新操作,其中包括计算梯度,计算每个参数的步长变化,并且计算出新的参数值。

返回的train_step操作对象,在运行时会使用梯度下降来更新参数。因此,整个模型的训练可以通过反复地运行train_step来完成。

TensorFlow只需将每个变量一点点地往使成本不断降低的方向移动(具体怎么操作的还不太清楚)

然后开始训练模型,这里我们让模型循环训练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})

该循环的每个步骤中,我们都会随机抓取训练数据中的100个数据,然后我们用并通过feed_dictx 和 y_张量占位符用训练数据替代(在计算图中,你可以用feed_dict来替代任何张量,并不仅限于替换占位符)。

使用一小部分的随机数据来进行训练,在这里更确切的说是随机梯度下降训练。
(所以这里具体做了什么??找出部分训练数据不断拟合,最终找出训练数据的特性??)
5.评估模型

tf.argmax 是一个非常有用的函数,它能给出某个tensor对象在某一维上的其数据最大值所在的索引值。由于标签向量是由0,1组成,因此最大值1所在的索引位置就是类别标签,比如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, "float"))

最后,我们计算所学习到的模型在测试数据集上面的正确率。

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

0 0
原创粉丝点击