摘要:但是在現今的驗證碼識別中,當要識別的圖片中的文字變成手寫體互相重疊,這種切分法就難以排上用場。下圖是的訓練萬多步的結果的訓練截圖總結本文采用了活著的進行驗證碼識別,可以免去大量進行人工標注的步驟,對工作效率有不小的提升。
1 驗證碼
驗證碼( CAPTCHA )是一種區分用戶是計算機或人的公共全自動程序。在 CAPTCHA 測試中,作為服務器的計算機會自動生成一個問題由用戶來解答。這個問題可以由計算機生成并評判,但是必須只有人類才能解答。由于計算機無法解答 CAPTCHA 的問題,所以回答出問題的用戶就可以被認為是人類。
2 CNN 驗證碼識別傳統的方法是通過兩個不相關的步驟來進行文字識別:1)將圖片中的文字的位置進行定位,然后通過“小框”來切分,將圖片中的文字剪切下來 2)再進行識別。但是在現今的驗證碼識別中,當要識別的圖片中的文字變成手寫體互相重疊,這種“切分”法就難以排上用場。因此卷積神經網絡(CNN)就被用來識別這些無從下手的手寫體。這種CNN 是通過一個或多個卷積層和頂端的全連通層(對應經典的神經網絡)組成來對圖像識別。CNN 訓練模型需要大量的人工標注的圖片來訓練,但是本文方法就是自主產生隨機的字符并產生相應的圖片來在運行過程中調整參數。
本文關注具有 4 個字符的的驗證碼圖片。每個字符在輸出層被表現為 62 個神經元。我們可以假設一個映射函數
即:
將前 62 個神經元分配給序列中的第一個字符,第二批 62 個神經元分配給序列中的第二個字符。因此,對于字符xi
所對應的神經元的索引為
輸出層一共有 4*62=128 個。如果第一個預測字符的索引為 c0=52,因此可以反推預測的字符為
3 實現步驟 1 驗證碼生成 1 驗證碼中的字符number = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] ALPHABET = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"] gen_char_set = number + ALPHABET # 用于生成驗證碼的數據集2 生成驗證碼的字符
# char_set=number + alphabet + ALPHABET, char_set=gen_char_set, # char_set=number, captcha_size=4): """ 生成隨機字符串,4位 :param char_set: :param captcha_size: :return: """ captcha_text = [] for i in range(captcha_size): c = random.choice(char_set) captcha_text.append(c) return captcha_text3 按照字符生成對應的驗證碼
def gen_captcha_text_and_image(): """ 生成字符對應的驗證碼 :return: """ image = ImageCaptcha() captcha_text = random_captcha_text() captcha_text = "".join(captcha_text) captcha = image.generate(captcha_text) captcha_image = Image.open(captcha) captcha_image = np.array(captcha_image) return captcha_text, captcha_image4 訓練
def crack_captcha_cnn(w_alpha=0.01, b_alpha=0.1): """1 定義CNN cnn在圖像大小是2的倍數時性能最高, 如果你用的圖像大小不是2的倍數,可以在圖像邊緣補無用像素。 np.pad(image,((2,3),(2,2)), "constant", constant_values=(255,)) # 在圖像上補2行,下補3行,左補2行,右補2行 """ x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1]) # w_c1_alpha = np.sqrt(2.0/(IMAGE_HEIGHT*IMAGE_WIDTH)) # # w_c2_alpha = np.sqrt(2.0/(3*3*32)) # w_c3_alpha = np.sqrt(2.0/(3*3*64)) # w_d1_alpha = np.sqrt(2.0/(8*32*64)) # out_alpha = np.sqrt(2.0/1024) # 3 conv layer w_c1 = tf.Variable(w_alpha * tf.random_normal([3, 3, 1, 32])) b_c1 = tf.Variable(b_alpha * tf.random_normal([32])) conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding="SAME"), b_c1)) conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME") conv1 = tf.nn.dropout(conv1, keep_prob) w_c2 = tf.Variable(w_alpha * tf.random_normal([3, 3, 32, 64])) b_c2 = tf.Variable(b_alpha * tf.random_normal([64])) conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, w_c2, strides=[1, 1, 1, 1], padding="SAME"), b_c2)) conv2 = tf.nn.max_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME") conv2 = tf.nn.dropout(conv2, keep_prob) w_c3 = tf.Variable(w_alpha * tf.random_normal([3, 3, 64, 64])) b_c3 = tf.Variable(b_alpha * tf.random_normal([64])) conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, w_c3, strides=[1, 1, 1, 1], padding="SAME"), b_c3)) conv3 = tf.nn.max_pool(conv3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME") conv3 = tf.nn.dropout(conv3, keep_prob) # Fully connected layer w_d = tf.Variable(w_alpha * tf.random_normal([8 * 20 * 64, 1024])) b_d = tf.Variable(b_alpha * tf.random_normal([1024])) dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]]) dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d)) dense = tf.nn.dropout(dense, keep_prob) w_out = tf.Variable(w_alpha * tf.random_normal([1024, MAX_CAPTCHA * CHAR_SET_LEN])) b_out = tf.Variable(b_alpha * tf.random_normal([MAX_CAPTCHA * CHAR_SET_LEN])) out = tf.add(tf.matmul(dense, w_out), b_out) # 36*4 # out = tf.reshape(out, (CHAR_SET_LEN, MAX_CAPTCHA)) # 重新變成4,36的形狀 # out = tf.nn.softmax(out) return out
由于時間和設備的限制,我在驗證碼生成字符串中刪去了英文字母只剩下了數字進行訓練。要不然可以算到地老天荒也還是3%的準確率。下圖是gen_char_set = number + ALPHABET的訓練1萬多步的結果的訓練截圖
5 總結本文采用了“活著的 CNN”進行驗證碼識別,可以免去大量進行人工標注的步驟,對工作效率有不小的提升。
文 / JoeCDC
數學愛好者編 / 熒聲
本文已由作者授權發布,版權屬于創宇前端。歡迎注明出處轉載本文。本文鏈接:https://knownsec-fed.com/2018...
想要訂閱更多來自知道創宇開發一線的分享,請搜索關注我們的微信公眾號:創宇前端(KnownsecFED)。歡迎留言討論,我們會盡可能回復。
歡迎點贊、收藏、留言評論、轉發分享和打賞支持我們。打賞將被完全轉交給文章作者。
感謝您的閱讀。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19842.html
閱讀 3564·2021-11-16 11:45
閱讀 2099·2021-11-08 13:23
閱讀 2212·2021-10-11 10:59
閱讀 2892·2021-09-27 13:36
閱讀 2481·2019-08-30 15:54
閱讀 2669·2019-08-29 16:58
閱讀 2783·2019-08-29 16:56
閱讀 1343·2019-08-26 13:52