tensorflow 实现 LeNet 用于手写数字的识别

介绍

使用 tensorflow 实现 LeNet-5 网络,用于手写数字集的识别。

代码

'''
Created on 2018年4月27日

@author: wangs0622
'''

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
from tensorflow.contrib.layers import flatten

filepath = r"G:\python\datasets\mnist"

mnist = input_data.read_data_sets(filepath, reshape=False)

x_train, y_train = mnist.train.images, mnist.train.labels
x_validation, y_validation = mnist.validation.images, mnist.validation.labels
x_test, y_test = mnist.test.images, mnist.test.labels

assert(len(x_train) == len(y_train))
assert(len(x_validation) == len(y_validation))
assert(len(x_test) == len(y_test))

print("Image shape = {}".format(x_train[0].shape))
print("Training set size = {}".format(len(x_train)))
print("Validation set size = {}".format(len(x_validation)))
print("Test set size = {}".format(len(x_test)))


x_train = np.pad(x_train, [(0,0),(2,2),(2,2),(0,0)], "constant")
x_validation = np.pad(x_validation, [(0,0),(2,2),(2,2),(0,0)], "constant")
x_test = np.pad(x_test, [(0,0),(2,2),(2,2),(0,0)], "constant")

print("updated size of train images = {}".format(x_train[0].shape))
print("update size of validation images = {}".format(x_validation[0].shape))
print("update size of test images = {}".format(x_test[0].shape))

# shuffle the training data 即对训练数据乱排序

from sklearn.utils import shuffle

x_train, y_train = shuffle(x_train, y_train)

EPOCHS = 10
BATCH_SIZE = 128

# define the LeNet-5 neural network architecture

def LeNet(x):
    mu = 0
    sigma = 0.1
    # 卷积层定义
    conv1_w = tf.Variable(tf.truncated_normal(shape=[5,5,1,6], mean=mu, stddev=sigma))
    conv1_b = tf.Variable(tf.zeros(6))
    conv1 = tf.nn.conv2d(x, conv1_w, strides=[1,1,1,1], padding="VALID") + conv1_b
    # relu 激活层
    conv1 = tf.nn.relu(conv1)
    # pooling 层
    pool_1 = tf.nn.max_pool(conv1, ksize=[1,2,2,1],strides=[1,2,2,1], padding="VALID")

    # 定义第二层卷积
    conv2_w = tf.Variable(tf.truncated_normal(shape=[5,5,6,16], mean=mu, stddev=sigma))
    conv2_b = tf.Variable(tf.zeros(16))
    conv2 = tf.nn.conv2d(pool_1, conv2_w, strides=[1,1,1,1], padding="VALID") + conv2_b

    conv2 = tf.nn.relu(conv2)
    pool_2 = tf.nn.max_pool(conv2, ksize=[1,2,2,1],strides=[1,2,2,1], padding="VALID")
    #print("pool_2 shape : ", pool_2.shape)
    fc1 = flatten(pool_2)
    #print("fc1 shape: ", fc1.shape)
    # 建立全链接层 第一层
    fc1_w = tf.Variable(tf.truncated_normal(shape=(400,120), mean=mu, stddev=sigma))
    fc1_b = tf.Variable(tf.zeros(120))

    fc1 = tf.matmul(fc1, fc1_w)+fc1_b
    fc1 = tf.nn.relu(fc1)
    #全链接层第二层
    fc2_w = tf.Variable(tf.truncated_normal(shape=(120,84), mean=mu, stddev=sigma))
    fc2_b = tf.Variable(tf.zeros(84))
    fc2 = tf.matmul(fc1, fc2_w) + fc2_b
    fc2 = tf.nn.relu(fc2)
    #第三层 输出层
    fc3_w = tf.Variable(tf.truncated_normal(shape=(84,10), mean=mu, stddev=sigma))
    fc3_b = tf.Variable(tf.zeros(10))
    logits = tf.matmul(fc2, fc3_w) + fc3_b
    return logits

x = tf.placeholder(tf.float32, shape=(None, 32, 32, 1))
y = tf.placeholder(tf.int32, shape=(None))
one_hot_y = tf.one_hot(y, 10)

rate = 0.001
logits = LeNet(x)
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=one_hot_y, logits=logits)

loss_operation = tf.reduce_mean(cross_entropy)
optimizer = tf.train.AdamOptimizer(learning_rate=rate)
training_operation = optimizer.minimize(loss_operation)

correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(one_hot_y, 1))
accuracy_operation = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
saver = tf.train.Saver()

def evaluate(x_data, y_data):
    num_examples = len(x_data)
    total_accuracy = 0
    sess = tf.get_default_session()
    for offset in range(0, num_examples, BATCH_SIZE):
        batch_x, batch_y = x_data[offset: offset+BATCH_SIZE], y_data[offset: offset+BATCH_SIZE]
        accuracy = sess.run(accuracy_operation, feed_dict={x: batch_x, y: batch_y})
        total_accuracy = total_accuracy + (accuracy*len(batch_x))
    return total_accuracy/num_examples

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    num_examples = len(x_train)
    print("-------------------------")
    print("-------start train-------")
    for i in range(EPOCHS):
        x_train, y_train = shuffle(x_train, y_train)
        for offset in range(0, num_examples, BATCH_SIZE):
            end = offset + BATCH_SIZE
            batch_x, batch_y = x_train[offset:end], y_train[offset:end]
            sess.run(training_operation, feed_dict={x:batch_x, y:batch_y})
        validation_accuracy = evaluate(x_validation, y_validation)
        print("EPOCHS {}....".format(i+1))
        print("Validation Accuracy = {:.3f}".format(validation_accuracy))
        saver.save(sess, ".\\")
    print("Model saved")

代码运行结果

Extracting G:\python\datasets\mnist\train-images-idx3-ubyte.gz
Extracting G:\python\datasets\mnist\train-labels-idx1-ubyte.gz
Extracting G:\python\datasets\mnist\t10k-images-idx3-ubyte.gz
Extracting G:\python\datasets\mnist\t10k-labels-idx1-ubyte.gz
Image shape = (28, 28, 1)
Training set size = 55000
Validation set size = 5000
Test set size = 10000
updated size of train images = (32, 32, 1)
update size of validation images = (32, 32, 1)
update size of test images = (32, 32, 1)
-------------------------
-------start train-------
EPOCHS 1....
Validation Accuracy = 0.971
EPOCHS 2....
Validation Accuracy = 0.977
EPOCHS 3....
Validation Accuracy = 0.985
EPOCHS 4....
Validation Accuracy = 0.983
EPOCHS 5....
Validation Accuracy = 0.989
EPOCHS 6....
Validation Accuracy = 0.986
EPOCHS 7....
Validation Accuracy = 0.987
EPOCHS 8....
Validation Accuracy = 0.989
EPOCHS 9....
Validation Accuracy = 0.988
EPOCHS 10....
Validation Accuracy = 0.989
Model saved

后记

更多的内容,欢迎点击我的个人博客查看 www.wangs0622.com

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