算法实现过程的详细介绍
- 对Minist数据进行加载,利用Tensorflow提供的封装函数
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
- 查看一下mnist数据集的情况,可以发现训练集有55000个样本,测试集有10000个样本,同时验证集有5000个样本。每一个样本都有它对应的标注信息。
print(mnist.train.images.shape, mnist.train.labels.shape)
print(mnist.test.images.shape, mnist.test.images.shape)
print(mnist.validation.images.shape, mnist.validation.labels.shape)
- 然后我们将2828的手写数字图片展开为784的一维向量,注意这个的确会丢失空间结构,但是由于这个数据集的分类任务比较简单,所以这里可以不考虑空间结构,后面用CNN的话就考虑。这里,我们的训练数据特征是一个55000784的Tensor,第一个维度是图片的编号,第二个维度是图片中像素点的编号。同时,训练数据的Label是一个10维的向量,只有一个值是1,其余是0.这里使用Softmax Regression的算法训练手写数字识别的分类模型,我们的数字是0-9之间的,所以一共有10个类别,最后取各个类别中概率最大的作为结果输出。对于一张图片,我们可以将特征携程 featurei=∑jWi,jxj+bi,其中i表示第i类,j表示一张图片的第j个像素, bi是bias。然后对所有特征计算softmax,结果如下: softmax(x)=normalize(exp(x)),其中判定为第i类的概率就是 softmax(x)i=∑jexp(xj)exp(xi),我们先对各个类的特征求exp函数,然后再对它们标准化,使得和为1,特征的值越大的类,最后输出的概率也为1,用矩阵的形式来看可以表示为 y=softmax(Wx+b)
- 载入Tensorflow库,并创建一个新的InteractiveSession,使用这个命令会将这个Session注册为默认的Session,之后的运算也默认跑在这个Session里面,不同session之间的数据和运算都是相互独立的人。接下来创建一个placeholder,表示输入数据的占位符号。
#注册为默认的Session
sess = tf.InteractiveSession()
x = tf.placeholder(tf.float32, [None, 784])
- 给Softmax Regression模型中的weights和bias创建Variable对象,并将weights和bias初始化为0,在初始化的时候,由于这里是浅层并且很简单的网络,所以初始化为0,如果对于深层网络,权重初始化是一门大学问了。再定义一下Softmax Regression模型。
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x, W)+b)
- 为了训练模型,我们还需要定义损失函数。Loss越小,代表模型的分类结果和真实值的偏差越小,也就是说模型更精确,我们一开始把模型填充了0,所以模型有一个初始Loss,我们的目的是不断将这个Loss缩小,得到一个全局或者局部最优解。对于多分类问题,常用交叉熵损失函数,公式吐下 Hy′(y)=−∑iyi′log(yi),其中y是预测的概率分布, y′是真实的概率分布。
先定义一个占位符,输入时真实的label,用来计算cross-entropy。这里的y_*tf.log(y)也就是前面公式的 yi′log(yi),tf.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)))
7.接下来定义个优化算法开始训练,这里使用随机梯度下降SGD。定义好优化算法之后,Tensorflow就可以根据我们定义的整个计算图(前面我们定义好的公式已经构成了计算图)自动求导,并根据反向传播算法进行训练,我们直接调用tf.train.GradientDescentOptimizer,并设置学习速率为0.5,优化目标设定为cross-entropy,得到进行,得到进行训练的操作train_step。
train_step = tf.train.GradientDescentOptimizer(0.0005).minimize(cross_entropy)
- 下一步使用Tensorflow的全局参数初始化器tf.global_variables_initalizer(),并直接执行它的run方法。
tf.global_variables_initializer().run()
- 最后一步,我们开始迭代执行训练操作train_step,这里每次随机从训练集中抽取100条样本构成mini-batch,并feed给placeholder,然后调用train_step对这些样本进行训练。使用一小部分样本进行训练称为随机梯度下降,与全局随机梯度下降对应。
for i in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100)
train_step.run(feed_dict={x: batch_xs, y_:batch_ys})
print(i)
- 现在我们已经完成了训练,接下来就对模型的准确率进行验证。
correct_prediction = tf.equal(tf.arg_max(y, 1), tf.arg_max(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x:mnist.test.images, y_:mnist.test.labels}))
最后打印出来的准确率是92%左右。
算法完整代码
#coding=utf-8
#softmax Regression
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
print(mnist.train.images.shape, mnist.train.labels.shape)
print(mnist.test.images.shape, mnist.test.images.shape)
print(mnist.validation.images.shape, mnist.validation.labels.shape)
#注册为默认的Session
sess = tf.InteractiveSession()
x = tf.placeholder(tf.float32, [None, 784])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x, W)+b)
y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y)))
train_step = tf.train.GradientDescentOptimizer(0.0005).minimize(cross_entropy)
#全局参数初始化
tf.global_variables_initializer().run()
for i in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100)
train_step.run(feed_dict={x: batch_xs, y_:batch_ys})
print(i)
#计算准确率
correct_prediction = tf.equal(tf.arg_max(y, 1), tf.arg_max(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(accuracy.eval({x:mnist.test.images, y_:mnist.test.labels}))