日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
教你使用TensorFlow2對(duì)識(shí)別驗(yàn)證碼

 驗(yàn)證碼是根據(jù)隨機(jī)字符生成一幅圖片,然后在圖片中加入干擾象素,用戶(hù)必須手動(dòng)填入,防止有人利用機(jī)器人自動(dòng)批量注冊(cè)、灌水、發(fā)垃圾廣告等等 。

創(chuàng)新互聯(lián)主營(yíng)邯山網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都App制作,邯山h5小程序設(shè)計(jì)搭建,邯山網(wǎng)站營(yíng)銷(xiāo)推廣歡迎邯山等地區(qū)企業(yè)咨詢(xún)

數(shù)據(jù)集來(lái)源:https://www.kaggle.com/fournierp/captcha-version-2-images

圖片是5個(gè)字母的單詞,可以包含數(shù)字。這些圖像應(yīng)用了噪聲(模糊和一條線)。它們是200 x 50 PNG。我們的任務(wù)是嘗試制作光學(xué)字符識(shí)別算法的模型。

在數(shù)據(jù)集中存在的驗(yàn)證碼png圖片,對(duì)應(yīng)的標(biāo)簽就是圖片的名字。

 
 
 
 
  1. import os
  2. import numpy as np
  3. import pandas as pd
  4. import cv2
  5. import matplotlib.pyplot as plt
  6. import seaborn as sns
  7. # imgaug 圖片數(shù)據(jù)增強(qiáng)
  8. import imgaug.augmenters as iaa
  9. import tensorflow as tf
  10. # Conv2D MaxPooling2D Dropout Flatten Dense BN  GAP
  11. from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Layer, BatchNormalization, GlobalAveragePooling2D 
  12. from tensorflow.keras.optimizers import Adam
  13. from tensorflow.keras import Model, Input 
  14. from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
  15. # 圖片處理器
  16. from tensorflow.keras.preprocessing.image import ImageDataGenerator
  17. import plotly.express as px
  18. import plotly.graph_objects as go
  19. import plotly.offline as pyo
  20. pyo.init_notebook_mode()

對(duì)數(shù)據(jù)進(jìn)行一個(gè)簡(jiǎn)單的分析,統(tǒng)計(jì)圖像中大約出現(xiàn)了什么樣的符號(hào)。

 
 
 
 
  1. # 數(shù)據(jù)路徑
  2. DIR = '../input/captcha-version-2-images/samples/samples'
  3. # 存儲(chǔ)驗(yàn)證碼的標(biāo)簽
  4. captcha_list = []
  5. characters = {}
  6. for captcha in os.listdir(DIR):
  7.     captcha_list.append(captcha)
  8.     # 每張驗(yàn)證碼的captcha_code
  9.     captcha_code = captcha.split(".")[0]
  10.     for i in captcha_code:
  11.         # 遍歷captcha_code 
  12.         characters[i] = characters.get(i, 0) +1
  13. symbols = list(characters.keys())
  14. len_symbols = len(symbols)
  15. print(f'圖像中只使用了{(lán)len_symbols}符號(hào)')
  16. plt.bar(*zip(*characters.items()))
  17. plt.title('Frequency of symbols')
  18. plt.show()

如何提取圖像的數(shù)據(jù)建立X,y??

 
 
 
 
  1. # 如何提取圖像 建立 model  X 的shape  1070 * 50 * 200 * 1 
  2. # y的shape 5 * 1070 * 19
  3.  
  4. for i, captcha in enumerate(captcha_list):
  5.     captcha_code = captcha.split('.')[0]
  6.     # cv2.IMREAD_GRAYSCALE 灰度圖
  7.     captcha_cv2 = cv2.imread(os.path.join(DIR, captcha),cv2.IMREAD_GRAYSCALE)
  8.     # 縮放
  9.     captcha_cv2 = captcha_cv2 / 255.0
  10.     # print(captcha_cv2.shape) (50, 200) 
  11.     # 將captcha_cv2的(50, 200) 切換成(50, 200, 1)
  12.     captcha_cv2 = np.reshape(captcha_cv2, img_shape)
  13.     # (5,19)
  14.     targs = np.zeros((len_captcha, len_symbols))
  15.     
  16.     for a, b in enumerate(captcha_code):
  17.         targs[a, symbols.index(b)] = 1
  18.     X[i] = captcha_cv2
  19.     y[:, i] = targs
  20. print("shape of X:", X.shape)
  21. print("shape of y:", y.shape)

輸出如下

 
 
 
 
  1. print("shape of X:", X.shape)
  2. print("shape of y:", y.shape)

通過(guò)Numpy中random 隨機(jī)選擇數(shù)據(jù),劃分訓(xùn)練集和測(cè)試集

 
 
 
 
  1. # 生成隨機(jī)數(shù)
  2. from numpy.random import default_rng
  3. rng = default_rng(seed=1)
  4. test_numbers = rng.choice(1070, size=int(1070*0.3), replace=False)
  5. X_test = X[test_numbers]
  6. X_full = np.delete(X, test_numbers,0)
  7. y_test = y[:,test_numbers]
  8. y_full = np.delete(y, test_numbers,1)
  9. val_numbers = rng.choice(int(1070*0.7), size=int(1070*0.3), replace=False)
  10. X_val = X_full[val_numbers]
  11. X_train = np.delete(X_full, val_numbers,0)
  12. y_val = y_full[:,val_numbers]
  13. y_train = np.delete(y_full, val_numbers,1)

在此驗(yàn)證碼數(shù)據(jù)中,容易出現(xiàn)過(guò)擬合的現(xiàn)象,你可能會(huì)想到添加更多的新數(shù)據(jù)、 添加正則項(xiàng)等, 但這里使用數(shù)據(jù)增強(qiáng)的方法,特別是對(duì)于機(jī)器視覺(jué)的任務(wù),數(shù)據(jù)增強(qiáng)技術(shù)尤為重要。

常用的數(shù)據(jù)增強(qiáng)操作:imgaug庫(kù)。imgaug是提供了各種圖像增強(qiáng)操作的python庫(kù) https://github.com/aleju/imgaug。

imgaug幾乎包含了所有主流的數(shù)據(jù)增強(qiáng)的圖像處理操作, 增強(qiáng)方法詳見(jiàn)github

 
 
 
 
  1. # Sequential(C, R)  尺寸增加了5倍,
  2. # 選取一系列子增強(qiáng)器C作用于每張圖片的位置,第二個(gè)參數(shù)表示是否對(duì)每個(gè)batch的圖片應(yīng)用不同順序的Augmenter list     # rotate=(-8, 8)  旋轉(zhuǎn)
  3. # iaa.CropAndPad  截取(crop)或者填充(pad),填充時(shí),被填充區(qū)域?yàn)楹谏?/li>
  4. # px: 想要crop(negative values)的或者pad(positive values)的像素點(diǎn)。
  5. # (top, right, bottom, left)
  6. # 當(dāng)pad_mode=constant的時(shí)候選擇填充的值
  7. aug =iaa.Sequential([iaa.CropAndPad(
  8.     px=((0, 10), (0, 35), (0, 10), (0, 35)),
  9.     pad_mode=['edge'],
  10.     pad_cval=1
  11. ),iaa.Rotate(rotate=(-8,8))])
  12. X_aug_train = None
  13. y_aug_train = y_train
  14. for i in range(40):
  15.     X_aug = aug(images = X_train)
  16.     if X_aug_train is not None:
  17.         X_aug_train = np.concatenate([X_aug_train, X_aug], axis = 0)
  18.         y_aug_train = np.concatenate([y_aug_train, y_train], axis = 1)
  19.     else:
  20.         X_aug_train = X_aug

讓我們看看一些數(shù)據(jù)增強(qiáng)的訓(xùn)練圖像。

 
 
 
 
  1. fig, ax = plt.subplots(nrows=2, ncols =5, figsize = (16,16))
  2. for i in range(10):
  3.     index = np.random.randint(X_aug_train.shape[0])
  4.     ax[i//5][i%5].imshow(X_aug_train[index],cmap='gray')

這次使用函數(shù)式API創(chuàng)建模型,函數(shù)式API是創(chuàng)建模型的另一種方式,它具有更多的靈活性,包括創(chuàng)建更為復(fù)雜的模型。

需要定義inputs和outputs

 
 
 
 
  1. #函數(shù)式API模型創(chuàng)建
  2. captcha = Input(shape=(50,200,channels))
  3. x = Conv2D(32, (5,5),padding='valid',activation='relu')(captcha)
  4. x = MaxPooling2D((2,2),padding='same')(x)
  5. x = Conv2D(64, (3,3),padding='same',activation='relu')(x)
  6. x = MaxPooling2D((2,2),padding='same')(x)
  7. x = Conv2D(128, (3,3),padding='same',activation='relu')(x)
  8. maxpool = MaxPooling2D((2,2),padding='same')(x)
  9. outputs = []
  10. for i in range(5):
  11.     x = Conv2D(256, (3,3),padding='same',activation='relu')(maxpool)
  12.     x = MaxPooling2D((2,2),padding='same')(x)
  13.     x = Flatten()(x)
  14.     x = Dropout(0.5)(x)
  15.     x = BatchNormalization()(x)
  16.     x = Dense(64, activation='relu')(x)
  17.     x = Dropout(0.5)(x)
  18.     x = BatchNormalization()(x)
  19.     x = Dense(len_symbols , activation='softmax' , name=f'char_{i+1}')(x)
  20.     outputs.append(x)
  21.     
  22. model = Model(inputs = captcha , outputs=outputs)
  23. # ReduceLROnPlateau更新學(xué)習(xí)率
  24. reduce_lr = ReduceLROnPlateau(patience =3, factor = 0.5,verbose = 1)
  25. model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.0005), metrics=["accuracy"])
  26. # EarlyStopping用于提前停止訓(xùn)練的callbacks。具體地,可以達(dá)到當(dāng)訓(xùn)練集上的loss不在減小
  27. earlystopping = EarlyStopping(monitor ="val_loss",  
  28.                              mode ="min", patience = 10,
  29.                               min_delta = 1e-4,
  30.                              restore_best_weights = True) 
  31. history = model.fit(X_train, [y_train[i] for i in range(5)], batch_size=32, epochs=30, verbose=1, validation_data = (X_val, [y_val[i] for i in range(5)]), callbacks =[earlystopping,reduce_lr])

下面對(duì)model進(jìn)行一個(gè)測(cè)試和評(píng)估。

 
 
 
 
  1. score = model.evaluate(X_test,[y_test[0], y_test[1], y_test[2], y_test[3], y_test[4]],verbose=1)
  2. metrics = ['loss','char_1_loss', 'char_2_loss', 'char_3_loss', 'char_4_loss', 'char_5_loss', 'char_1_acc', 'char_2_acc', 'char_3_acc', 'char_4_acc', 'char_5_acc']
  3. for i,j in zip(metrics, score):
  4.     print(f'{i}: {j}')

具體輸出如下:

 
 
 
 
  1. 11/11 [==============================] - 0s 11ms/step - loss: 0.7246 - char_1_loss: 0.0682 - char_2_loss: 0.1066 - char_3_loss: 0.2730 - char_4_loss: 0.2636 - char_5_loss: 0.0132 - char_1_accuracy: 0.9844 - char_2_accuracy: 0.9657 - char_3_accuracy: 0.9408 - char_4_accuracy: 0.9626 - char_5_accuracy: 0.9938
  2. loss: 0.7246273756027222
  3. char_1_loss: 0.06818050146102905
  4. char_2_loss: 0.10664034634828568
  5. char_3_loss: 0.27299806475639343
  6. char_4_loss: 0.26359987258911133
  7. char_5_loss: 0.013208594173192978
  8. char_1_acc: 0.9844236969947815
  9. char_2_acc: 0.9657320976257324
  10. char_3_acc: 0.940809965133667
  11. char_4_acc: 0.9626168012619019
  12. char_5_acc: 0.9937694668769836

字母1到字母5的精確值都大于

繪制loss和score

 
 
 
 
  1. metrics_df = pd.DataFrame(history.history)
  2. columns = [col for col in metrics_df.columns if 'loss' in col and len(col)>8]
  3. fig = px.line(metrics_df, y = columns)
  4. fig.show()

 
 
 
 
  1. plt.figure(figsize=(15,8))
  2. plt.plot(history.history['loss'])
  3. plt.plot(history.history['val_loss'])
  4. plt.title('model loss')
  5. plt.ylabel('loss')
  6. plt.xlabel('epoch')
  7. plt.legend(['train', 'val'], loc='upper right',prop={'size': 10})
  8. plt.show()
 
 
 
 
  1. # 預(yù)測(cè)數(shù)據(jù)
  2. def predict(captcha):
  3.     captcha = np.reshape(captcha , (1, 50,200,channels))
  4.     result = model.predict(captcha)
  5.     result = np.reshape(result ,(5,len_symbols))
  6.     # 取出最大預(yù)測(cè)中的輸出
  7.     label = ''.join([symbols[np.argmax(i)] for i in result])
  8.     return label
  9.     
  10. predict(X_test[2])
  11. # 25277

下面預(yù)測(cè)所有的數(shù)據(jù)

 
 
 
 
  1. actual_pred = []
  2. for i in range(X_test.shape[0]):
  3.     actual = ''.join([symbols[i] for i in (np.argmax(y_test[:, i],axis=1))])
  4.     pred =  predict(X_test[i])
  5.     actual_pred.append((actual, pred))
  6. print(actal_pred[:10])

輸出如下:

 
 
 
 
  1. [('n4b4m', 'n4b4m'), ('42nxy', '42nxy'), ('25257', '25277'), ('cewnm', 'cewnm'), ('w46ep', 'w46ep'), ('cdcb3', 'edcb3'), ('8gf7n', '8gf7n'), ('nny5e', 'nny5e'), ('gm2c2', 'gm2c2'), ('g7fmc', 'g7fmc')]
 
 
 
 
  1. sameCount = 0
  2. diffCount = 0
  3. letterDiff = {i:0 for i in range(5)}
  4. incorrectness = {i:0 for i in range(1,6)}
  5. for real, pred in actual_pred:
  6.     # 預(yù)測(cè)和輸出相同
  7.     if real == pred:
  8.         sameCount += 1
  9.     else:
  10.         # 失敗
  11.         diffCount += 1
  12.         # 遍歷
  13.         incorrectnessPoint = 0
  14.         for i in range(5):
  15.             if real[i] != pred[i]:
  16.                 letterDiff[i] += 1
  17.                 incorrectnessPoint += 1
  18.         incorrectness[incorrectnessPoint] += 1
  19. x = ['True predicted', 'False predicted']
  20. y = [sameCount, diffCount]
  21. fig = go.Figure(data=[go.Bar(x = x, y = y)])
  22. fig.show()

在預(yù)測(cè)數(shù)據(jù)中,一共有287個(gè)數(shù)據(jù)預(yù)測(cè)正確。

在這里,我們可以看到出現(xiàn)錯(cuò)誤到底是哪一個(gè)index。

 
 
 
 
  1. x1 = ["Character " + str(x) for x in range(1, 6)]
  2.     
  3. fig = go.Figure(data=[go.Bar(x = x1, y = list(letterDiff.values()))])
  4. fig.show()

為了計(jì)算每個(gè)單詞的錯(cuò)誤數(shù),繪制相關(guān)的條形圖。

 
 
 
 
  1. x2 = [str(x) + " incorrect" for x in incorrectness.keys()]
  2. y2 = list(incorrectness.values())
  3. fig = go.Figure(data=[go.Bar(x = x2, y = y2)])
  4. fig.show()

下面繪制錯(cuò)誤的驗(yàn)證碼圖像,并標(biāo)準(zhǔn)正確和錯(cuò)誤的區(qū)別。

 
 
 
 
  1. fig, ax = plt.subplots(nrows = 8, ncols=4,figsize = (16,20))
  2. count = 0
  3. for i, (actual , pred) in enumerate(actual_pred):
  4.     if actual != pred:
  5.         img = X_test[i]
  6.         try:
  7.             ax[count//4][count%4].imshow(img, cmap = 'gray')
  8.             ax[count//4][count%4].title.set_text(pred + ' - ' + actual)
  9.             count += 1
  10.         except:
  11.             pass


分享標(biāo)題:教你使用TensorFlow2對(duì)識(shí)別驗(yàn)證碼
新聞來(lái)源:http://www.dlmjj.cn/article/dhodegp.html