TensorFlow—mnist手写识别

神经网络:
重点在阙值和w,因为y=w1*x1+w2*x2+w3*x3...
激活函数:在隐藏层,每个输出点带入激活函数,然后再继续向后,最后输出的y预测值不需要激活
损失函数:定义的形式(三种):均方误差(西瓜书)、自定义需要的参数、交叉熵(吴恩达里面定义的有log的损失函数)

优化神经网络方法:1.定义合适的损失函数loss、选择合适的激活函数、2.不断更新学习率(梯度下降的学习率)、3.创建滑动平均值、4.正则化

实现过程:
1.(0,1)范围初始化所以连接权和阙值。
2.计算出y预测值。
3.BP算法,在循环中迭代,利用梯度下降算法优化w,使定义的损失函数最小化,同时得到w最优值。
4.输出连接权和阙值确定最优化的多层前馈神经网络。

1.前向传播

import tensorflow as tf
INPUT_NODE=784
OUTPUT_NODE=10
LAYER1_NODE=500

#初始化w
def get_weight_variable(shape,regularizer):
    weights=tf.get_variable("weights",shape,initializer=tf.truncated_normal_initializer(stddev=0.1))  #初始化变量
    if regularizer !=None:
        tf.add_to_collection('losses',regularizer(weights))   #当前变量的正则化损失加到losses中
    return weights
#前向传播
def inference(input_tensor,regularizer):
    with tf.variable_scope('layer1'):  #tf.get_variable 与tf.Variable 用法一致
        weights=get_weight_variable([INPUT_NODE,LAYER1_NODE],regularizer)   #784*500
        biases=tf.get_variable("biases",[LAYER1_NODE],initializer=tf.constant_initializer(0.0))  #500个隐藏层神经元
        layer1=tf.nn.relu(tf.matmul(input_tensor,weights)+biases)    #relu激活函数   在0  和  x的选择
    with tf.variable_scope('layer2'):
        weights=get_weight_variable([LAYER1_NODE,OUTPUT_NODE],regularizer)    #500*10
        biases=tf.get_variable("biases",[OUTPUT_NODE],initializer=tf.constant_initializer(0.0))
        layer2=tf.matmul(layer1,weights)+biases
    return layer2


#n*784  *  784*500  =n*500
#n*500  *  500*10   =n*10
#返回y


2.反向传播训练过程

import os
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import  input_data
import mnist_inference
BATCH_SIZE = 100    #每轮喂入多少张图片
LEARNING_RATE_BASE=0.8  #学习率
LEARNING_RATE_DECAY=0.99  #衰减率
REGULARIZER_RATE=0.0001  #正则化系数
STEPS= 30000 #迭代次数
MOVING_AVERAGE_DECAY=0.99   #滑动平均衰减率
MODEL_SACE_PATH="./model/"  #模型保存路径
MODEL_NAME="mnist_model"    #模型保存文件名

def train(mnist):
    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')
    regularizer = tf.contrib.layers.l2_regularizer(REGULARIZER_RATE)
    y=mnist_inference.inference(x,regularizer)    #得出的预测y

    gloabl_step=tf.Variable(0,trainable=False)    #轮数,不可改变


    variable_averages=tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY,gloabl_step)#定义滑动平均类
    variables_averages_op=variable_averages.apply(tf.trainable_variables())#在实际应用中会使tf.trainable_variables()
                # 自动将所有训练的参数汇总为列表
    #   average_y=mnist_inference.inference(xxxxxxx) 滑动平均,影子值

#交叉熵定义损失函数,loss             交叉熵和softmax一起使用,softmax是y呈概率分布
    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)
    loss=cross_entropy_mean+tf.add_n(tf.get_collection('losses'))
#损失函数=交叉熵损失  +   正则化损失(正则化)


#设置梯度下降的指数衰减学习率
    learning_rate=tf.train.exponential_decay(LEARNING_RATE_BASE,gloabl_step,mnist.train.num_examples/BATCH_SIZE,LEARNING_RATE_DECAY)
#梯度下降算法
    train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss,global_step=gloabl_step)


    with tf.control_dependencies([train_step,variables_averages_op]):#一步完成多个操作
        train_op=tf.no_op(name='train')
    saver=tf.train.Saver()  #保存模型

#生成会话`
    with tf.Session() as sess:
        tf.global_variables_initializer().run()

        #设置断点
        ckpt = tf.train.get_checkpoint_state(MODEL_SACE_PATH)
        if ckpt and ckpt.model_checkpoint_path:
            saver.restore(sess,ckpt.model_checkpoint_path)

        for i in range(STEPS): #导入数据,迭代更新
            xs,ys=mnist.train.next_batch(BATCH_SIZE)  #产生数据
            _,loss_value,step=sess.run([train_op,loss,gloabl_step],feed_dict={x:xs,y_:ys})

            if i%1000 == 0:  #打印,1000次输出loss
                print(variables_averages_op)
                print("After %d training step(s) , loss on training batch is %g"%(step,loss_value))

                saver.save(sess,os.path.join(MODEL_SACE_PATH,MODEL_NAME),global_step=gloabl_step)
def main(argv=None):
    mnist=input_data.read_data_sets("./data/",one_hot=True)
    train(mnist)
if __name__ == '__main__':
    tf.app.run()



3.输出准确率检验

import time
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import  input_data
import mnist_inference
import mnist_train
EVAL_INTERVAL_SECS=10   #10s加载一次正确率

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')
        validata_feed={x:mnist.validation.images,y_:mnist.validation.labels}

        #正确率计算
        y = mnist_inference.inference(x, None)
        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 = variable_averages.variables_to_restore()
        saver = tf.train.Saver(variables_to_restore)

        while True:
            with tf.Session() as sess:   #会话生成
                ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SACE_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]
                    accuracy_score = sess.run(accuracy, feed_dict=validata_feed)
                    print("After %s training step(s) ,validation accuracy=%g" % (global_step, accuracy_score))
                else:
                    return
            time.sleep(EVAL_INTERVAL_SECS)

def main():
    mnist=input_data.read_data_sets("./data/",one_hot=True)
    evaluate(mnist)
if __name__ == '__main__':
    main()


4.识别自己写的数字,注意:写时要把图片填满,然后字体识别度保持高一点

from PIL import Image
import os
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import mnist_inference
import mnist_eval
import mnist_train
import matplotlib.pyplot as plt


def resore_model(testPicArr):
    with tf.Graph().as_default() as tg:  # 重现计算图
        x = tf.placeholder(tf.float32, [None, mnist_inference.INPUT_NODE])
        y = mnist_inference.inference(x, None)  # 输出y
        preValue = tf.argmax(y, 1)  # y的最大值代表种类

        # 下面这一坨到with中都是优化, () 直接得出结果
        variable_averages = tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY)
        variable_to_restore = variable_averages.variables_to_restore()
        saver = tf.train.Saver()
        with tf.Session() as sess:
            ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SACE_PATH)
            ckpt.model_checkpoint_path = ckpt.model_checkpoint_path
            saver.restore(sess, ckpt.model_checkpoint_path)
            #print(ckpt.model_checkpoint_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]
            preValue = sess.run(preValue, feed_dict={x: testPicArr})
            #print(preValue)
            return preValue


def pre_pic(picName):  # 图片预处理。转化为1*784矩阵,作为特征输入
    img = Image.open(picName)  # 打开图片
    reIm = img.resize((28, 28), Image.ANTIALIAS)  # 图片转化为28*28像素
    im_arr = np.array(reIm.convert('L'))  # 转化为矩阵
    threshold = 50
    #print(im_arr)
    for i in range(28):  # 求互补反色   让图片只有黑白色的点
        for j in range(28):
            im_arr[i][j] = 255 - im_arr[i][j]
            if (im_arr[i][j] < threshold):
                im_arr[i][j] = 0
            else:
                im_arr[i][j] = 255
    nm_arr = im_arr.reshape([1, 784])  # 784像素点
    nm_arr = nm_arr.astype(np.float32)
    img_ready = np.multiply(nm_arr, 1.0 / 255.0)
    #print(img_ready)


    #plt.imshow(im_arr)
    #plt.show()
    return img_ready


def application():
    testNum = int(input("input the number of test pictures:"))
    for i in range(testNum):
        testPic = input("the path of test picture:")
        testPicArr = pre_pic(testPic)
        preValue = resore_model(testPicArr)  # 在神经网络中喂入预处理的图片的矩阵
        print("The prediction number is :", preValue)


def main():
    application()


if __name__ == '__main__':
    main()

猜你喜欢

转载自blog.csdn.net/qq_40602790/article/details/83046392
今日推荐