今天介紹darknet識別文字點選驗證碼, Darknet is an open source neural network framework written in C and CUDA. darknet是基於yolo算法的神經網絡框架。
廢話少說先熱熱身
平台是Ubuntu20,首先要安裝NVIDIA驅動
1、安裝驅動
https://www.nvidia.cn/geforce/drivers/ 找見對應的驅動下載安裝
2、安裝cuda
下載 https://developer.nvidia.com/cuda-toolkit-archive
Ubuntu 通過deb(local)方式安裝
3、安裝cudnn
下載對應版本 https://developer.nvidia.com/cudnn
4、安裝完成后(測試是否成功)
~$ nvidia-smi Wed Sep 16 13:57:38 2020 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 440.33.01 Driver Version: 440.33.01 CUDA Version: 10.2 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 GeForce RTX 208... On | 00000000:08:00.0 Off | N/A | | 45% 34C P8 4W / 215W | 1721MiB / 7973MiB | 0% Default | +-------------------------------+----------------------+----------------------+
接下來安裝darknet
1、安裝
wget https://github.com/pjreddie/darknet/archive/master.zip unzip master.zip # 修改Makefile(GPU和 CUDNN改成1,默認是0) vim darknet-master/Makefile GPU=1 CUDNN=1 # 保存退出,然后編譯 make
2、測試
下載官方的權重文件
wget https://pjreddie.com/media/files/yolov3-tiny.weights
識別
./darknet detect cfg/yolov3-tiny.cfg yolov3-tiny.weights data/dog.jpg
結果:能識別出來並標記位置,這很符合我們想要的結果
分類
./darknet classify cfg/yolov3-tiny.cfg yolov3-tiny.weights data/dog.jpg
結果:
熱身完了,現在開始訓練自己的模型
以某驗文字點選驗證碼為例,先看看樣本,我們要做的就是按照左下角小字的順序,點擊圖片上的文字驗證。
先說說思路(只說大字,小字的類似):
1、搜集足夠的樣本數據
2、標注字的位置
3、訓練定位器
4、識別字的位置,並切割
5、標注字的類別
6、訓練分類器
一、准備數據
定位器需要標注大概 1000張左右就可以了
分類器需要標注大概 36W 張(越多越好,魯迅說過大力出奇跡 ( •̀ .̫ •́ )✧)
二、標注位置
標注工具有很多,我用的是labelImg-1.8.1
1)、安裝(配置過程按照教程)
https://github.com/tzutalin/labelImg/archive/master.zip
2)、配置好之后打開,開始標注
a、選擇yolo模式
b、定位器只設定一個類,使用默認標簽名word(標簽名可以任意取)
c、開始標注
d、標注圖片中所有的字,可以看出圖上有4個漢字(只關注大字)
e、可以看到標注完后有4個結果
f、然后保存
g、點擊下一個繼續標注
3)、標注結果文件
標注完后,在圖片所在的目錄生成了結果文件,與圖片命名相同。
標注文件里有4行數據,對應4個字,以第一行為例
1 表示標簽文件的第一個(從0開始) 0.129360 位置的中心x坐標 0.200521 位置的中心y坐標 0.252907 相對寬度w 0.208333 相對高度h
三、標注完后開始訓練預處理
a、/home/data目錄下,創建訓練集 測試集目錄
mkdir train
mkdir test
b、將標注好的數據以9:1的比率分別放入train和test目錄,制作訓練文件
find `pwd`/train -name \*.jpg > train.list find `pwd`/test -name \*.jpg > test.list train.list內容,就是標注后的圖片絕對路徑 /home/data/train/0.jpg /home/data/train/1.jpg /home/data/train/2.jpg /home/data/train/3.jpg /home/data/train/4.jpg /home/data/train/5.jpg
c、模型配置文件,定位使用yolov3-tiny.cfg就足夠
/home/data/word.cfg
*、藍色可以改 [net] batch=1 # 測試時1,訓練時根據顯存大小設置64 32 16 subdivisions=1 # 測試時1,訓練時根據batch 配置 16 8 4 2 width=416 # 網絡輸入寬度,取默認值 height=416 # 網絡輸入高度,取默認值 channels=3 # 網絡輸入通道數 momentum=0.9 decay=0.0005 # 防止過擬合 angle=0 # 旋轉角度,增強樣本量 saturation = 1.5 # 飽和度 exposure = 1.5 # 曝光量 hue=.1 learning_rate=0.001 # 學習率 burn_in=1000 max_batches = 500200 # 最大訓練次數 policy=steps # 學習策略 steps=400000,450000 scales=.1,.1 *、紅色必須改 [convolutional] size=1 stride=1 pad=1 filters=18# 值為3*(classes + 5) activation=linear [yolo] mask = 0,1,2 anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319 classes=1 #數據集類別(定位器只有1類) num=6 jitter=.3 ignore_thresh = .7 truth_thresh = 1 random=1
d、標簽文件
/home/data/word.labels
文件中每一行都表示一個標簽
e、數據集配置文件
/home/data/word.data classes = 1 # 類別個數 train = /home/data/train.list # 訓練集文件位置 valid = /home/data/test.list # 測試集文件位置 labels = /home/data/word.labels # 標簽位置 backup = backup/word # 結果保存位置 top=5 # 表示輸出前5個結果
f、開始訓練
1、最后目錄結構
/home/data
├── test # 測試集目錄
├── test.list # 測試集文件
├── train # 訓練集目錄
├── train.list # 訓練集文件
├── word.cfg # 模型配置文件
├── word.data # 數據集配置文件
└── word.labels # 標簽文件
2、准備好之后就開始訓練
./darknet detector train /home/data/word.data /home/data/word.cfg
3、開始打印日志:
第1部分:
Region 16 Avg IOU 表示當前subdivision 內圖片的評價IOU數字越大表明 精度越高 Class 標注物體的正確率 Obj 目標越接近1越好 No Obj 趨於0 .5R 當前模型在所有 subdivision 樣本中檢測出的正樣本與實際正樣本的比值 count所有當前 subdivision 圖片中包含正樣本標簽數量
第2部分:
434483 當前迭代次數 0.008373 總體損失(損失很小的時候就可以停止訓練) 0.008263 avg 平均損失 0.000100 rate 當前學習率 0.093013 seconds 當前批次花費時間 6951728 images 參與訓練的圖片總數
4、檢測結果
如果顯存足夠大,訓練過程會很快,訓練完成開始檢測,可以看到成功識別出4個漢字(大字)的位置並標注
./darknet detect /home/data/word.cfg /home/data/word.weights 0.jpg
四、識別位置並切割
darknet中python目錄darknet.py
# 修改點 # so文件路徑 lib = CDLL("libdarknet.so", RTLD_GLOBAL) # 配置文件和模型路徑 net = load_net("/home/data/result/word.cfg", "/home/data/result/word.weights", 0) meta = load_meta("/home/data/result/word.data") # 調用識別函數后返回類別和坐標 (b'0', 0.9999345541000366, (89.49639129638672, 259.5166320800781, 78.38817596435547, 58.78640365600586)) b'0' 類別 0.9999345541000366 識別率 89.49639129638672 位置中心x坐標 259.5166320800781 位置中心y坐標 78.38817596435547 相對寬度w 58.78640365600586 相對高度h # 根據x y w h可以計算出位置的四邊的邊界位置 左 left = x - (w / 2) 右 right = x + (w / 2) 上 top = y - (h / 2) 下 bottom = y + (h / 2)
切割完后
五、標注類別
將所有數據集分割后,開始標注類別,可以借助百度識別,但是效率不高。我們考慮半監督學習,自行標注一部分,然后訓練,再根據訓練結果識別,然后再重復之前的操作。
標注完后大概有4277個類 也就是4277個漢字。
六、訓練分類器
前兩步和定位器一樣
c、模型配置文件,分類器參考darknet19.cfg
/home/data/class.cfg
*、藍色可以改 [net] batch=1 # 測試時1,訓練時根據顯存大小設置64 32 16 subdivisions=1 # 測試時1,訓練時根據batch 配置 16 8 4 2 learning_rate=0.001 # 學習率 max_batches = 500200 # 最大訓練次數 policy=poly # 學習策略 angle=7 # 旋轉樣本 *、紅色必須改 [convolutional] filters=4277 # 總共有多少類 size=1 stride=1 pad=1 activation=linear [avgpool] [softmax] groups=1
d、標簽文件
/home/data/class.labels
文件中每一行都表示一個標簽(所以共有4277行)
e、數據集配置文件
/home/data/class.data
classes = 4277 # 類別個數 train = /home/data/train.list # 訓練集文件位置 valid = /home/data/test.list # 測試集文件位置 labels = /home/data/class.labels # 標簽位置 backup = backup/class # 結果保存位置 top=5 # 表示輸出前5個結果
f、開始訓練
1、訓練
./darknet classifier train /home/data/class.data /home/data/class.cfg
2、日志
3、訓練完成后檢測結果
./darknet classifier predict /home/data/class.data /home/data/class.cfg /home/data/class.weights code0.jpg
可以看出四個字全部識別出來了,識別率還是很高的,好了任務完成~~
(本文只用於學習交流,如涉及作品內容、版權或其它問題,請及時與我們聯系,我們將立即更正或刪除相關內容。)