《人工智能实践:Tensorflow笔记》听课笔记21_5.3手写数字识别准确率输出

附:课程链接

第五讲.全连接网络基础
5.3手写数字识别准确率输出

由于个人使用Win7系统,并未完全按照课程所讲,以下记录的也基本是我的结合课程做的Windows系统+PyCharm操作。且本人有python基础,故一些操作可能简略。并未完全按照网课。

记住编写代码时,除注释内容外,字符均使用英文格式。

本节目标:搭建神经网络,在MNIST数据集上训练模型,输出手写数字识别准确率。

五、实例学习
实现手写体mnist数据集的识别任务,共分为三个模块文件:
描述网络结构的前向传播文件mnist_forward.py
描述网络参数优化方法的反向传播文件mnist_backward.py
验证模型准确率的测试过程文件mnist_test.py

1.前向传播文件mnist_forward.py
在前向传播过程中,需要定义网络模型输入层个数、隐藏层节点数、输出层个数,定义网络参数w、偏置b,定义由输入到输出的神经网络架构。

"""
    前向传播
"""
import tensorflow as tf

#在前向传播中,首先定义了神经网络的相关参数
INPUT_NODE = 784    #神经网络输入节点为784个
#(代表每张图片输入的像素点个数28*28=784,每个像素点是0-1之间的浮点数)。
#这784个点组成了一个一维数组
OUTPUT_NODE = 10    #输出10个数,每个数表示对应索引号出现的概率,实现了数字0-9的十分类
LAYER1_NODE = 500   #定义了隐藏层的节点个数

"""
    与参数w有关
    get_weight有两个参数,一个是w的形状shape,一个是正则化权重regularizer
"""
def get_weight(shape,regularizer):
    w = tf.Variable(tf.truncated_normal(shape,stddev=0.1))   #通过tf.Variable()函数在训练神经网络时随机生成参数w
    if regularizer != None: tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w))
    #如果使用正则化(regularizer != None),则把每一个w的正则化计入到总losses
    return w

"""
    与参数b有关
    get_bias有一个参数,一个是b的形状shape,其实就是某层中b的个数
"""
def get_bias(shape):
    b = tf.Variable(tf.zeros(shape))   #给b赋初值,()里写赋初值的方法。这些方法在3.2中讲过
    return b

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

    # 第二层参数w2、偏置b2、输出y
    w2 = get_weight([LAYER1_NODE,OUTPUT_NODE], regularizer)
    b2 = get_bias(OUTPUT_NODE)
    y = tf.matmul(y1,w2) + b2   #此y直接输出。因为输出y要经过softmax函数,使其符合概率分布,故输出y不经过relu函数
    return y

2.反向传播文件mnist_backward.py
反向传播过程实现利用训练数据集对神经网络的模型训练,通过降低损失函数值,实现网络模型参数的优化,从而得到准确率高且泛化能力强的神经网络模型。

"""
    反向传播
"""
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import mnist_forward
import os   #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 = "mnist_model" #模型的保存路径
MODEL_NAME = "mnist_model"  #模型保存的文件名

#对于反向传播而言,要训练网络参数
def backward(mnist):    #在backward函数中读入mnist
    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, 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))  # 实现softmax和交叉熵的协同使用
    cem = tf.reduce_mean(ce)
    loss = cem + tf.add_n(tf.get_collection('losses'))  #调用包含正则化的损失函数loss

    #定义指数衰减学习率
    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
    saver = tf.train.Saver() #tf.compat.v1.train.Saver

    #在with结构中初始化所有变量
    with tf.Session() as sess:
        init_op = tf.global_variables_initializer()
        sess.run(init_op)

        #在for循环中迭代STEPS轮
        for i in range(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})    #喂入神经网络,执行相关过程
            if i % 1000 == 0:   #每1000轮打印loss值
                print("After %d training steps(s),loss on training batch is %g"%(step,loss_value))
                saver.save(sess,os.path.join(MODEL_SAVE_PATH,MODEL_NAME),global_step=global_step)   #保存模型到当前会话

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

if __name__ == '__main__':
    main()

3.测试文件mnist_test.py
当训练完模型后,给神经网络模型输入测试集验证网络的准确性和泛化性,注意,所用的测试集和训练集是相互独立的。

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  #定义程序循环的间隔时间是5s

def test(mnist):
    with tf.Graph().as_default() as g:  #绘制计算图中的节点
        #给输入图像x和y_占位
        x = tf.placeholder(tf.float32, [None, mnist_forward.INPUT_NODE])
        y_ = tf.placeholder(tf.float32, [None, mnist_forward.OUTPUT_NODE])
        #用前向传播过程计算出y的值
        y = mnist_forward.forward(x, None)

        #实例化可还原滑动平均的saver,这样所有参数在会话中北加载时会被赋值为各自的滑动平均值
        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:
                #加载训练好的模型ckpt,也就是把滑动平均值赋给各个参数
                ckpt = tf.train.get_checkpoint_state(mnist_backward.MODEL_SAVE_PATH)
                #如果已有ckpt模型则恢复
                if ckpt and ckpt.model_checkpoint_path:
                    #恢复会话
                    saver.restore(sess,ckpt.model_checkpoint_path)
                    #恢复轮数
                    global_step = int(ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1])
                    #计算准确率
                    accuracy_score = sess.run(accuracy,feed_dict = {x:mnist.test.images,y_:mnist.test.labels})
                    #打印提示
                    print("After %s training step(s),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("mnist_work/", one_hot=True)
    test(mnist)

if __name__ == '__main__':
    main()

注意
对于global_step = int(ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]) 这句话,课程中原本是global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1] ,但是在实际运行代码结果时,会出现这样的结果:
在这里插入图片描述
我们发现训练轮数并没有改变,而老师在print("After %s training step(s),test accuracy = %g"%(global_step,accuracy_score))中使用的占位符也是%s,即为一个字符串string占位,但事实并非如此。现在大部分人使用的都是python3.x,在python2.x中老师的例子是成功的,训练轮数在改变,但是在我们这里就不适用了,所以要改成:global_step = int(ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1])将字符串变作整形,这样训练轮数才会改变:
在这里插入图片描述
我竟然把这个debug出来了,哭泣】

先运行mnist_backward.py文件
首先下载了数据集(无视WARNING):
在这里插入图片描述
开始训练且从打印出来的内容可以看到loss在减小(仅显示首尾部分训练过程):
在这里插入图片描述
在这里插入图片描述
运行mnist_test.py文件(运行了一段时间mnist_backward文件后,再同时运行mnist_test.py文件。这样可以同时观察准确率的提高),最后准确率达到:
在这里插入图片描述
第五讲至此结束。

附:助教的TensorFlow笔记5

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值