TensorFlow - 手写数字识别 (MNIST), 多类分类 (multiclass classification) 问题

TensorFlow - 手写数字识别 (MNIST), 多类分类 (multiclass classification) 问题

flyfish
softmax版
Python3.6编译

import tensorflow as tf

#导入input_data用于自动下载和安装MNIST数据集
#这里我在MNIST_data文件里放置之前下载的4个文件,
#t10k-images-idx3-ubyte.gz
#t10k-labels-idx1-ubyte.gz
#train-images-idx3-ubyte.gz
#train-labels-idx1-ubyte.gz

#下载下来的数据集被分成两部分:
# 60000行的训练数据集( mnist.train )train开头的文件
# 10000行的测试数据集( mnist.test )t10k开头的文件
#在机器学习模型设计时必须有一个单独的测试数据集不用于训练而是用来评估这个模型的性能,从而更加容易泛化
#(把设计的模型推广到其他数据集上)。
#关于数据的下载,TensorFlow已经编写好了,例如查看MNIST_data文件下有没有这4个文件,没有就下载
#每一个MNIST数据单元有两部分组成:一张包含手写数字的图片和一个对应的标签。
#图片设为“xs”,标签设为“ys”。训练数据集和测试数据集都包含xs和ys
#训练数据集的图片是 mnist.train.images
#训练数据集的标签是 mnist.train.labels

from tensorflow.examples.tutorials.mnist import input_data

#one-hot向量除了某一位的数字是1以外其余各维度数字都是0
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

#placeholder理解成形参 或者理解成C++里的 #define
#放置占位符,用于在计算时接收输入值
#每一张图片包含28X28个像素点。展开成一个向量,长度是 28x28 = 784。
#这里的 None 表示此张量的第一个维度可以是任何长度的。
x = tf.placeholder("float", [None, 784])

#创建两个变量,分别用来存放权重值W和偏置值b
# W 的维度是[784,10],因为我们想要用784维的图片向量乘以它以得到一个10维的证据值(evidence)向量,
#每一位对应不同数字类。
#  b 的形状是[10],所以我们可以直接把它加到输出上面。
#mnist.train.images 是一个形状为 [60000, 784] 的张量,第一个维度数字用来索引图片,
#第二个维度数字用来索引每张图片中的像素点
#矩阵乘法 第一个矩阵的列数(column)和第二个矩阵的行数(row)
#MNIST数据集的标签是介于0到9的数字,标签数据是one-hot向量。
#数字n将表示成一个只有在第n维度(从0开始)数字为1的10维向量。
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

#使用Tensorflow提供的回归模型softmax,y代表输出
#MNIST的每一张图片都表示一个数字,从0到9。
#目的得到给定图片代表每个数字的概率。
#例如模型可能推测一张包含9的图片代表数字9的概率是80%但是判断它是8的概率是5%(因为8和9都有上半部分的
#小圆),然后给予它代表其他数字的概率更小的值。
#这是使用softmax回归(softmax regression)模型的经典案例。
#softmax模型用来给不同的对象分配概率。

#softmax回归(softmax regression):

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

#softmax回归模型对于输入的 x 加权求和,再分别加上一个偏置量b,最后再输入到softmax函数中
#用向量表示这个计算过程:用矩阵乘法和向量相加 就是下面的式子
y = tf.nn.softmax(tf.matmul(x, W) + b)

#开始使用交叉墒
#y 是我们预测的概率分布, ' y' 是实际的分布
y_ = tf.placeholder("float", [None,10])

#计算交叉墒,这里的交叉熵不仅仅用来衡量单一的一对预测和真实值,而是所有100幅图片的交叉熵的总和。
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))

#TensorFlow用梯度下降算法(gradient descent algorithm)以0.01的学习速率最小化交叉熵
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

#初始化之前创建的变量的操作
init = tf.global_variables_initializer()

#启动初始化
sess = tf.Session()
sess.run(init)

#模型循环训练1000次随机抓取训练数据中的100个批处理数据点,
#然后我们用这些数据点作为参数替换之前的占位符来运行 train_step 。
#这里使用一小部分的随机数据来进行训练被称为随机梯度下降训练。
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})

#评估模型,tf.argmax 能找出那些预测正确的标签。
# 它能给出某个tensor对象在某一维上的其数据最大值所在的索引值。由于标签向量是由0,1组成,
#因此最大值1所在的索引位置就是类别标签,
# 比如 tf.argmax(y,1) 返回的是模型对于任一输入x预测到的标签值,
# 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"))

#在session中启动accuracy,输入是MNIST中的测试集
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
#结果是0.9151

你可能感兴趣的:(深度学习)