关于卷积神经网络的原理, 网上资料比较多, 这里不做介绍。
我基于tensorflow搭建了一个含有三层卷积层(包含池化层和dropout)和2层全连接层的卷积神经网络, 使用了L2正则化和AdamOptimizer。
结构较为简单,直接看代码就可以了, 非常适合新手上路。
如果使用cpu进行模型训练(比如我), 训练速度比较慢, 在我的电脑上大概需要20分钟左右,在测试集上进行Validation时还有可能会出现内存超出的问题, 可以把测试机分成小的batch进行验证最后计算平均值也可以直接忽略。
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import os
mnist = input_data.read_data_sets(".", one_hot=True)
# 定义神经网络参数
learning_rate = 0.0055
training_epochs = 10
batch_size = 100
display_step = 1
n_input = 784
n_classes = 10
drop_out = 0.95 # drop_out需设置的比较接近1
regular_rate = 0.001
x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_classes])
keep_prob = tf.placeholder(tf.float32)
# 定义卷积层、池化层和LRN层, 但是并没有使用LRN层, 因为增加了训练时间的同时并没有带来明显的准确率提高
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
def norm(l_input, lsize=4):
return tf.nn.lrn(l_input, lsize, bias=1.0, alpha=0.001/9.0, beta=0.75)
# 搭建神经网络
def multilayer_preceptron(x, weights1, biases1, _dropout):
x_image = tf.reshape(x, [-1, 28, 28, 1])
# 第一层神经网络
h_conv1 = tf.nn.relu(conv2d(x_image, weights1['conv1'])+biases1['conv_b1'])
h_pool1 = max_pool_2x2(h_conv1)
conv1 = tf.nn.dropout(h_pool1, keep_prob=_dropout)
# 第二层神经网络
h_conv2 = tf.nn.relu(conv2d(conv1, weights1['conv2']) + biases1['conv_b2'])
h_pool2 = max_pool_2x2(h_conv2)
conv2 = tf.nn.dropout(h_pool2, keep_prob=_dropout)
# 第三层神经网络
h_conv3 = tf.nn.relu(conv2d(conv2, weights1['conv3']) + biases1['conv_b3'])
conv3 = tf.nn.dropout(h_conv3, keep_prob=_dropout)
# 将第三层神经网络的输出“压平”
h_conv3_flat = tf.reshape(conv3, [-1, 7*7*128])
# 后接两个全连接层
h_fc1 = tf.nn.relu(tf.matmul(h_conv3_flat, weights1['fc1']) + biases1['fc1_b'])
out_layer = tf.matmul(h_fc1, weights1['out']) + biases1['out_b']
return out_layer
# 定义权重
weights = {
'conv1':tf.Variable(tf.random_normal([6, 6, 1, 32])),
'conv2':tf.Variable(tf.random_normal([5, 5, 32, 64])),
'conv3':tf.Variable(tf.random_normal([3, 3, 64, 128])),
'fc1':tf.Variable(tf.random_normal([7*7*128, 256])),
'fc2':tf.Variable(tf.random_normal([256, 128])),
'out':tf.Variable(tf.random_normal([256, n_classes]))
}
# 定义偏置
biases = {
'conv_b1':tf.Variable(tf.constant(0.1, shape=[32])),
'conv_b2':tf.Variable(tf.constant(0.1, shape=[64])),
'conv_b3':tf.Variable(tf.constant(0.1, shape=[128])),
'fc1_b':tf.Variable(tf.constant(0.1, shape=[256])),
'fc2_b':tf.Variable(tf.constant(0.1, shape=[256])),
'out_b':tf.Variable(tf.constant(0.1, shape=[n_classes]))
}
# 加入正则化
pred = multilayer_preceptron(x, weights, biases, keep_prob)
reg = tf.contrib.layers.l2_regularizer(regular_rate)
regular = reg(weights['conv1']) + reg(weights['conv2']) + reg(weights['conv3']) + reg(weights['fc1']) + reg(weights['out'])
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y)) + regular
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
initializer = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(initializer) # 参数初始化
for epoch in range(training_epochs):
avg_cost = 0
total_batch = int(mnist.train.num_examples/batch_size) # 共需跑多少个batch
# Loop over all batches
for i in range(total_batch):
learning_rate *= 0.99 # 每个epoch衰减一次learning_rate
batch_x, batch_y = mnist.train.next_batch(batch_size)
_, c = sess.run([optimizer, cost], feed_dict={x: batch_x, y: batch_y, keep_prob: drop_out})
avg_cost += c/total_batch
# 每个epoch显示一遍avg_cost
if epoch % display_step == 0:
print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(avg_cost))
if avg_cost < 100:
break
print("Optimization Finished!")
correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
# Calculate accuracy
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print("Accuracy:", accuracy.eval({x:mnist.test.images, y: mnist.test.labels, keep_prob: 1.}))
运行结果:
Epoch: 0001 cost= 23365.755206854
Epoch: 0002 cost= 2148.654016113
Epoch: 0003 cost= 1453.050265891
Epoch: 0004 cost= 1176.044130083
Epoch: 0005 cost= 1023.660095437
Epoch: 0006 cost= 960.693018355
Epoch: 0007 cost= 898.075058927
Epoch: 0008 cost= 858.702115479
Epoch: 0009 cost= 818.889318959
Epoch: 0010 cost= 792.803656450
Optimization Finished!
2019-03-07 19:00:28.302878: W tensorflow/core/framework/allocator.cc:122] Allocation of 1003520000 exceeds 10% of system memory.
Accuracy: 0.9826