MNIST数字识别问题

说明:1、损失函数 loss = cross_entropy_mean + regularization

                                  = cross_entropy_mean + regularizer(weights1)+regularizer(weights2)

           2、 预测值  y = w2y' + b2

                           = w2(w1x + b1) +b2

           3、在所有代表神经网络参数的变量上使用滑动平均,其他超参数不需要

           4、使用梯度下降优化算法优化损失函数,损失函数包括交叉熵损失和L2正则化损失

           5、在训练神经网络模型时,每过一遍数据既需要通过反向传播来更新参数,也要更新每个参数的滑动平均值

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("./data/MNIST/", one_hot=True)


#输入结点数为像素点数,输出结点数为类别数
INPUT_NODE=784
OUTPUT_NODE=10

#一个隐藏层
LAYER1_NODE=500

#一个批量中的样本量,数据量越小训练过程越接近SGD,数据量越大训练过程越接近梯度下降
BATCH_SIZE=100

#学习率和学习衰减率
LEARNING_RATE_BASE=0.8
LEARNING_RATE_DECAY=0.99

#正则化系数、迭代次数和滑动平均衰减率
REGULARIZATION_RATE=0.0001
TRAINING_STEPS=3000
MOVING_AVERAGE_DECAY=0.99

#定义推断函数,给定所有参数下计算神经网络的前向传播结果。参数avg_class可确定推断中使不使用滑动平均模型
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)+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')
    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_hat=inference(x,None,weights1,biases1,weights2,biases2)

    #定义储存迭代数的变量,这个变量不需要计算滑动平均值,所以这里指定的这个变量为不饿训练变量(trainable=False)
    global_step=tf.Variable(0,trainable=False)
    
    #给定滑动平均衰减率和迭代数,初始化滑动平均类。
    variable_averages=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
    
    #在所有代表神经网络参数的变量上使用滑动平均,其他超参数不需要。tf.trainable_variables返回的就是图上的集合GraphKeys.TRAINABLE_VARIABLES中的元素。
    variables_averages_op=variable_averages.apply(tf.trainable_variables())
    
    #计算使用滑动平均后的前向传播结果,滑动平均不会改变变量本身,而是使用影子变量记录滑动平均值,需要使用滑动平均再明确调用average函数
    average_y_hat=inference(x,variable_averages,weights1,biases1,weights2,biases2)
    
    #~使用tf.argmax函数得到正确答案对应的类别编号
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y, 1))
    
    #计算当前批量中所有样本的交叉熵均值
    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
    
    #设置指数衰减学习率.基础学习率、当前迭代次数、一个epoch所需要的迭代次数、学习衰减率
    learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,mnist.train.num_examples/BATCH_SIZE,LEARNING_RATE_DECAY)
    
    #使用梯度下降优化算法优化损失函数,损失函数包括交叉熵损失和L2正则化损失
    train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=global_step)
    
    #在训练神经网络模型时,每过一遍数据既需要通过反向传播来更新参数,也要更新每个参数的滑动平均值。为了一次完成多个操作
    #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_hat,1),tf.argmax(y,1))
    accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

    #初始化会话并开始训练过程
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        validate_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):
            if i % 1000 == 0:
                validate_acc = sess.run(accuracy, feed_dict=validate_feed)
                print("After %d training step(s), 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_feed)
        print(("After %d training step(s), test accuracy using average model is %g" %(TRAINING_STEPS, test_acc)))

运行结果:

 

avg_class = None
train(mnist)

运行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值