1 理论
卷积神经网络(CNN)的理论内容请参考:卷积神经网络概念与原理
2 CNN网络结构
利用CNN进行MNist数字识别,两层卷积层,两层池化层
1层卷积层:Size(5,5),Stride(1), 32feature Map 激活函数为RELU
1层池化层:Size(2,2),最大池化
2层卷积层:Size(5,5),Stride(1), 64feature Map 激活函数为RELU
2层池化层:Size(2,2),最大池化
1全连接层:1024特征
1层卷积层:Size(5,5),Stride(1), 32feature Map 激活函数为RELU
1层池化层:Size(2,2),最大池化
2层卷积层:Size(5,5),Stride(1), 64feature Map 激活函数为RELU
2层池化层:Size(2,2),最大池化
1全连接层:1024特征
2全连接层:10个输出(softmax分类器)
3 代码实现
import tensorflow.examples.tutorials.mnist.input_data as inputData
import tensorflow as tf
mnist=inputData.read_data_sets('MNIST_data',one_hot=True)
def compute_accuracy(t_xs,t_ys):
global y
prediction=tf.nn.softmax(y)
#sess.run(prediction,feed_dict={xs:t_xs,keep_pro:1})
correct_prdiction=tf.equal(tf.argmax(prediction,1),tf.argmax(t_ys,1))
accuracy=tf.reduce_mean(tf.cast(correct_prdiction,tf.float32))
result=sess.run(accuracy,feed_dict={xs:t_xs,ys:t_ys,keep_pro:1})
return result
#定义weight变量
def weight_Variables(shape):
initial=tf.truncated_normal(shape,stddev=0.1)
return tf.Variable(initial)
#定义bias变量
def bias_Variable(shape):
initial=tf.constant(0.1,shape=shape)
return tf.Variable(initial)
#卷积函数
def cov2d(x,W):
# stride [1, x_movement, y_movement, 1]
# 必有 strides[0] = strides[3] = 1
return tf.nn.conv2d(x,W,strides=[1,1,1,1],padding='SAME')
#定义池化层
def max_pool_2X2(x):
#Size(2,2),最大池化
return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
#1 define the place holder for the train data
xs=tf.placeholder(tf.float32,[None,784])#28*28
ys=tf.placeholder(tf.float32,[None,10])#labels
keep_pro=tf.placeholder(tf.float32)
x_image=tf.reshape(xs,[-1,28,28,1])#1means黑白
print(x_image.shape) #[nsamples,28,28]
#2 ===Cov1 layer====
W_cov1=weight_Variables([5,5,1,32]) #Size(5,5),Stride(1), 32feature Map
b_cov1=bias_Variable([32])
#利用Relu激励函数构建第一个卷积层
h_conv1=tf.nn.relu(cov2d(x_image,W_cov1)+b_cov1)
#第1层池化,池化后Size[14,14]
h_pool1=max_pool_2X2(h_conv1)
#3 ===Cov2 layer====
W_cov2=weight_Variables([5,5,32,64]) #Size(5,5),Stride(1), 64feature Map
b_cov2=bias_Variable([64])
#利用Relu激励函数构建第2个卷积层
h_conv1=tf.nn.relu(cov2d(h_pool1, W_cov2)+b_cov2)
#第2层池化,池化后Size[7,7]
h_pool2=max_pool_2X2(h_conv1)
#4 ===全连接层1(fully connected layer)====
W_fc1=weight_Variables([7*7*64,1024]) #1024特征
b_fc1=bias_Variable([1024])
#将h_pool2变平,即[nsamples,7,7,64]->[nsamples,7*7*64]
h_pool2_flat=tf.reshape(h_pool2,[-1,7*7*64])
h_fc1=tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1)
#dropout,增强模型的泛化能力
h_fc1_drop=tf.nn.dropout(h_fc1,keep_pro)
#5 ===全连接层2(fully connected layer)====
W_fc2=weight_Variables([1024,10]) #10个类别
b_fc2=bias_Variable([10])
#分类结果
y=tf.matmul(h_fc1_drop,W_fc2)+b_fc2
#6 loss and optimizer
loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=ys,logits=y))
optimizer=tf.train.AdamOptimizer(1e-4).minimize(loss)
#7 启动会话
sess=tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
#8 training and test
for i in range(1000):
# 100 data points are randomly selected from the training data set
batch_x, batch_y=mnist.train.next_batch(100)
#training
sess.run(optimizer,feed_dict={xs:batch_x, ys:batch_y,keep_pro:0.5})
if i%50==0:
print(compute_accuracy(mnist.test.images, mnist.test.labels))
4 输出结果
0.0947 0.8033 0.8809 0.9039 0.9223 0.9276 0.941 0.9473 0.9492 0.9496 0.9556
0.9574 0.9586 0.9622 0.965 0.9654 0.9668 0.9679 0.9709 0.9689
0.9574 0.9586 0.9622 0.965 0.9654 0.9668 0.9679 0.9709 0.9689
可以看出在前几次训练时,测试精度大幅提高,最高达到97.09%,而也不是训练的次数越多越好,相比于之前只用softmax分类器进行识别,测试精度提高了约10%。