1. 程式人生 > >tensorflow 全連線神經網路 MNIST手寫體數字識別

tensorflow 全連線神經網路 MNIST手寫體數字識別

____tz_zs小練習

案例來源《TensorFlow實戰Google深度學習框架》

MNIST手寫體數字識別神經網路模型——版本一

# -*- coding: utf-8 -*-
"""
@author: tz_zs(5_2)

MNIST手寫體數字識別
"""

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

# MNIST 資料集相關的常數
INPUT_NODE = 784  # 輸入層為28*28的畫素
OUTPUT_NODE = 10  # 輸出層0~9有10類

# 配置神經網路的引數
LAYER1_NODE = 500  # 隱藏層節點數

BATCH_SIZE = 100  # batch的大小

LEARNING_RATE_BASE = 0.8  # 基礎的學習率
LEARNING_RATE_DECAY = 0.99  # 學習率的衰減率
REGULARIZATION_RATE = 0.0001  # 正則化項的係數
TRAINING_STEPS = 30000  # 訓練輪數
MOVING_AVERAGE_DECAY = 0.99  # 滑動平均的衰減率


# 定義神經網路的結構
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)
        # 計算輸出層的前向傳播結果(計算損失函式時,會一併進行softmax運輸,在這裡不進行softmax迴歸)
        return tf.matmul(layer1, weights2) + biases2
    else:
        # 需要先使用滑動平均值計算出引數
        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]))

    # 定義計算當前引數下,神經網路前向傳播的結果。
    y = inference(x, None, weights1, biases1, weights2, biases2)

    # 定義儲存訓練輪數的變數
    global_step = tf.Variable(0, trainable=False)

    # 初始化滑動平均物件
    variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)

    # 定義滑動平均的操作
    variable_averages_op = variable_averages.apply(tf.trainable_variables())

    # 定義計算使用了滑動平均之後的前向傳播結果
    average_y = inference(x, variable_averages, weights1, biases1, weights2, biases2)

    # 損失函式
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(y_, 1), logits=y)
    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

    # 學習率
    learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, mnist.train.num_examples / BATCH_SIZE,
                                               LEARNING_RATE_DECAY)

    # 優化演算法
    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)

    # 訓練的操作
    with tf.control_dependencies([train_step, variable_averages_op]):
        train_op = tf.no_op(name='train')

    # 檢驗 準確度
    correct_prediction = tf.equal(tf.argmax(average_y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

    with tf.Session() as sess:
        tf.global_variables_initializer().run()

        # 準備資料
        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):
            # 每1000輪,使用驗證資料測試一次
            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))


# 主程式入口
def main(argv=None):
    mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)
    train(mnist)


if __name__ == '__main__':
    tf.app.run()

執行結果:

After 0 training step(s), validation accuracy using average model is 0.1202 
After 1000 training step(s), validation accuracy using average model is 0.976 
After 2000 training step(s), validation accuracy using average model is 0.9798 
After 3000 training step(s), validation accuracy using average model is 0.9824 
After 4000 training step(s), validation accuracy using average model is 0.9828 
After 5000 training step(s), validation accuracy using average model is 0.9834 
After 6000 training step(s), validation accuracy using average model is 0.983 
After 7000 training step(s), validation accuracy using average model is 0.9836 
After 8000 training step(s), validation accuracy using average model is 0.9838 
After 9000 training step(s), validation accuracy using average model is 0.9826 
After 10000 training step(s), validation accuracy using average model is 0.985 
After 11000 training step(s), validation accuracy using average model is 0.9844 
After 12000 training step(s), validation accuracy using average model is 0.9848 
After 13000 training step(s), validation accuracy using average model is 0.9844 
After 14000 training step(s), validation accuracy using average model is 0.9848 
After 15000 training step(s), validation accuracy using average model is 0.9852 
After 16000 training step(s), validation accuracy using average model is 0.9854 
After 17000 training step(s), validation accuracy using average model is 0.9854 
After 18000 training step(s), validation accuracy using average model is 0.9846 
After 19000 training step(s), validation accuracy using average model is 0.9852 
After 20000 training step(s), validation accuracy using average model is 0.9852 
After 21000 training step(s), validation accuracy using average model is 0.9864 
After 22000 training step(s), validation accuracy using average model is 0.9852 
After 23000 training step(s), validation accuracy using average model is 0.9854 
After 24000 training step(s), validation accuracy using average model is 0.9856 
After 25000 training step(s), validation accuracy using average model is 0.9862 
After 26000 training step(s), validation accuracy using average model is 0.9856 
After 27000 training step(s), validation accuracy using average model is 0.986 
After 28000 training step(s), validation accuracy using average model is 0.986 
After 29000 training step(s), validation accuracy using average model is 0.986 
After 30000 training step(s), test accuracy using average model is 0.9843

MNIST手寫體數字識別神經網路模型——版本二

mnist_inference.py

# -*- coding: utf-8 -*-
"""
@author: tz_zs

MNIST 升級----mnist_inference.py
"""
import tensorflow as tf

# 定義神經網路結構相關的引數
INPUT_NODE = 784
OUTPUT_NODE = 10
LAYER1_NODE = 500


# 正則化損失
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))

    return weights


# 神經網路的前向傳播過程
def inference(input_tensor, regularizer):
    # 第一層
    with tf.variable_scope('layer1'):
        weights = get_weight_variable([INPUT_NODE, LAYER1_NODE], regularizer)
        biases = tf.get_variable("biases", [LAYER1_NODE], initializer=tf.constant_initializer(0.0))

        layer1 = tf.nn.relu(tf.matmul(input_tensor, weights) + biases)

    # 第二層
    with tf.variable_scope('layer2'):
        weights = get_weight_variable([LAYER1_NODE, OUTPUT_NODE], regularizer)
        biases = tf.get_variable("biases", [OUTPUT_NODE], initializer=tf.constant_initializer(0.0))

        layer2 = tf.matmul(layer1, weights) + biases

    return layer2

mnist_train.py

# -*- coding: utf-8 -*-
"""
@author: tz_zs

MNIST 升級----mnist_train.py
"""
import tensorflow as tf
import os
from tensorflow.examples.tutorials.mnist import input_data
# 載入函式
import mnist_inference

# 配置神經網路引數
BATCH_SIZE = 100
LEARNING_RATE_BASE = 0.8
LEARNING_RATE_DECAY = 0.99
REGULARIZATION_RATE = 0.0001
TRAINING_STEPS = 30000
MOVING_AVERAGE_DECAY = 0.99

# 模型儲存路徑和檔名
MODEL_SAVE_PATH = "/path/to/model/"
MODEL_NAME = "model.ckpt"


def train(mnist):
    # 定義輸入輸出的placeholder
    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(REGULARIZATION_RATE)

    # 使用前向傳播
    y = mnist_inference.inference(x, regularizer)

    global_step = tf.Variable(0, trainable=False)

    # 滑動平均
    variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
    variable_averages_op = variable_averages.apply(tf.trainable_variables())

    # 損失函式
    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.arg_max(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,
                                               global_step,
                                               mnist.train.num_examples / BATCH_SIZE,
                                               LEARNING_RATE_DECAY)
    # 優化演算法
    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
    with tf.control_dependencies([train_step, variable_averages_op]):
        train_op = tf.no_op(name="train")

    # 持久化
    saver = tf.train.Saver()
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        for i in range(TRAINING_STEPS):
            xs, ys = mnist.train.next_batch(BATCH_SIZE)
            # 執行
            _, loss_valuue, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y_: ys})

            # 每1000輪儲存一次模型
            if i % 1000 == 0:
                print("After %d training step(s), loss on training batch is %g." % (step, loss_valuue))
                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("/tmp/data", one_hot=True)
    train(mnist)


if __name__ == '__main__':
    tf.app.run()

mnist_eval.py

# -*- coding: utf-8 -*-
"""
@author: tz_zs

測試程式
"""
import time
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

import mnist_inference
import mnist_train

# 每十秒載入一次最新的模型,並在測試資料上測試最新模型的準確率
EVAL_INTERVAL_SECS = 10


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")

        validate_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)
        # print(variables_to_restore)
        # {'layer2/biases/ExponentialMovingAverage': < tf.Variable
        # 'layer2/biases:0'
        # shape = (10,)
        # dtype = float32_ref >, 'layer2/weights/ExponentialMovingAverage': < tf.Variable
        # 'layer2/weights:0'
        # shape = (500, 10)
        # dtype = float32_ref >, 'layer1/biases/ExponentialMovingAverage': < tf.Variable
        # 'layer1/biases:0'
        # shape = (500,)
        # dtype = float32_ref >, 'layer1/weights/ExponentialMovingAverage': < tf.Variable
        # 'layer1/weights:0'
        # shape = (784, 500)
        # dtype = float32_ref >}

        while True:
            with tf.Session() as sess:
                # 找到檔名
                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)
                    # 通過檔名獲得模型儲存時迭代的輪數
                    global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]

                    # 運算出資料
                    accuracy_score = sess.run(accuracy, feed_dict=validate_feed)

                    print("After %s training stpe(s), validation accuracy = %g" % (global_step, accuracy_score))
                else:
                    print("No checkpoint file found")
                    return
                time.sleep(EVAL_INTERVAL_SECS)


def main(argv=None):
    mnist = input_data.read_data_sets("/tmp/data", one_hot=True)
    evaluate(mnist)


if __name__ == '__main__':
    tf.app.run()

·