一、数据处理
1、数据加载
from tensorflow.examples.tutorials.mnist import input_data
#number 1 to 10 data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
2、数据处理
(1)定义input的placeholder
(2)定义dropout的placeholde
(3)把xs的形状变成[-1,28,28,1],-1代表先不考虑输入的图片例子多少这个维度,后面的1是channel的数量,图片是黑白,channel是1,如果是RGB图像,那么channel就是3。
#define placeholder for input to network
xs = tf.placeholder(tf.float32,[None,784])#28*28
ys = tf.placeholder(tf.float32,[None,10])
#define dropout的placeholder,解决overfitting
keep_prob = tf.placeholder(tf.float32)
x_image = tf.reshape(xs,[-1,28,28,1])
二、建立卷积层
1、定义weight,bias
定义第一层卷积,先定义本层的Weight,本层我们的卷积核patch(kernal)的大小是5x5,因为黑白图片channel是1所以输入是1,输出是32个featuremap;接着定义bias,它的大小是32个长度,因此我们传入它的shape为[32]
W_conv1 = weight_varible([5,5,1,32])#patch(kernal) 5x5,insize 1,outsize 32
b_conv1 = bias_variable([32])
def weight_varible(shape):
initial = tf.truncated_normal(shape,stddev = 0.1)#产生随机变量 stddev标准偏差
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1,shape=shape)
return tf.Variable(initial)
2、定义第一个卷积层
h_conv1=conv2d(x_image,W_conv1)+b_conv1,同时对h_conv1进行非线性处理(激活函数),这里用的是tf.nn.relu(修正线性单元)来处理。要注意的是,因为采用了SAME的padding方式,输出图片的大小没有变化依然是28x28,只是厚度变厚了,因此现在的输出大小就变成了28x28x32。最后我们再进行pooling的处理就ok啦,经过pooling的处理,输出大小就变为了14x14x32
#conv1 layer
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1)+b_conv1)#output size 28x28x32
def conv2d(x,W):
#strides=[1,x_movement,y_movement,1]
#Must have strides[0]=strides[3]=1
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')
3、第二个卷积层
本层我们的输入就是上一层的输出,本层我们的卷积核patch的大小是5x5,有32个featuremap所以输入就是32,输出呢我们定为64。接着我们就可以定义卷积神经网络的第二个卷积层,这时的输出的大小就是14x14x64。最后也是一个pooling处理,输出大小为7x7x64。
#conv2 layer
W_conv2 = weight_varible([5,5,32,64])#patch(kernal) 5x5,insize 32,outsize 64
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1,W_conv2)+b_conv2)#output size 14x14x64
h_pool2 = max_pool_2x2(h_conv2) #output size 7x7x64
三、建立全链接层
进入全连接层时, 通过tf.reshape()将h_pool2的输出值从一个三维的变为一维的数据, -1表示先不考虑输入图片例子维度, 将上一个输出结果展平.此时weight_variable的shape输入就是第二个卷积层展平了的输出大小: 7x7x64, 后面的输出size我们继续扩大,定为1024。
#func1 layer
W_fc1 = weight_varible([7*7*64,1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2,[-1,7*7*64])#[n_sample,7,7,64] -->[n_sample,7*7*64]
然后将展平后的h_pool2_flat与本层的W_fc1相乘(注意这个时候不是卷积了),可以加一个dropout的处理过拟合问题
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat,W_fc1)+b_fc1)
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)
接下来我们就可以进行最后一层的构建了,输入是1024,最后的输出是10个 (因为mnist数据集就是[0-9]十个类),prediction就是我们最后的预测值,用softmax分类器(多分类,输出是各个类的概率),对输出进行分类。
#func2 layer
W_fc2 = weight_varible([1024,10])
b_fc2 = bias_variable([10])
prediction = tf.nn.softmax(tf.matmul(h_fc1_drop,W_fc2)+b_fc2)
四、选优化方法
利用交叉熵损失函数来定义cost function,用tf.train.AdamOptimizer()作为优化器进最小化cross_entropy。
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys*tf.log(prediction),
reduction_indices=[1]))#loss
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
定义Session,初始化变量
init = tf.global_variables_initializer()
sess=tf.Session()
sess.run(init)
五、训练数据
假定训练1000步,每50步输出一下准确率, 注意sess.run()时记得要用feed_dict给我们的众多 placeholder 喂数据哦.
for i in range(1000):
batch_xs,batch_ys = mnist.train.next_batch(100)
sess.run(train_step,feed_dict={xs:batch_xs,ys:batch_ys,keep_prob: 0.5})
if i%50 == 0:
print(compute_accuracy(
mnist.test.images[:1000], mnist.test.labels[:1000]
))