驗證碼識別(1) -- 1 個字元,1 個 softmax 層,正確率 92%

代碼:JackonYang/captcha-tensorflow V0.1

# 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 |