15.6 示例:在TensorFlow下识别验证码(三)

完整演示代码请见本书GitHub上的15-3.py

1.数据清洗与特征提取

我们依然使用MNIST数据集合和TensorFlow的DNN(如图15-12所示),同样使用one-hot编码处理标记数据。

图15-12 3层DNN示意图

2.训练

我们使用DNN模型进行计算,使用placeholder函数设置占位符,用于定义整个数据流的输入和输出。在这个例子中x和_y都是这种情况,其中,x对应整个系统输入,是一个维度为784的向量集合,且长度不限制;_y是整个系统的输出,对应一个维度为10的向量集合,两者的特征数据类型都是浮点型;另外,需要定义drop_out的比例keep_prob,同样也是浮点型:


x = tf.placeholder("float", [None, 784])
y_ = tf.placeholder("float", [None,10])
keep_prob=tf.placeholder(tf.float32)

定义整个系统中的变量,其中有3个隐藏层:


in_units=784
out_units=10
h1_units=300
h2_units=200
h3_units=100
W1=tf.Variable(tf.truncated_normal([in_units,h1_units],stddev=0.1))
b1=tf.Variable(tf.zeros([h1_units]))
W2=tf.Variable(tf.zeros([h1_units,h2_units]))
b2=tf.Variable(tf.zeros([h2_units]))
W3=tf.Variable(tf.zeros([h2_units,h3_units]))
b3=tf.Variable(tf.zeros([h3_units]))
W4=tf.Variable(tf.zeros([h3_units,out_units]))
b4=tf.Variable(tf.zeros([out_units]))

定义整个系统的操作函数,其中隐藏层有3层,使用relu函数生成:


hidden1=tf.nn.relu(tf.matmul(x,W1)+b1)
hidden2=tf.nn.relu(tf.matmul(hidden1,W2)+b2)
hidden3=tf.nn.relu(tf.matmul(hidden2,W3)+b3)
hidden_drop=tf.nn.dropout(hidden3,keep_prob)
y = tf.nn.softmax(tf.matmul(hidden_drop,W4) + b4)

定义衰减函数,这里的衰减函数使用交叉熵来衡量,通过Adagrad自适应调节,学习速率为0.3:


cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y),reduction_indices=[1]))
train_step = tf.train.AdagradOptimizer(0.3).minimize(cross_entropy)

初始化全部变量并定义会话,在TensorFlow中每个会话都是独立的,互不干扰:


init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

我们定义每次训练的数据子集的个数:


batch_size=100

每次我们都顺序取出100个数据用于训练,便于梯度下降算法快速收敛,整个训练的次数取决于整个数据集合的长度以及每次训练的数据个数,其中keep_prob比例为75%:


for i in range(int(len(x_training_data)/batch_size)):
    batch_xs=x_training_data[(i*batch_size):((i+1)*batch_size)]
    batch_ys=y_training_data[(i*batch_size):((i+1)*batch_size)]
    sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys,keep_prob:0.75})

3.验证

TensorFlow的数据验证非常简单,使用自带的API即可:


correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(sess.run(accuracy, feed_dict={x: x1, y_: y1,keep_prob:1.0}))

运行结果如下,准确率约为93%,可见并非深度学习就一定效果好,当数据量不大时,SVM的效果很有可能优于深度学习。


can't determine number of CPU cores: assuming 4
I tensorflow/core/common_runtime/local_device.cc:25] Local device intra op parallelism threads: 4
can't determine number of CPU cores: assuming 4
I tensorflow/core/common_runtime/local_session.cc:45] Local session inter op parallelism threads: 4
0.9361