手写数字识别准确率输出

                                                                                                                                            点击此处返回总目录


 

 

【要求】

1. 包含正则化的损失函数。

2. 指数学习衰减率。

3. 滑动平均。

4. 模型支持断点续训功能。也就是,训练如果被中断,再次运行的时候,会找到断点,继续训练。

 

【实现】

整个工程共包括3个文件:

前向传播    mnist_forward.py                         //描述网络结构

后向传播    mnist_backward.py                      //描述网络参数优化方法

测试输出准确率   mnist_test.py                      //复现了计算图中的节点,计算模型在测试数据上的准确率

 

 

//mnist_forward.py

import tensorflow as tf

 

#首先定义了神经网络结构的相关参数
INPUT_NODE = 784                  #神经网络的输入节点是784个。因为输入的是图片像素值,每张图片是28*28=784个像素点。
OUTPUT_NODE = 10                #输出10个数,每个数表示对应的索引号出现的概率。实现了10分类。
LAYER1_NODE = 500               #隐藏层节点的个数

 

def get_weight(shape,regularizer):
    w = tf.Variable(tf.truncated_normal(shape,stddev = 0.1))        #随机生成参数w
    if regularizer !=None:             #如果使用正则化,则将每一个w的正则化损失加入到总损失集合losses
        tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w))
    return w    

def get_bias(shape):
    b = tf.Variable(tf.zeros(shape))
    return b


#搭建网络,描述从输入到输出的数据流
def forward(x,regularizer):
    w1 = get_weight([INPUT_NODE,LAYER1_NODE],regularizer)
    b1 = get_bias([LAYER1_NODE])
    y1 = tf.nn.relu(tf.matmul(x,w1)+b1)

    w2 = get_weight([LAYER1_NODE,OUTPUT_NODE],regularizer)
    b2 = get_bias([OUTPUT_NODE])
    y = tf.matmul(y1,w2)+b2                              #这个结果是直接输出的,因为要对输出使用softmax函数,使它符合概率分布,

                                                                        #所以输出y,不过relu函数。
    return y

 

 

 

//mnist_backward.py

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data   #导入模块
import mnist_forward
import os

BATCH_SIZE = 200                                  #每轮喂入神经网络多少张图片
LEARNING_RATE_BASE = 0.1                #初始的学习率
LEARNING_RATE_DECAY = 0.99            #学习率衰减率
REGULARIZER = 0.0001                         #正则化系数
STEPS = 50000                                       #共训练多少轮
MOVING_AVERAGE_DECAY = 0.99        #滑动平均衰减率
MODEL_SAVE_PATH = "./model/"            #模型的保存路径
MODEL_NAME = "mnist_model"              #模型的保存的文件名

def backward(mnist):                               #在backward函数中读入mnist数据集
    x=tf.placeholder(tf.float32,shape=(None,mnist_forward.INPUT_NODE))             #给x占位
    y_ = tf.placeholder(tf.float32,shape=(None,mnist_forward.OUTPUT_NODE))    #给y_占位
    
    #首先进行前向传播
    y = mnist_forward.forward(x,REGULARIZER)                            #调用前向传播的程序,计算输出y
    global_step = tf.Variable(0,trainable = False)                            #给轮数计数器赋初值,设定为不可训练
    
    
    ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels= tf.argmax(y_,1))          #交叉熵损失
    cem = tf.reduce_mean(ce)
    loss = cem+tf.add_n(tf.get_collection('losses'))                          #包含正则化的损失函数
    
    #指数学习衰减率
    learning_rate = tf.train.exponential_decay(
            LEARNING_RATE_BASE,
            global_step,
            mnist.train.num_examples/BATCH_SIZE,
            LEARNING_RATE_DECAY,
            staircase=True)
    
    
    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)  #定义训练过程
    
    ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)     #定义滑动平均
    ema_op = ema.apply(tf.trainable_variables())
    with tf.control_dependencies([train_step,ema_op]):
        train_op = tf.no_op(name='train')
        
        
        
    saver = tf.train.Saver()                                               #实例化saver对象
    with tf.Session() as sess:
        init_op = tf.global_variables_initializer()
        sess.run(init_op)

 

        #在会话中加入加载ckpt的操作,如果ckpt存在,则用saver.restore把ckpt恢复到当前会话。

        #这三句话实现了给所有的w和b赋保存在ckpt中的值,实现了断点续训。
        ckpt = tf.train.get_checkpoint_state(MODEL_SAVE_PATH)
        if ckpt and ckpt.model_checkpoint_path:
            saver.restore(sess, ckpt.model_checkpoint_path)

 

        for i in range(STEPS):                #迭代STEPS轮
            xs,ys = mnist.train.next_batch(BATCH_SIZE)                      #每次读入BATCH_SIZE组图片和标签
            _,loss_value,step = sess.run([train_op,loss,global_step],feed_dict={x:xs,y_:ys})       #把x,y喂入神经网络,执行训练过程train_op
            if i%1000 ==0:
                print("After %d training step(s),loss on training batchis %g" %(step,loss_value))    #每1000轮打印出当前的loss值

                #循环1000轮保存模型到当前会话
                saver.save(sess,os.path.join(MODEL_SAVE_PATH,MODEL_NAME),global_step = global_step)


def main():
    mnist = input_data.read_data_sets("./data/",one_hot = True)
    backward(mnist)

if __name__ =='__main__':
    main()
 

 

//mnist_test.py

# -*- coding: utf-8 -*-

import time                                                 #为了延迟,导入了time模块
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import mnist_forward
import mnist_backward
TEST_INTERVAL_SECS = 5                                        #定义程序循环的间隔时间为5秒

def test(mnist):                                                             #先读入mnist数据集
    with tf.Graph().as_default() as g:                             #用with tf.Graph复现计算图
        x = tf.placeholder(tf.float32, [None, mnist_forward.INPUT_NODE])          #给x占位
        y_ = tf.placeholder(tf.float32, [None,mnist_forward.OUTPUT_NODE])    #给y_占位
        y = mnist_forward.forward(x, None)                                   #用前向传播过程计算出y的值
        
        #实例化带滑动平均的server对象,这样所有参数在会话中被加载时会被赋值为各自的滑动平均值
        ema = tf.train.ExponentialMovingAverage(mnist_backward.MOVING_AVERAGE_DECAY)
        ema_restore = ema.variables_to_restore()
        saver = tf.train.Saver(ema_restore)
        
        
        #计算准确率
        correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))


        while True:
            with tf.Session() as sess:

                #用with结构,记载ckpt,也就是把滑动平均值赋给各个参数
                ckpt = tf.train.get_checkpoint_state(mnist_backward.MODEL_SAVE_PATH)  
                if ckpt and ckpt.model_checkpoint_path:                          #判断是否有模型。
                    saver.restore(sess, ckpt.model_checkpoint_path)        #恢复模型到当前会话
                    global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]     #恢复global_step值
                    accuracy_score = sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})      #执行准确率计算
                    print("After %s training steps, test accuracy = %g" %(global_step, accuracy_score))    #打印准确率
                else:                                                      #如果没有模型和参数
                    print("No checkpoint file found")                      #提示模型没找到
                    return
            time.sleep(TEST_INTERVAL_SECS)
            
def main():
    mnist = input_data.read_data_sets("./data/", one_hot = True)          #main()函数读入数据集
    test(mnist)                                                                                         #调用test()函数

if __name__ =='__main__':
    main()

 

运行方法:首先运行mnist_backward.py。再打开一个终端运行mnist_test.py同步看一下准确率。可以看到随着训练轮数的增加,准确率在逐渐提高。

 

运行结果(当第一次运行完之后的结果):

手写数字识别准确率输出_第1张图片

 

 

当执行到14000轮之后手动断开,再重启时的界面:

 

手写数字识别准确率输出_第2张图片

 

 

 

 

 

 

 

你可能感兴趣的:(17,深度学习)