本帖最后由 regan 于 2018-4-12 09:44 编辑
1.下载数据
wget http://tensorflow-1253902462.cosgz.myqcloud.com/mnist_cnn/t10k-images-idx3-ubyte.gz
wget http://tensorflow-1253902462.cosgz.myqcloud.com/mnist_cnn/t10k-labels-idx1-ubyte.gz
wget http://tensorflow-1253902462.cosgz.myqcloud.com/mnist_cnn/train-images-idx3-ubyte.gz
wget http://tensorflow-1253902462.cosgz.myqcloud.com/mnist_cnn/train-labels-idx1-ubyte.gz
2.引入必要的库
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
3.定义输入数据并预处理数据,得到训练图片和标签,及测试图片及标签
mnist = input_data.read_data_sets('./',one_hot=True)
trX , trY,teX,teY = mnist.train.images,mnist.train.labels,mnist.test.images,mnist.test.labels
上面图像的矩阵表现形式,现在需要把这个矩阵变换成(-1,28,28,1)的形状,-1表示不考虑图片的数量,28*28分别表示图片的长度和宽度,1表示颜色通道数量,黑白图片的颜色通道为1,RGB为3.
trX = trX.reshape(-1,28,28,1)
teX = teX.reshape(-1,28,28,1)
4.定义placeholder变量
X = tf.placeholder(tf.float32,[None,28,28,1])
Y = tf.placeholder(tf.float32,[None,10])
5.定义网络结构与初始化网络权重
三个卷积层,3个池化层,1个全连接层,1个输出层。定义一个初始化权重的函数
def init_weights(shape):
return tf.Variable(tf.random_normal(shape,stddev=0.01))
接下来初始化权重,定义卷积核大小为3*3【一般卷积和和最后的输出维度之间的关系为:(int_weight+2*padding-core_weight)/stride步长+1】
对于tensorflow由于padding有两种选择,所以有如下的算法:
卷积核的stride定义为【1,1,1,1】,池化的stride定义为[1,2,2,1]
下面定义卷积核,大小为3*3,输入维度为1对应输入时的厚度因为是单颜色通道,所以是1,输出维度为32表示有32个patch,卷积之后就是32个厚度的了。w4中的128*4*4是什么意思呢?由上面的公式,第一次卷积之后的matrix大小为【28 / 1】接着是池化【28 / 2 = 14】;第二次卷积matrix大小为【14/1=14】接着池化【14/2=7】,接着第三次卷积matrix大小为【 7 /1 = 7】接着池化【7/2 = 4】。一共128个patch且每个patch大小为4*4。
w = init_weights([3,3,1,32])
w2 = init_weights([3,3,32,64])
w3 = init_weights([3,3,64,128])
w4 = init_weights([128*4*4,625])
w_o = init_weights([625,10])
6.接下来定义模型函数
def model(X,w,w2,w3,w4,w_o,p_keep_conv,p_keep_hidden):
l1a = tf.nn.relu(tf.nn.conv2d(X,w,strides=[1,1,1,1],padding='SAME'))
l1p = tf.nn.max_pool(l1a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l1 = tf.nn.dropout(l1p,p_keep_conv)
l2a = tf.nn.relu(tf.nn.conv2d(l1,w2,strides=[1,1,1,1],padding='SAME'))
l2p = tf.nn.max_pool(l2a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l2 = tf.nn.dropout(l2p,p_keep_conv)
l3a = tf.nn.relu(tf.nn.conv2d(l2,w3,strides=[1,1,1,1],padding='SAME'))
l3p = tf.nn.max_pool(l3a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l3 = tf.reshape(l3p,[-1,w4.get_shape().as_list()[0]])
l3 = tf.nn.dropout(l3,p_keep_conv)
l4 = tf.nn.relu(tf.matmul(l3,w4))
l4 = tf.nn.dropout(l4,p_keep_hidden)
out = tf.matmul(l4,w_o)
return out
7.定义占位符
p_keep_conv = tf.placeholder('float')
p_keep_hidden = tf.placeholder('float')
out = model(X,w,w2,w3,w4,w_o,p_keep_conv,p_keep_hidden)
8.定义损失值和优化器。采用softmax_cross_entropy_with_logits来比较预测值和真实值之间的差异,这些差异最后做均值处理。优化器采用RMSProp算法实现的RMSPropOptimizer,制定学习率为0.001,学习率的衰减值为0.9,并使损失沿着最小的方向迭代。
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=out,labels=Y))
train_op = tf.train.RMSPropOptimizer(0.001,0.9).minimize(cost)
predict_op = tf.argmax(out,1)
8.训练和评估模型
定义批次大小为128
batch_size = 128
在session中启动图
with tf.Session() as sess:
tf.global_variables_initializer().run()
for i in range(500):
train_batch = zip(range(0,len(trX),batch_size),range(batch_size,len(trX)+1,batch_size))
for start,end in train_batch:
sess.run(train_op,feed_dict={X:trX[start:end],Y:trY[start:end],p_keep_conv:0.8,p_keep_hidden:0.5})
test = np.arange(len(trX))
np.random.shuffle(test)
test_indices = test[0:batch_size]
print(i,np.mean(np.argmax(teY[test_indices],axis=1)==sess.run(predict_op,feed_dict={X:teX[test_indices],p_keep_conv:1.0,p_keep_hidden:1.0})))
运行结果如下:
可以看到卷积神经网络预测的准确率确实挺高的。
完整代码如下:
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('./',one_hot=True)
#print(dir(mnist))
trX , trY,teX,teY = mnist.train.images,mnist.train.labels,mnist.test.images,mnist.test.labels
trX = trX.reshape(-1,28,28,1)
teX = teX.reshape(-1,28,28,1)
X = tf.placeholder(tf.float32,[None,28,28,1])
Y = tf.placeholder(tf.float32,[None,10])
def init_weights(shape):
return tf.Variable(tf.random_normal(shape,stddev=0.01))
w = init_weights([3,3,1,32])
w2 = init_weights([3,3,32,64])
w3 = init_weights([3,3,64,128])
w4 = init_weights([128*4*4,625])
w_o = init_weights([625,10])
def model(X,w,w2,w3,w4,w_o,p_keep_conv,p_keep_hidden):
l1a = tf.nn.relu(tf.nn.conv2d(X,w,strides=[1,1,1,1],padding='SAME'))
l1p = tf.nn.max_pool(l1a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l1 = tf.nn.dropout(l1p,p_keep_conv)
l2a = tf.nn.relu(tf.nn.conv2d(l1,w2,strides=[1,1,1,1],padding='SAME'))
l2p = tf.nn.max_pool(l2a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l2 = tf.nn.dropout(l2p,p_keep_conv)
l3a = tf.nn.relu(tf.nn.conv2d(l2,w3,strides=[1,1,1,1],padding='SAME'))
l3p = tf.nn.max_pool(l3a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l3 = tf.reshape(l3p,[-1,w4.get_shape().as_list()[0]])
l3 = tf.nn.dropout(l3,p_keep_conv)
l4 = tf.nn.relu(tf.matmul(l3,w4))
l4 = tf.nn.dropout(l4,p_keep_hidden)
out = tf.matmul(l4,w_o)
return out
p_keep_conv = tf.placeholder('float')
p_keep_hidden = tf.placeholder('float')
out = model(X,w,w2,w3,w4,w_o,p_keep_conv,p_keep_hidden)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=out,labels=Y))
train_op = tf.train.RMSPropOptimizer(0.001,0.9).minimize(cost)
predict_op = tf.argmax(out,1)
batch_size = 128
with tf.Session() as sess:
tf.global_variables_initializer().run()
for i in range(100):
train_batch = zip(range(0,len(trX),batch_size),range(batch_size,len(trX)+1,batch_size))
for start,end in train_batch:
sess.run(train_op,feed_dict={X:trX[start:end],Y:trY[start:end],p_keep_conv:0.8,p_keep_hidden:0.5})
test = np.arange(len(teX))
np.random.shuffle(test)
test_indices = test[0:batch_size]
print(i,np.mean(np.argmax(teY[test_indices],axis=1)==sess.run(predict_op,feed_dict={X:teX[test_indices],p_keep_conv:1.0,p_keep_hidden:1.0})))
现在的准确率就很高了,能达到99.x%.
|