初学TensorFlow和机器学习,MNIST算法的每条语句都不是很清楚,通过查阅资料,将每句代码的基本用法差不多理解了。希望能够帮助正在学习的你
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)
mnist.train:训练数据,mnist.test:测试数据,mnist.valication:开发数据.
每份MNIST数据包含手写数字图像(后记为xs)和对应标注(后记为ys)2部分,训练集和测试集均包含xs和ys.
所以训练图像是mnist.train.images、训练标注是mnist.train.labels.
print(mnist.train.images.shape,mnist.train.labels.shape)
print(mnist.test.images.shape,mnist.test.labels.shape)
print(mnist.validation.images.shape,mnist.validation.labels.shape )
载入TensorFlow库,创建新的InteractionSession,使用命令将session注册为默认的session,之后的运算默认跑在这个session. 不同session之间的数据和运算是相互独立的.
import tensorflow as tf
sess = tf.InteractiveSession()
x表示所有的手写体图片。它并不是一个固定值而是一个占位符,只有在TensorFlow运行时才会被设定真实.
创建一个Placeholder,即输入数据的地方.
第一个参数是数据类型,表示一个二维浮点数
第二个参数[None,784]代表tensor的shape,代表数据的尺寸,None代表不限条数的输入,784代表每条输入是一个784维的向量
x = tf.placeholder(tf.float32,[None,784])
tf.Variable创建变量,使用 tf.zeros 将变量 W 和 b 设为初始化全为0的张量.
w用一个784维度的向量表示像素值,代表每个图片都有784个像素点.用10维度的向量表示分类,代表从“0”到“9”一共有10类图片.
而2个向量进行乘法运算(或者说2个向量的笛卡尔集)就表示“某个像素在某个分类下的证据”。
b的形状是[10],他仅表示10个分类的偏移值。
w = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
tf.matmul是TensorFlow中的矩阵乘法函数tf.matmul(x, W) 表达式表示W和x的乘积运算,对应之前等式(y=softmax(Wx+b))的Wx,这个计算结果会得到一个y1=[None, 10]的张量,表示每个图片在10个分类下权重计算结果。
tf.matmul(x, W) + b 表示执行y2=y1+b的运算,它计算每个分类的偏移量。y2还是一个[None,10]的张量。最后使用 tf.nn.softmax 进行归一计算,得到每张图片在每个分类下概率。
TensorFlow能够将forward和backward的内容自动实现,只要接下来定义好loss,训练时会自动求导并进行梯度下降
y = tf.nn.softmax(tf.matmul(x,w) + b)
定义一个placeholder,输入的是真实的label,用来计算cross-entropy.
y_ * tf.log(y)是对应交叉熵公式的乘积部分,
f.reduce_sum对应求和部分。
tf.reduce_mean则用来对每个batch数据结果求均值
y_ = tf.placeholder(tf.float32,[None,10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y),reduction_indices=[1]))
TensorFlow会根据我们定义的整个计算图自动求导,我们只需要调用封装好的优化器,提供数据给它就好.
调用tf.train.GradientDescentOptimizer,设置学习速率为0.5,优化目标设为cross-entropy,得到进行训练的操作train_step
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
使用TensorFlow的全局参数初始化器,执行它的run方法
tf.global_variables_initializer().run()
随机抽取100条样本构成一个mini-batch,并提供给placeholder
接着调用train_step对样本进行训练
for i in range(1000):
batch_xs,batch_ys = mnist.train.next_batch(100)
train_step.run({x:batch_xs,y_:batch_ys})
tf.argmax是从一个tensor中寻找最大值的序号
tf.argmax(y,1)是求各个预测的数字中概率最大的那一个
tf.argmax(y_,1)是找样本的真是数字类别。
而tf.equal则用来判断数字类别是否就是正确的类别。
correct_prediction表示计算分类是否正确
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
统计全部样本预测的accuracy
先用tf.cast将之前corrext_prediction输出的bool值转换为float32,再求平均值
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
将测试数据的特征和Label输入评测流程accuracy,计算模型在测试集上的准确率,打印结果
print(accuracy.eval({x:mnist.test.images,y_:mnist.test.labels}))
总结TensorFlow实现算法的流程:
1、载入TensorFlow库
2、创建一个占位符,输入数据//张量
3、创建两个变量w、b,用来存储模型参数,不同于tensor一旦使用掉就会消失,变量会在模型训练迭代中持久化,长期存在并不断更新
4、实现softmax regression算法,定义公式。
5、定义loss公式,选定优化算法,并指定优化loss
6、迭代地对数据进行训练
7、使用训练数据对模型的准确率进行验证
注意
需要注意的是我们定义的各个公式都是Computation Graph。在执行代码的时候,计算还没实际发生,只有等调用run方法,并feed数据时,计算才真正执行。比如cross_entropy、train_step、accuracy等都是计算图中的节点,而不是数据结果。我们调用run方法执行节点或者说操作来获取结果