captcha_trainer 驗證碼識別-訓練 使用記錄


captcha_trainer 驗證碼識別-訓練 使用記錄

在爬數據的時候,網站出現了驗證碼,那么我們就得去識別驗證碼了。目前有兩種方案

  1. 接入打碼平台(花錢,慢)
  2. 自己訓練(費時,需要GPU環境,快)

那么我采用的是使用開源訓練框架 https://github.com/kerlomz/captcha_trainer

訓練集准備

圖片示例:

  1. 請求網站驗證碼具體接口,訓練集(2w張) 測試集(1k張)
  2. 從打碼平台進行標注
  3. 提交驗證碼給網站 檢測 打碼平台正確性
  4. 保存驗證碼圖片格式為 {結果}_{md5(文件)}.jpg
  5. 打包訓練集 測試集
    在projects/項目名/model.yaml 文件中配置訓練集位置
Trains:
DatasetPath:
  Training: 
    # 訓練集打包結果路徑
    - ./projects/wacai-model-CNN5-GRU-H64-CTC-C1/dataset/Trains.0.tfrecords
  Validation: 
    # 測試集打包結果路徑
    - ./projects/wacai-model-CNN5-GRU-H64-CTC-C1/dataset/Validation.0.tfrecords
SourcePath:
  Training: 
    # 訓練集圖片路徑
    - D:/PyCode/XiaoXiangDemo/APPCheck/WaCaiCaptchaTraining/images
  Validation: 
    # 測試集圖片路徑
    - D:/PyCode/XiaoXiangDemo/APPCheck/WaCaiCaptchaTraining/images2

最后在項目主目錄下 運行 python make_dataset.py 項目名 方式打包

設置訓練配置

根據項目作者的參數說明,配置了符合我自己項目的要求

# - requirement.txt  -  GPU: tensorflow-gpu, CPU: tensorflow
# - If you use the GPU version, you need to install some additional applications.
# MemoryUsage: 顯存占用率,推薦0.6-0.8之間
System:
  MemoryUsage: {MemoryUsage}
  Version: 2

# CNNNetwork: [CNN5, ResNet50, DenseNet] 
# RecurrentNetwork: [CuDNNBiLSTM, CuDNNLSTM, CuDNNGRU, BiLSTM, LSTM, GRU, BiGRU, NoRecurrent]
# - 推薦配置為 不定長問題:CNN5+GRU ,定長:CNN5/DenseNet/ResNet50
# UnitsNum: RNN層的單元數 [16, 64, 128, 256, 512] 
# - 神經網絡在隱層中使用大量神經元,就是做升維,將糾纏在一起的特征或概念分開。
# Optimizer: 優化器算法 [AdaBound, Adam, Momentum]
# OutputLayer: [LossFunction, Decoder]
# - LossFunction: 損失函數 [CTC, CrossEntropy] 
# - Decoder: 解碼器 [CTC, CrossEntropy] 
NeuralNet:
  CNNNetwork: {CNNNetwork}
  RecurrentNetwork: {RecurrentNetwork}
  UnitsNum: {UnitsNum}
  Optimizer: {Optimizer}
  OutputLayer:
    LossFunction: {LossFunction}
    Decoder: {Decoder}


# ModelName: 模型名/項目名,同時也對應編譯后的pb模型文件名
# ModelField: 模型處理的數據類型,目前只支持圖像 [Image, Text]
# ModelScene: 模型處理的場景類型,目前只支持分類場景 [Classification]
# - 目前只支持 “圖像分類” 這一種場景.
Model:
  ModelName: {ModelName}
  ModelField: {ModelField}
  ModelScene: {ModelScene}

# FieldParam 分為 Image, Text 兩種,不同數據類型時可配置的參數不同,目前只提供 Image 一種。
# ModelField 為 Image 時:
# - Category: 提供默認的內置解決方案:
# -- [ALPHANUMERIC(含大小寫英文數字), ALPHANUMERIC_LOWER(小寫英文數字), 
# -- ALPHANUMERIC_UPPER(大寫英文數字),NUMERIC(數字), ALPHABET_LOWER(小寫字母), 
# -- ALPHABET_UPPER(大寫字母), ALPHABET(大小寫字母), 
# -- ALPHANUMERIC_CHS_3500_LOWER(小寫字母數字混合中文常用3500)]
# - 或者可以自定義指定分類集如下(中文亦可):
# -- ['Cat', 'Lion', 'Tiger', 'Fish', 'BigCat']
# - Resize: 重置尺寸,對應網絡的輸入: [ImageWidth, ImageHeight/-1, ImageChannel]
# - ImageChannel: 圖像通道,3為原圖,1為灰度 [1, 3]
# - 為了配合部署服務根據圖片尺寸自動選擇對應的模型,由此誕生以下參數(ImageWidth,ImageHeight):
# -- ImageWidth: 圖片寬度.
# -- ImageHeight: 圖片高度.
# - MaxLabelNum: 該參數在使用CTC損失函數時將被忽略,僅用於使用交叉熵作為損失函數/標簽數固定時使用
# ModelField 為 Text 時:
# - 該類型暫時不支持
FieldParam:
  Category: {Category}
  Resize: {Resize}
  ImageChannel: {ImageChannel}
  ImageWidth: {ImageWidth}
  ImageHeight: {ImageHeight}
  MaxLabelNum: {MaxLabelNum}
  OutputSplit: {OutputSplit}


# 該配置應用於數據源的標簽獲取.
# LabelFrom: 標簽來源,目前只支持 從文件名提取 [FileName, XML, LMDB]
# ExtractRegex: 正則提取規則,對應於 從文件名提取 方案 FileName:
# - 默認匹配形如 apple_20181010121212.jpg 的文件.
# - 默認正則為 .*?(?=_.*\.)
# LabelSplit: 該規則僅用於 從文件名提取 方案:
# - 文件名中的分割符形如: cat&big cat&lion_20181010121212.png,那么分隔符為 &
# - The Default is null.
Label:
  LabelFrom: {LabelFrom}
  ExtractRegex: {ExtractRegex}
  LabelSplit: {LabelSplit}


# DatasetPath: [Training/Validation], 打包為TFRecords格式的訓練集/驗證集的本地絕對路徑。
# SourcePath:  [Training/Validation], 未打包的訓練集/驗證集源文件夾的本地絕對路徑。
# ValidationSetNum: 驗證集數目,僅當未配置驗證集源文件夾時用於系統隨機抽樣用作驗證集使用。
# - 該選項用於懶人訓練模式,當樣本極度不均衡時建議手動設定合理的驗證集。
# SavedSteps: 當 Session.run() 被執行一次為一步(1.x版本),保存訓練過程的步數,默認為100。
# ValidationSteps: 用於計算准確率,驗證模型的步數,默認為每500步驗證一次。
# EndAcc: 結束訓練的條件之准確率 [EndAcc*100]% 到達該條件時結束任務並編譯模型。
# EndCost: 結束訓練的條件之Cost值 EndCost 到達該條件時結束任務並編譯模型。
# EndEpochs: 結束訓練的條件之樣本訓練輪數 Epoch 到達該條件時結束任務並編譯模型。
# BatchSize: 批次大小,每一步用於訓練的樣本數量,不宜過大或過小,建議64。
# ValidationBatchSize: 驗證集批次大小,每個驗證准確率步時,用於驗證的樣本數量。
# LearningRate: 學習率 [0.1, 0.01, 0.001, 0.0001] fine-tuning 時選用較小的學習率。
Trains:
  DatasetPath:
    Training: {DatasetTrainsPath}
    Validation: {DatasetValidationPath}
  SourcePath:
    Training: {SourceTrainPath}
    Validation: {SourceValidationPath}
  ValidationSetNum: {ValidationSetNum}
  SavedSteps: {SavedSteps}
  ValidationSteps: {ValidationSteps}
  EndAcc: {EndAcc}
  EndCost: {EndCost}
  EndEpochs: {EndEpochs}
  BatchSize: {BatchSize}
  ValidationBatchSize: {ValidationBatchSize}
  LearningRate: {LearningRate}

# 以下為數據增廣的配置
# Binaryzation: 該參數為 list 類型,包含二值化的上界和下界,值為 int 類型,參數為 -1 表示未啟用。
# MedianBlur: 該參數為 int 類型,參數為 -1 表示未啟用。
# GaussianBlur: 該參數為 int 類型,參數為 -1 表示未啟用。
# EqualizeHist: 該參數為 bool 類型。
# Laplace: 該參數為 bool 類型。
# WarpPerspective: 該參數為 bool 類型。
# Rotate: 該參數為大於 0 的 int 類型,參數為 -1 表示未啟用。
# PepperNoise: 該參數為小於 1 的 float 類型,參數為 -1 表示未啟用。
# Brightness: 該參數為 bool 類型。
# Saturation: 該參數為 bool 類型。
# Hue: 該參數為 bool 類型。
# Gamma: 該參數為 bool 類型。
# ChannelSwap: 該參數為 bool 類型。
# RandomBlank: 該參數為大於 0 的 int 類型,參數為 -1 表示未啟用。
# RandomTransition: 該參數為大於 0 的 int 類型,參數為 -1 表示未啟用。
DataAugmentation:
  Binaryzation: {DA_Binaryzation}
  MedianBlur: {DA_MedianBlur}
  GaussianBlur: {DA_GaussianBlur}
  EqualizeHist: {DA_EqualizeHist}
  Laplace: {DA_Laplace}
  WarpPerspective: {DA_WarpPerspective}
  Rotate: {DA_Rotate}
  PepperNoise: {DA_PepperNoise}
  Brightness: {DA_Brightness}
  Saturation: {DA_Saturation}
  Hue: {DA_Hue}
  Gamma: {DA_Gamma}
  ChannelSwap: {DA_ChannelSwap}
  RandomBlank: {DA_RandomBlank}
  RandomTransition: {DA_RandomTransition}
  
# 以下為預處理的配置 
# Binaryzation: 該參數為 list 類型,包含二值化的上界和下界,值為 int 類型,參數為 -1 表示未啟用。
# ReplaceTransparent: 使用白色替換透明背景
# HorizontalStitching: 水平拆分拼接,適用於上下分層
# ConcatFrames: 根據幀索引列表水平合並幀
# BlendFrames: 根據幀索引列表融合幀內容
Pretreatment:
  Binaryzation: {Pre_Binaryzation}
  ReplaceTransparent: {Pre_ReplaceTransparent}
  HorizontalStitching: {Pre_HorizontalStitching}
  ConcatFrames: {Pre_ConcatFrames}
  BlendFrames: {Pre_BlendFrames}

開始訓練

執行 python trains.py 項目名 方式訓練。然后就開始等待訓練完成,生成 .pb文件

調用 pb 文件進行識別

采用作者提供的 muggle_ocr 項目來進行調用 pb 文件,進行驗證碼識別

import muggle_ocr
yaml_path = 'xx.pb'
sdk = muggle_ocr.SDK(model_type=muggle_ocr.ModelType.Captcha,conf_path=yaml_path)
url = 'http://www.xxx/image/11.jpg'
response = requests.get(url, verify=False)
text = self.sdk.predict(image_bytes=response.content)

結語

這樣簡單的操作就完成了驗證碼識別了,是不是太方便了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM