驗證碼識別(1) -- 1 個字元,1 個 softmax 層,正確率 92%
# create the modeln# ...n# ...nn# forword propnpredict = tf.argmax(y, axis=1)nn# Define loss and optimizerncross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y))ntrain_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)nnwith tf.Session() as sess:n tf.global_variables_initializer().run()nn # Trainn for _ in range(10000):n batch_xs, batch_ys = train_data.next_batch(1000)n sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})nn if _ % 100 == 0:n # Test trained modeln correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))n accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))n r = sess.run(accuracy, feed_dict={x: test_data.images,n y_: test_data.labels})n print step = %s, accuracy = %.2f%% % (_, r * 100)nn a = sess.run(predict, feed_dict={x: test_data.images[-10:]})n print predict: %s % an print expect : %s % np.argmax(test_data.labels[-10:], axis=1)n
運行結果:
從 mnist 的 demo 修改過來的。
訓練的代碼,看 mnist 的文檔就好了,關鍵點相同。
主要的改動點如下:
數據源 -- 生成驗證碼
訓練數據,用 python 的 captcha 庫批量生成。
分 train 和 test 2 個子目錄,test 是 train 的數據量的 20%
https://github.com/JackonYang/captcha-tensorflow/blob/v0.1/gen_capthca.py
# -*- coding:utf-8 -*-nimport osnimport uuidnfrom captcha.image import ImageCaptchannndef one_char(loop=1000, img_dir=images):n image = ImageCaptcha(width=60, height=100)n for _ in range(loop):n if _ % 100 == 0:n print %s looping... % _n for i in range(10):n fn = os.path.join(img_dir, %s_%s.png % (i, uuid.uuid4()))n image.write(str(i), fn)nnnif __name__ == __main__:n one_char(1000, images/one-char/train)n one_char(200, images/one-char/test)n
訓練好的模型,怎麼用?-- Forward Propagation
在 sklearn 等其他 python 包里,
模型訓練 OK 以後,使用時只要調用 model.apply 方法即可。
在 tensorflow 里,則需要修改 model 的最後一層,使用 forward propagation。
訓練的時候,最後一層是在找最小 loss 的 predict。
apply 的時候,選擇概率最高的 predict 即可。
代碼:
# Create the modelnx = tf.placeholder(tf.float32, [None, image_px])nW = tf.Variable(tf.zeros([image_px, y_len]))nb = tf.Variable(tf.zeros([y_len]))ny = tf.matmul(x, W) + bnn# forword propnpredict = tf.argmax(y, axis=1)nn# train the model and apply itnwith tf.Session() as sess:n tf.global_variables_initializer().run()n # train the modeln # ...nn # apply the modeln a = sess.run(predict, feed_dict={x: test_data.images[-10:]})n print predict: %s % an print expect : %s % np.argmax(test_data.labels[-10:], axis=1)n
踩過的坑
最初是在 MacBook Pro 上做。
數據量小的時候,每次預測的正確率都是 10%
一共就 10 個驗證碼,跟隨機蒙的概率完全一樣。
令我懷疑人生,懷疑代碼。
不斷的 code review,不斷的 debug 找 bug。
浪費了 1 天。
然後決定加大數據量看看,
正確率到了 43%,只是,訓練一次 1 個小時。
前 10 分鐘都是正確率為 10% 的階段,什麼都看不出來。
debug 一天,睡了四分之三天。
等的實在是寂寞難耐。
浪費了 2 天。
換了 GPU,
加大數據量,batch_size 翻 10 倍,step 數量翻 10 倍。
1 分鐘出結果,正確率 92%
多次 debug 之後,對 tensorflow 的執行過程熟悉了太多。
用時,30 分鐘。
好的煉丹爐,節省太多生命。
推薦閱讀:
TAG:验证码识别 | 深度学习DeepLearning | TensorFlow |