TensorFlow-原生写法之CNN实现手写数字识别

TensorFlow四种写法之一:原生写法

代码:

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/8/23 16:49
# @Author : Seven
# @Site :
# @File : CNN-native.py
# @Software: PyCharm

# 0.导入环境

from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

# 1.数据准备

# 使用tensorflow自带的工具加载MNIST手写数字集合
mnist = input_data.read_data_sets('data', one_hot=True)
# 查看数据的维度和target的维度
print(mnist.train.images.shape)
print(mnist.train.labels.shape)

# 2.准备好palceholder
x = tf.placeholder(tf.float32, [None, 784])
y = tf.placeholder(tf.float32, [None, 10])
learnRate = tf.placeholder(tf.float32)

# 3.构建网络计算图结构

# 把输入数据reshape--28x28=784, 单通道, -1表示None
with tf.name_scope('reshape'):
x_image = tf.reshape(x, [-1, 28, 28, 1])

# 构建第一层卷积计算层--将一个灰度图像映射到32个feature maps, 卷积核为5x5
with tf.name_scope('conv1'):
shape = [5, 5, 1, 32]
W_conv1 = tf.Variable(tf.truncated_normal(shape=shape, stddev=0.1),
collections=[tf.GraphKeys.GLOBAL_VARIABLES, 'WEIGHTS'])

shape = [32]
b_conv1 = tf.Variable(tf.constant(0.1, shape=shape))

net_conv1 = tf.nn.conv2d(x_image, W_conv1, strides=[1, 1, 1, 1],
padding='SAME') + b_conv1

out_conv1 = tf.nn.relu(net_conv1)

# 构建池化层--采用最大池化
with tf.name_scope('pool1'):
h_pool1 = tf.nn.max_pool(out_conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],
padding='VALID')

# 构建第二层卷积计算层--maps 32 feature maps to 64.
with tf.name_scope('conv2'):
shape = [5, 5, 32, 64]
W_conv2 = tf.Variable(tf.truncated_normal(shape=shape, stddev=0.1),
collections=[tf.GraphKeys.GLOBAL_VARIABLES, 'WEIGHTS'])

shape = [64]
b_conv2 = tf.Variable(tf.constant(0.1, shape=shape))

net_conv2 = tf.nn.conv2d(h_pool1, W_conv2, strides=[1, 1, 1, 1],
padding='SAME') + b_conv2

out_conv2 = tf.nn.relu(net_conv2)


# 构建第二层池化层--采用最大池化
with tf.name_scope('pool2'):
h_pool2 = tf.nn.max_pool(out_conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1],
padding='VALID')

# 构建全连接层--经过的两层的下采样(池化),28x28x1的图像-->7x7x64,然后映射到1024个特征
with tf.name_scope('fc1'):
shape = [7*7*64, 1024]
W_fc1 = tf.Variable(tf.truncated_normal(shape=shape, stddev=0.1),
collections=[tf.GraphKeys.GLOBAL_VARIABLES, 'WEIGHTS'])

shape = [1024]
b_fc1 = tf.Variable(tf.constant(0.1, shape=shape))

shape = [-1, 7*7*64]
h_pool2_flat = tf.reshape(h_pool2, shape)

out_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

# Dropout--防止过拟合
with tf.name_scope('dropout'):
keep_prob = tf.placeholder(tf.float32)
out_fc1_drop = tf.nn.dropout(out_fc1, keep_prob=keep_prob)


# 构建第二层全连接层--将1024个特性映射到10个类,每个类对应一个数字
with tf.name_scope('fc2'):
shape = [1024, 10]
W_fc2 = tf.Variable(tf.truncated_normal(shape=shape, stddev=0.1),
collections=[tf.GraphKeys.GLOBAL_VARIABLES, 'WEIGHTS'])

shape = [10]
b_fc2 = tf.Variable(tf.constant(0.1, shape=shape))

out = tf.matmul(out_fc1_drop, W_fc2) + b_fc2


# 4.计算损失值并初始化optimizer
print(y.shape, out.shape)
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=out))

l2_loss = tf.add_n([tf.nn.l2_loss(w) for w in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)])

total_loss = cross_entropy + 7e-5*l2_loss

train_step = tf.train.AdamOptimizer(learnRate).minimize(total_loss)
# 5.初始化变量
init = tf.global_variables_initializer()

print("FUNCTION READY!!")
# 6.在会话中执行网络定义的运算
with tf.Session() as sess:
sess.run(init)

for step in range(3000):
batch_xs, batch_ys = mnist.train.next_batch(100)
lr = 0.01

_, loss, l2_loss_value, total_loss_value = sess.run(
[train_step, cross_entropy, l2_loss, total_loss],
feed_dict={x: batch_xs, y: batch_ys, learnRate: lr, keep_prob: 0.5})

if (step + 1) % 100 == 0:
print("step %d, entropy loss: %f, l2_loss: %f, total loss: %f" %
(step + 1, loss, l2_loss_value, total_loss_value))

# 验证训练的模型
correct_prediction = tf.equal(tf.argmax(out, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print("Train accuracy:", sess.run(accuracy, feed_dict={x: batch_xs, y: batch_ys, keep_prob: 0.5}))

if (step + 1) % 1000 == 0:
print("Text accuracy:", sess.run(accuracy, feed_dict={x: batch_xs, y: batch_ys, keep_prob: 0.5}))

转载请注明:Seven的博客

本文标题:TensorFlow-原生写法之CNN实现手写数字识别

文章作者:Seven

发布时间:2018年08月27日 - 00:00:00

最后更新:2018年12月11日 - 22:09:28

原始链接:http://yoursite.com/2018/08/27/2018-08-27-TensorFlow-native/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%