• tensorflow1.12.1实现MNIST数据集训练和识别


    1.mnist_train.py

    # -*- coding: utf-8 -*-
    """
    Created on Mon Dec 23 20:01:39 2019
    tensorflow实现Lenet-5网络,mnist_train.py实现lenet-5训练过程
    @author: zhaoy
    """
    
    
    ##lenet-5训练过程
    
    import os
    
    import tensorflow as tf
    
    from tensorflow.examples.tutorials.mnist import input_data
    
    import numpy as np
    
     
    
    import mnist_inference
    
    
    ##配置神经网络的参数
    
    BATCH_SIZE=100
    
    LEARNING_RATE_BASE=0.01  #基础学习率
    
    LEARNING_RATE_DECAY=0.99
    
    REGULARAZTION_RATE=0.0001
    
    TRAINING_STEPS=30000
    
    MOVING_AVERAGE_DECAY=0.99
    
    ##模型保存的路径和文件名
    
    MODEL_SAVE_PATH="./model/"
    
    MODEL_NAME="model.ckpt"
    
    ##定义训练过程
    
    def train(mnist):
    
        #区别与全连接神经网络的输入是一个二维[None, mnist_inference.INPUT_NODE],
        #卷积神经网络的输入x是一个四维数组
        x=tf.placeholder(tf.float32,[
    
        BATCH_SIZE,                       # 第一维表示一个batch中样例的个数
    
        mnist_inference.IMAGE_SIZE,       # 第二维和第三维表示图片的尺寸28
    
        mnist_inference.IMAGE_SIZE,
    
        mnist_inference.NUM_CHANNELS],    #图像通道数,黑白图像赋值1,彩色图像赋值3
    
                     name='x-input')
    
        y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE] , name='y-input')  
    
        regularizer=tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE)
    
        y=mnist_inference.inference(x,True,regularizer)
    
        global_step=tf.Variable(0,trainable=False)
    
        #给定滑动平均衰减率和训练轮数的变量,初始化滑动平均类
    
        variable_averages=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
    
        #在所有代表神经网络参数的变量上使用滑动平均。
    
        variables_averages_op=variable_averages.apply(tf.trainable_variables())
    
        #计算交叉熵作为刻画预测值和真实值之间差距的损失函数
    
        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+tf.add_n(tf.get_collection('losses'))                                            #regularization
    
        #设置指数衰减的学习率
    
        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)
    
        #with tf.control_dependencies([train_step,variables_averages_op]):train_op=tf.no_op(name='train')
        train_op=tf.group(train_step, variables_averages_op)
        
    
        #初始化tensorflow持久化类
    
        saver=tf.train.Saver()
    
        ##初始化会话并开始训练过程
    
        with tf.Session() as sess:
    
            tf.global_variables_initializer().run()
    
            print("****************开始训练************************")  
    
           # 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):
    
                xs,ys=mnist.train.next_batch(BATCH_SIZE)
    
                #区别于全连接神经网络,卷积神经网络的输入为四维数组
                reshaped_xs = np.reshape(xs, (BATCH_SIZE,  
    
                                              mnist_inference.IMAGE_SIZE,  
    
                                              mnist_inference.IMAGE_SIZE,  
    
                                              mnist_inference.NUM_CHANNELS))
    
                train_op_renew,loss_value, step=sess.run([train_op,loss,global_step],
    
                                           feed_dict={x:reshaped_xs,y_:ys})
    
     
    
                if i%1000==0:
    
                    print("After %d training step(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(argv=None):
    
        mnist=input_data.read_data_sets("MNIST_data/",one_hot=True)
    
        train(mnist)
        
    
    if __name__=='__main__':
    
        tf.app.run()

    2.mnist_inference.py

    # -*- coding: utf-8 -*-
    """
    Created on Mon Dec 23 19:44:19 2019
    Tensorflow实现LeNet-5模型,mnist_inference.py实现神经卷积网络前向传播过程
    @author: zhaoy
    """
    ##实现神经卷积网络的前向传播过程
    
    import tensorflow as tf
    
    INPUT_NODE=784     
    OUTPUT_NODE=10
    IMAGE_SIZE=28
    
    NUM_CHANNELS=1
    NUM_LABELS=10
    
    #第一层卷积层的尺寸和深度
    CONV1_DEEP=32
    CONV1_SIZE=5
    
    #第二层卷积层的尺寸和深度
    CONV2_DEEP=64
    CONV2_SIZE=5
    
    #全连接层的节点个数
    FC_SISE=512
    
    tf.reset_default_graph()
    #定义卷积神经网络的前向传播过程,这里添加了一个新的参数train用以区分训练过程和测试过程;train为布尔量:
    #采用dropout机制防止过拟合,在全连接层layer5-fc1中包含dropout机制,
    def inference(input_tensor,train,regularizer):
    
        ##声明第一层卷积层的变量并实现前向传播过程,这一层的输入为28*28*1的矩阵,由于采取全0填充,所以输出层为28*28*32的矩阵    
        with tf.variable_scope('layer1-conv1'):
    
            conv1_weights=tf.get_variable("weights",[CONV1_SIZE,CONV1_SIZE,NUM_CHANNELS,CONV1_DEEP],
    
                                          initializer=tf.truncated_normal_initializer(stddev=0.1))
    
            conv1_biases=tf.get_variable("bias",[CONV1_DEEP],initializer=tf.constant_initializer(0.0))
    
            #使用边长为5,深度为32的过滤器,过滤器移动的步长为1,且使用全0填充.
    
            conv1=tf.nn.conv2d(input_tensor,conv1_weights,strides=[1,1,1,1],padding='SAME')
    
            relu1=tf.nn.relu(tf.nn.bias_add(conv1,conv1_biases))
    
        ##实现第二层(池化层的前向传播过程),这里选用最大池化层,池化层的过滤器的边长为2,所以输出为14*14*32
        with tf.name_scope('layer2-poll'):
    
            pool1=tf.nn.max_pool(relu1,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
    
        ##声明第三层卷积层的变量并实现前向传播过程,这一层的输入为14*14*32的矩阵,输出为14*14*64
        with tf.variable_scope('layer3-conv2'):
    
            conv2_weights=tf.get_variable("weights",[CONV2_SIZE,CONV2_SIZE,CONV1_DEEP,CONV2_DEEP],
    
                                          initializer=tf.truncated_normal_initializer(stddev=0.1))
    
            conv2_biases=tf.get_variable("bias",[CONV2_DEEP],initializer=tf.constant_initializer(0.0))
    
     
    
            #使用边长为5,深度为64的过滤器,过滤器移动的步长为1,且使用全0填充.
    
            conv2=tf.nn.conv2d(pool1,conv2_weights,strides=[1,1,1,1],padding='SAME')
    
            relu2=tf.nn.relu(tf.nn.bias_add(conv2,conv2_biases))
    
        ##实现第四层池化层的前向传播过程,输入为14*14*64的矩阵,输出为7*7*64的矩阵
        with tf.name_scope('layer4-pool2'):
    
             pool2=tf.nn.max_pool(relu2,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
            
     
        #第四层的输出为7*7*64,然而第五层全连接层需要的输入格式为向量,所以这里需要将7*7*64拉伸为一个向量。
        #pool2.get_shape。因为每层网络的输入输出都是一batch,矩阵所以这里的维度也包含batch中数据的个数
        pool_shape=pool2.get_shape().as_list()
    
        nodes=pool_shape[1]*pool_shape[2]*pool_shape[3]
    
        #通过tf.reshape函数将第四层的输出编程一个batch的向量
        reshaped=tf.reshape(pool2,[pool_shape[0],nodes])
    
        #声明第五层全连接层的变量并实现前向传播过程,这一层是一个拉直后的一组向量,向量长度为3136,输出为为一组长度为512的向量
        #引入dropout机制,droupout在训练时会随机将部分节点输出为0,即使部分节点“死掉”
        with tf.variable_scope('layer5-fc1'):
    
            fc1_weights=tf.get_variable("weight",[nodes,FC_SISE],
    
                                        initializer=tf.truncated_normal_initializer(stddev=0.1))
    
            if regularizer!=None:
    
                tf.add_to_collection('losses',regularizer(fc1_weights))
    
            fc1_biases=tf.get_variable("bias",[FC_SISE],initializer=tf.constant_initializer(0.1))
    
     
    
            fc1=tf.nn.relu(tf.matmul(reshaped,fc1_weights)+fc1_biases)
            
            #duopout系数为0.5
            if train:fc1=tf.nn.dropout(fc1,0.5)
    
        ##声明第六层全连接层的变量并实现前向传播过程,这一层输入为长度为512的向量,输出为一组长度10的向量
        with tf.variable_scope('layer6-fc2'):
    
            fc2_weights=tf.get_variable("weight",[FC_SISE,NUM_LABELS],
    
                                        initializer=tf.truncated_normal_initializer(stddev=0.1))
    
            if regularizer!=None:
    
                tf.add_to_collection('losses',regularizer(fc2_weights))
    
            fc2_biases=tf.get_variable("bias",[NUM_LABELS],
    
                                       initializer=tf.constant_initializer(0.1))
    
            logit=tf.matmul(fc1,fc2_weights)+fc2_biases
    
        ##返回第六层的输出
        return logit

    3.mnist_test.py

    # -*- coding: utf-8 -*-
    """
    Created on Mon Dec 23 17:28:07 2019
    tensorflow实现神经网络对mnist手写字的识别,mnist_test.py评估训练的神经网络在mnist测试集的正确率
    @author: zhaoy
    """
    
    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    
    # 加载mnist_inference.py 和mnist_train.py中定义的常量和函数。
    import mnist_inference
    import mnist_train
    
    
    def evaluate(mnist):
        with tf.Graph().as_default() as g:
            # 定义输入输出的格式。
            x = tf.placeholder(tf.float32, [None, mnist_inference.INPUT_NODE], name='x-input')
            y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input')
            test_feed = {x: mnist.test.images, y_: mnist.test.labels}
    
            # 直接通过调用封装好的函数来计算前向传播的结果。因为测试时不关注ze正则化损失的值
            # 所以这里用于计算正则化损失的函数被设置为None。
            y = mnist_inference.inference(x, None)
    
            # 使用前向传播的结果计算正确率。如果需要对未知的样例进行分类,那么使用
            # tf.argmax(y,1)就可以得到输入样例的预测类别了。
            correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    
            # 同训练模型一样,定义一个滑动平均类
            variable_averages = tf.train.ExponentialMovingAverage(
                mnist_train.MOVING_AVERAGE_DECAY
            )
            
            #在使用滑动平均进行模型训练时,模型除了保存网络参数以外,还会保存相应的滑动平均参数,
            #此时加载模型参数需要联通滑动参数一起加载模型时,需要用到.variables_to_restore
            variables_to_restore = variable_averages.variables_to_restore()
            saver = tf.train.Saver(variables_to_restore)
    
            with tf.Session() as sess:
                # tf.train.get_checkpoint_state函数会通过checkpoint文件自动
                # 找到目录中最新模型的文件名。
                ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SAVE_PATH)
                if ckpt and ckpt.model_checkpoint_path:
                    # 加载模型。
                    saver.restore(sess, ckpt.model_checkpoint_path)
                    # 通过文件名得到模型保存时迭代的轮数。
                    #split函数:拆分字符串。通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(list)。
                    #split函数返回值为:分割后的字符串列表。
                    #list[n]:即表示选取第n个分片,n为-1即为末尾倒数第一个分片(分片即为在返回值列表中元素)
                    global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
                    accuracy_score = sess.run(accuracy, feed_dict=test_feed)
                    print("After %s training step(s), test " "accuracy = %g" % (global_step, accuracy_score))
                else:
                    print("No checkpoint file found")
                    return
    
    def main(argv=None):
        mnist = input_data.read_data_sets("C:/Users/zhaoy/Desktop/Tensorflow/sample/data/MNIST", one_hot=True)  #one_hot表示0-1编码
        evaluate(mnist)
    
    if __name__ == "__main__":
        tf.app.run()

    4.predict.py

    # -*- coding: utf-8 -*-
    """
    Created on Fri Dec 27 17:35:39 2019
    
    @author: zhaoy
    """
    import tensorflow as tf
    # 加载mnist_inference.py 和mnist_train.py中定义的常量和函数。
    import mnist_inference
    import mnist_train
    import cv2
    
    def imageprepare(file_name):
        im = cv2.imread(file_name,0)
        print(file_name)
        pixels = []
        h, w = im.shape
        #normalize pixels to 0 and 1. 0 is pure white, 1 is pure black.
        for i in range(h):
            for j in range(w):
                #如果是白底黑字则为:pixels.append((255-im[i,j])*1.0/255.0)
                pixels.append(im[i, j]*1.0/255.0)
        #print(pixels)
        return pixels
    
    # =============================================================================
    # def imageprepare(file_name):
    #     image = tf.gfile.FastGFile(file_name, 'rb').read()
    #     print(file_name)
    #     pixels = []
    #     image_data = tf.image.decode_jpeg(image)
    #     image_data = tf.image.convert_image_dtype(image_data, dtype=tf.float32)
    #     
    #     pixels.append(image_data)
    #     return pixels
    # =============================================================================
    
    x = tf.placeholder(tf.float32, [None, mnist_inference.INPUT_NODE], name='x-input')
    y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input')
    
    y = mnist_inference.inference(x, None)
    
    variable_averages = tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY)
    variables_to_restore = variable_averages.variables_to_restore()
    saver = tf.train.Saver(variables_to_restore)
    
    prediction = tf.argmax(y, 1)
    probability = tf.nn.softmax(y)
    
    with tf.Session() as sess:
        result = imageprepare('4.jpg')
        tf.global_variables_initializer().run()
        ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SAVE_PATH)
        if ckpt and ckpt.model_checkpoint_path:
            # 加载模型。
            saver.restore(sess, ckpt.model_checkpoint_path)        
    
            pre, prob = sess.run([prediction, probability], feed_dict={x:[result]})
            #pre = prediction.eval(feed_dict={x:[result]}, session=sess)
            #global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
            #accuracy_score = sess.run(accuracy, feed_dict=test_feed)
            print( "recognize result = %d," "the probability is %g " % (pre[0],prob[0][pre]))
        else:
            print("No checkpoint file found")
     
  • 相关阅读:
    算法技巧之打表
    Python_爬虫_爬取网络图片信息01
    python_爬虫_爬取京东商品信息
    Python——turtle库学习
    Python学习笔记——函数
    131219流水账
    121219流水账
    081219~111219流水账
    071219流水账
    061219流水账
  • 原文地址:https://www.cnblogs.com/xinyumuhe/p/12674392.html
Copyright © 2020-2023  润新知