from tensorflow.examples.tutorials.mnist import input_data
#载入minist数据集,如果指定地址/path/MNIST_data下么有已经下载好的数据,那么将自动下载
mnist=input_data.read_data_sets("C:/Users/jin/Documents/path/MNIST_data/",one_hot=True)
print(mnist.train.num_examples)#训练样本数
print(mnist.validation.num_examples)#验证样本数
print(mnist.test.num_examples)#测试样本数
print(mnist.train.images[0])#看看第一张图片的矩阵
mnist提供了生成batch的函数
batch_size=50
xs,ys=mnist.train.next_batch(batch_size)
print(xs.shape)
print(ys.shape)
下面给出了一个完整的神经网络训练mnist数字识别
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
INPUT_NODE=784#输入维度,28*28的图片
OUTPUT_NODE=10#输出分类维度
LAYER1_NODE=500#第一个隐层节点个数
BATCH_SIZE=100
LEARNING_RATE_BASE=0.8#初始学习率
LEARNING_RATE_DECAY=0.99#衰减指数
REGULARIZATION_RATE=0.0001#正则化系数
TRAINING_STEPS=30000#迭代轮数
MOVING_AVERAGE_DECAY=0.99#滑动平均模型的稳定率
#一个辅助函数,给定神经网络的输入和所有参数,计算神经网络的前向传播结果,在这里定义了一个使用ReLu激活函数的三层全连接网络。通过加入隐藏层实现了
#多层网络结构,avg_class代表了一个滑动平均的类
def inference(input_tensor,avg_class,weights1,biases1,weights2,biases2):
#当没有提供滑动平均类时,直接使用参数当前的取值
if(avg_class==None):#不适用滑动平均模型的神经网络
layer1=tf.nn.relu(tf.matmul(input_tensor,weights1)+biases1)
#计算输出层的前向传播结果
return tf.matmul(layer1,weights2)+biases2
else:
#首先使用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')#输入数据占位符,第一位设为None,可以适应任何batch数量
y_=tf.placeholder(tf.float32,[None,OUTPUT_NODE],name='y-output')
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]))
#不用滑动平均值的前向传播
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)#tf内置的滑动平均函数,需要提供两个参数,一个稳定的系数和当前迭代的轮数
variables_averages_op=variable_averages.apply(tf.trainable_variables())#滑动平均模型更新的参数就是所有可以训练的变量
average_y=inference(x,variable_averages,weights1,biases1,weights2,biases2)
#交叉熵损失作为刻画预测值和真实值的损失函数,用sparse_softmax_cross_entropy_with_logits函数计算交叉熵,问题只有一个正确答案,
#可以用这个函数加速交叉熵的计算。
#用tf.argmax()函数来得到正确答案对应的类别编号
cross_entropy=tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(y_,1),logits=y)#书上没有写labels和logits,因为tf的版本不同
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)
#使用tf.train.GradientDescentOptimizer优化算法来优化损失函数 minimize不仅可以优化全局参数,还可以计算global_step
train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)
#在训练神经网络模型时,每过一遍数据既要通过反向传播更新参数,又要更新每一个参数的滑动平均值,tf提供了tf.control_dependencies和tf.group两种
#机制,下面两行程序和train_op=tf.group(train_step,variables_averages_op)是等价的
with tf.control_dependencies([train_step,variables_averages_op]):
train_op=tf.no_op(name='train')
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.initialize_all_variables().run()
validation_feed={x:mnist.validation.images,y_:mnist.validation.labels}
test_feed={x:mnist.test.images,y_:mnist.test.labels}
for i in range(TRAINING_STEPS):
#每1000轮迭代输出一次在验证数据集上的测试结果
if(i%1000==0):
#计算滑动平均模型在验证数据集上的结果。因为mnist数据集比较小,所以一次可以处理所有的验证数据。
#为了计算方便,本样例程序没有将验证数据划分为更小的batch,当神经网络模型比较复杂或者验证数据比较大时,太大的batch会
#导致计算时间过长甚至发生内存溢出的错误
validate_acc=sess.run(accuracy,feed_dict=validation_feed)
print("after %d steps,validation accuracy using average model is %g"% (i,validate_acc))
xs,ys=mnist.train.next_batch(BATCH_SIZE)
sess.run(train_op,feed_dict={x:xs,y_:ys})
test_acc=sess.run(accuracy,feed_dict=test_dict)
print("after %d steps,test accuracy using average model is %g"%(i,test_acc))
#主程序入口
def main(argv=None):
mnist=input_data.read_data_sets("C:/Users/jin/Documents/path/MNIST_data/",one_hot=True)
train(mnist)
#tensorflow函数提供的一个主程序入口,tf.app.run会调用上面定义的main函数
if __name__=='__main__':
tf.app.run()