Tensorflow学习-MNIST识别-两层卷积

在之前的基础上,尝试卷积,效果很好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#导入Tensorflow库
import tensorflow as tf

#导入MNIST数据样例库
from tensorflow.examples.tutorials.mnist import input_data

#导入Tensorboard用于显示训练过程
import tensorboard

#从MNIST数据库中读取数据
mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)

#定义输入输出的维度,使用占位符并定义矩阵格式
x = tf.placeholder(tf.float32,[None,784])
y_ = tf.placeholder(tf.float32,[None,10])

#使用reshape将原始的数据进行转换,使784维向量成为28*28*1的矩阵图片
x_image = tf.reshape(x,[-1,28,28,1])

#试输出转换后的数据形式
x_image
OUT:
<tf.Tensor 'Reshape:0' shape=(?, 28, 28, 1) dtype=float32>

#定义权重层,shape为权重层数据的格式,n为当前层数
def weight_variable(shape,n):
with tf.name_scope('weight_variable_%s' % n):
#通过tf.truncated_normal来初始化权重
#该方法使用2倍的stddev来截断正态分布,选取随机值
initial = tf.truncated_normal(shape,stddev=0.1)
return tf.Variable(initial)

#定义偏置层,shape为偏置的格式,n为当前层数
def bias_variable(shape,n):
with tf.name_scope('bias_variable_%s' % n):
#通过定义常数张量初始化偏置
initial = tf.constant(0.1,shape=shape)
return tf.Variable(initial)

#卷积层,x为输入矩阵,w为卷积的核
def conv2d(x,w,n):
with tf.name_scope('Convolution_layer_%s' % n):
#strides为步长,padding选择SAME
return tf.nn.conv2d(x,w,strides=[1,1,1,1],padding='SAME')

#池化层,x为输入矩阵,n为当前层数
def maxpool_2x2(x,n):
with tf.name_scope('pooling_%s' % n):
#ksize池化窗口大小,
#strides窗口每个维度的滑动步长
return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')

#定义第一层的权重、偏置
W_conv1 = weight_variable([5,5,1,32],1)
b_conv1 = bias_variable([32],1)

#进行第一层的卷积
h_conv1 = tf.nn.relu(conv2d(x_image,W_conv1,1) + b_conv1)

#对第一层卷积的结果进行池化
h_pool1 = maxpool_2x2(h_conv1,1)

#定义第二层的权重、偏置
W_conv2 = weight_variable([5, 5, 32, 64],2)
b_conv2 = bias_variable([64],2).

#进行第二层的卷积
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2,2) + b_conv2)

#对第二层卷积的结果进行池化
h_pool2 = maxpool_2x2(h_conv2,2)

#两次的卷积由于padding,都没有缩小维数,
#但是pooling的时候,每次都缩小了2倍,则最后28/2/2=7,维数为7*7,通道为64
W_fc1 = weight_variable([7 * 7 * 64,1024],'fc1')
b_fc1 = bias_variable([1024],'fc1')

#又将7*7*64的图片格式,转化为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的比例
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1,keep_prob)

#最后全连接层,准备输出
W_fc2 = weight_variable([1024,10],'fc2')
b_fc2 = bias_variable([10],'fc2')

#输出预测层
y_conv = tf.matmul(h_fc1_drop,W_fc2) + b_fc2

#定义交叉熵为损失函数
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_,logits=y_conv))

#定义训练步骤,使用AadmOptimizer最小化损失函数——交叉熵
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

#获得正确样本
correct_prediction = tf.equal(tf.argmax(y_conv, 1),tf.argmax(y_,1))

#取得准确率
accuracy= tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

#初始化Session会话
sess = tf.Session()

#将所有定义的Summary操作进行整合
merged = tf.summary.merge_all()

#保存Summary的图形结构
writer = tf.summary.FileWriter("logofmnist2/",sess.graph)

#初始化所有变量,准备启动Session
sess.run(tf.global_variables_initializer())

#开始训练
#定义训练次数为20000次
for i in range(20000):
#选取100个样本作为一批训练样本
batch = mnist.train.next_batch(100)
#进行训练,定义输入与标签,并定义dropout概率为0.5
sess.run(train_step,feed_dict={x:batch[0],y_:batch[1],keep_prob:0.5})
#每一百次训练输出正确率
if i % 100 == 0:
train_accuracy = accuracy.eval(session=sess,feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0})
print ("step %d, training accuracy %g" % (i,train_accuracy))
#result = sees.run(merged,feed_dict={x:batch[0],y:batch[1]})
#writer.add_summary(result,i)

OUT:
step 0, training accuracy 0.19 step 100, training accuracy 0.92

step 200, training accuracy 0.89 step 300, training accuracy 0.88

step 400, training accuracy 0.94 step 500, training accuracy 0.91

step 600, training accuracy 0.98 step 700, training accuracy 0.95

step 800, training accuracy 0.97 step 900, training accuracy 0.94

step 1000, training accuracy 0.93 step 1100, training accuracy 0.96

step 1200, training accuracy 0.99 step 1300, training accuracy 0.94

step 1400, training accuracy 0.98 step 1500, training accuracy 0.98

step 1600, training accuracy 0.97 step 1700, training accuracy 0.98

step 1800, training accuracy 0.99 step 1900, training accuracy 0.96

step 2000, training accuracy 0.99 step 2100, training accuracy 0.97

step 2200, training accuracy 0.99 step 2300, training accuracy 1

step 2400, training accuracy 1 step 2500, training accuracy 0.99

step 2600, training accuracy 0.97 step 2700, training accuracy 0.98

step 2800, training accuracy 0.98 step 2900, training accuracy 0.98

step 3000, training accuracy 0.99 step 3100, training accuracy 0.98

step 3200, training accuracy 0.99 step 3300, training accuracy 1

step 3400, training accuracy 0.97 step 3500, training accuracy 0.98

step 3600, training accuracy 0.98 step 3700, training accuracy 0.99

step 3800, training accuracy 0.99 step 3900, training accuracy 0.99
0%