1. 程式人生 > >tensorflow實戰:端到端簡單粗暴識別驗證碼(反爬利器OA信用盤平臺可殺大賠小)

tensorflow實戰:端到端簡單粗暴識別驗證碼(反爬利器OA信用盤平臺可殺大賠小)

今天分享一OA信用盤平臺可殺大賠小(殺豬)QQ2952777280【話仙原始碼論壇】hxforum.com下如何簡單粗暴的解決驗證碼的辦法
背景:
對於一個爬蟲開發者來說,反爬蟲無疑是一個又愛又恨的對手,兩者之間通過鍵盤的鬥爭更是一個沒有硝煙的戰場。
反爬蟲有很多措施,在這裡說說驗證碼這一塊
論爬蟲修養:大家都是混口飯吃,上有老下有小,碼農何苦為難碼農?爬資料的時候儘可能減少伺服器壓力,能爬列表頁,就不爬詳情頁,
正文:
資料集:百度上找的一個驗證碼資料集(因為懶得生成),也可以自己生成。

在訓練前可以先對圖片進行降噪,去掉干擾點,可以用opencv裡面的函式濾波器等。這樣識別會快點

在這裡我就沒有去做啦,不然怎麼叫粗暴呢(真正:懶, 沒時間)

準確率訓練到90+我就儲存模型停止了,大家可以根據需求設定。看下圖

這裡是訓練中的loss以及accuracy

這裡是測試

這個是識別有錯誤的,畢竟我的GTX950也辛苦算了這麼久,再說這個7這麼像1呀。莫得了。

話不多說來個網路結構圖再說

覺得有點亂的,看看下面的圖

劃重點:show you code
import numpy as np
import tensorflow as tf
from PIL import Image
import os
import random
import time

number = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
# 圖片所在資料夾
data_dir = 'F:/checkimages/train'

# 圖片長寬
width = 160
height = 60
# 驗證碼長度
max_captcha = 4
# 每一批次的樣本數
batch_size = 64
# 字元類別的長度
num_numbers = len(number)


def get_train_data(data_dir=data_dir):
# 獲取檔案中的所有圖片的路徑
# 返回包含所有的圖片的地址和標籤的鍵值對一個字典
simples = {}
for file_name in os.listdir(data_dir):
captcha = file_name.split('.')[0]
# {"F:/checkimages/train/1231.jpg" : "1231"}
simples[data_dir + '/' + file_name] = captcha
return simples

simples = get_train_data(data_dir)

# 獲取所有的鍵,也就是所有圖片的詳細地址
file_dir = list(simples.keys())
num_simples = len(simples)

# 獲取一批次的資料
def get_next_batch():
# 初始化全部為0的張量
# batch_x :[64, 160*60]
batch_x = np.zeros([batch_size, width * height])
# batch_y: [64, 10類別 * 4個字元]
batch_y = np.zeros([batch_size, num_numbers * max_captcha])

# 隨機選取一張圖片的資料填進去batch_x,batch_y
# 注意,因為是隨機選的,也即是有可能選到同一張,不過沒關係
for i in range(batch_size):
# 隨機選出一個simples裡面的鍵,也就是圖片的路徑,如 F:/checkimages/train/1231.jpg
file_name = file_dir[random.randint(0, num_simples - 1)]
# 給每一個樣本輸入數值,覆蓋掉之前的0
# np.float32(Image.open(file_name).convert('L')):
# [[247. 247. 247. ... 247. 247. 247.]
# [247. 247. 247. ... 247. 247. 247.]]
# flatten(): 將2維的畫素值轉化為一維的
# 當然還要標準化,除255
batch_x[i, :] = np.float32(Image.open(file_name).convert('L')).flatten() / 255
# 獲取每一個圖片的標籤,轉化為one-hot編碼
batch_y[i, :] = text2vec(simples[file_name])
return batch_x, batch_y

# 將目標值轉換為one-hot編碼。
def text2vec(text):
return [0 if ord(i) - 48 != j else 1 for i in text for j in range(num_numbers)]

小結:
這次分享主要目的事分享一下實現的程式碼,但不是說看了文章就可以識別驗證碼了。想要自己解決這些問題沒有其他的辦法。從頭開始學,歡迎學習交流一下。
這次使用的就是單任務訓練模式。以後還會分享多工模式以及使用Alexnet來實現。有興趣的可以關注一下,以防迷路。