代码可在https://github.com/TimeIvyace/MNIST-TensorFlow.git
<https://github.com/TimeIvyace/MNIST-TensorFlow.git>中下载,程序名为train.py。


以下代码实现了使用TensorFlow搭建神经网络解决MNIST手写体数字识别问题,此神经网络使用了激活函数去线性化,本身为三层全连接结构,带有指数衰减的学习率以及L2正则化损失函数,同时使用滑动平均模型进行优化。
import tensorflow as tf from tensorflow.examples.tutorials.mnist import
input_data INPUT_NODE =784 #输入层的节点数,图片为28*28,为图片的像素 OUTPUT_NODE = 10
#输出层的节点数,等于类别的数目,需要区分0-9,所以为10类 #配置神经网络的参数 LAYER1_NODE = 500
#隐藏层的节点数,此神经网络只有一层隐藏层 BATCH_SIZE = 100
#一个训练batch中的训练数据个数,数字越小,越接近随机梯度下降,越大越接近梯度下降 LEARNING_RATE_BASE = 0.8 #基础的学习率
LEARNING_RATE_DECAY =0.99 #学习率的衰减率 REGULARIZATION_RATE = 0.0001
#描述网络复杂度的正则化向在损失函数中的系数 TRAINING_STEPS = 30000 #训练轮数 MOVING_AVERAGE_DECAY = 0.99
#滑动平均衰减率 #给定神经网络的输入和所有参数,计算神经网络的前向传播结果,定义了一个使用ReLU的三层全连接神经网络,通过加入隐藏层实现了多层网络结构
def inference(input_tensor, avg_class, weights1, biases1, weights2, biases2):
#若没有提供滑动平均类,则直接使用参数当前的取值 if avg_class == None: #计算隐藏层的前向传播结果,使用ReLU激活函数 layer1
= tf.nn.relu(tf.matmul(input_tensor, weights1) + biases1)return
tf.matmul(layer1, weights2)+biases2else: #首先使用avg_class.average来计算得出变量的滑动平均值
#然后在计算相应的神经网络前向传播结果 layer1 = tf.nn.relu(tf.matmul(input_tensor,
avg_class.average(weights1)) + avg_class.average(biases1))return
tf.matmul(layer1, avg_class.average(weights2))+avg_class.average(biases2)
#训练网络的过程 def train(mnist): x = tf.placeholder(tf.float32, [None, INPUT_NODE],
name='x-input') y_ = tf.placeholder(tf.float32, [None, OUTPUT_NODE], name=
'y-input') #使用截断正态分布生成隐藏层的参数 weights1 =
tf.Variable(tf.truncated_normal([INPUT_NODE, LAYER1_NODE], stddev=0.1)) biases1
= tf.Variable(tf.constant(0.1, shape=[LAYER1_NODE])) #生成输出层的参数 weights2 =
tf.Variable(tf.truncated_normal([LAYER1_NODE, OUTPUT_NODE], stddev=0.1))
biases2 = tf.Variable(tf.constant(0.1, shape=[OUTPUT_NODE]))
#计算在当前参数下神经网络前向传播的结果,这里的用于计算滑动平均的类为None,所以没有使用滑动平均值 y = inference(x, None,
weights1, biases1, weights2, biases2)#定义存储训练轮数的变量,这个变量不需要被训练 global_step =
tf.Variable(0, trainable=False) #初始化滑动平均类 variable_averages =
tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
#在所有代表神经网络参数的变量上使用滑动平均,需要被训练的参数,variable_averages返回的就是GraphKeys.TRAINABLE_VARIABLES中的元素
variable_averages_op = variable_averages.apply(tf.trainable_variables())
#计算使用了滑动平均之后的前向传播结果,滑动平均不会改变变量本身取值,会用一个影子变量来记录 average_y = inference(x,
variable_averages, weights1, biases1, weights2, biases2)
#计算交叉熵,使用了sparse_softmax_cross_entropy_with_logits,当问题只有一个正确答案时,可以使用这个函数来加速交叉熵的计算。
#这个函数的第一个参数是神经网络不包括softmax层的前向传播结果,第二个是训练数据的正确答案,argmax返回最大值的位置 cross_entropy =
tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_,1))
#计算在当前batch中所有样例的交叉熵平均值 cross_entropy_mean = tf.reduce_mean(cross_entropy)
#计算L2正则化损失 regularizer = tf.contrib.layers.l2_regularizer(REGULARIZATION_RATE)
#计算网络的正则化损失 regularization = regularizer(weights1) + regularizer(weights2)
#总损失为交叉熵损失和正则化损失之和 loss = cross_entropy_mean + regularization #设置指数衰减的学习率
learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step,
mnist.train.num_examples/BATCH_SIZE, LEARNING_RATE_DECAY)
#LEARNING_RATE_BASE为基础学习率,global_step为当前迭代的次数
#mnist.train.num_examples/BATCH_SIZE为完整的过完所有的训练数据需要的迭代次数
#LEARNING_RATE_DECAY为学习率衰减速度 #使用GradientDescentOptimizer优化算法优化损失函数 train_step =
tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,
global_step=global_step)#在训练神经网络的时候,每过一遍数据都要通过反向传播来更新参数以及其滑动平均值 #
为了一次完成多个操作,可以通过tf.control_dependencies和tf.group两种机制来实现 # train_op =
tf.group(train_step, variable_averages_op) #和下面代码功能一样 with
tf.control_dependencies([train_step, variable_averages_op]): train_op =
tf.no_op(name ='train') #检验使用了滑动平均模型的神经网络前向传播结果是否正确 #f.argmax(average_y,
1)计算了每一个样例的预测答案,得到的结果是一个长度为batch的一维数组 #一维数组中的值就表示了每一个样例对应的数字识别结果
#tf.equal判断两个张量的每一维是否相等。如果相等返回True,反之返回False correct_prediction =
tf.equal(tf.argmax(average_y,1), tf.argmax(y_, 1)) #首先将一个布尔型的数组转换为实数,然后计算平均值
#平均值就是网络在这一组数据上的正确率 accuracy = tf.reduce_mean(tf.cast(correct_prediction,
tf.float32))#初始会话并开始训练过程 with tf.Session() as sess:
tf.global_variables_initializer().run()#参数初始化
#准备验证数据,在神经网络的训练过程中,会通过验证数据来大致判断停止的条件和评判训练的效果 validate_data = {x:
mnist.validation.images, y_:mnist.validation.labels}#准备测试数据 test_data =
{x:mnist.test.images, y_:mnist.test.labels}#迭代的训练神经网络 for i in
range(TRAINING_STEPS):#每1000轮输出一次在验证数据集上的测试结果 if i%1000==0:
#计算滑动平均模型在验证数据上的结果,因为MNIST数据集较小,所以可以一次处理所有的验证数据 validate_acc =
sess.run(accuracy, feed_dict=validate_data) print("After %d training steps,
validation accuracy using average model is %g" %(i, validate_acc)) #
产生训练数据batch,开始训练 xs, ys = mnist.train.next_batch(BATCH_SIZE) # xs为数据,ys为标签
sess.run(train_op, feed_dict={x:xs, y_:ys}) test_acc = sess.run(accuracy,
feed_dict=test_data) print("After %d training steps, validation accuracy using
average model is %g" %(TRAINING_STEPS, test_acc)) #程序主入口 def main(argv=None): #
声明处理MNIST数据集的类,one_hot=True将标签表示为向量形式 mnist = input_data.read_data_sets(
"/tensorflow_google", one_hot=True) train(mnist)
#TensorFlow提供程序主入口,tf.app.run会调用上面定义的main函数 if __name__ =='__main__':
tf.app.run() >>After0 training steps, validation accuracy using average model is
0.0934 After 1000 training steps, validation accuracy using average model is
0.978 After 2000 training steps, validation accuracy using average model is
0.982 After 3000 training steps, validation accuracy using average model is
0.983 After 4000 training steps, validation accuracy using average model is
0.9848 After 5000 training steps, validation accuracy using average model is
0.9836 . . . After 30000 training steps, validation accuracy using average model
is 0.983

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信