使用 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