初涉YOLO

一瞥(You Only Look Once, YOLO),是檢測Pascal VOC 2012數據集內對象/目標的系統,能夠檢測出20種Pascal對象:

人person

鳥bird、貓cat、牛cow、狗dog、馬horse、羊sheep

飛機aeroplane、自行車bicycle、船boat、巴士bus、汽車car、摩托車motorbike、火車train

瓶子bottle、椅子chair、餐桌dining table、盆景potted plant、沙發sofa、顯示器tv/monitor

YOLO由以下參與者共同完成:Santosh、Ross和Ali,詳細內容參見其paper

以下教程分爲9部分(不要害怕,easy),運行系統Ubuntu 14.04。OpenCV、cuda、GPU這些依賴是可選項,如果沒有也可以,就是慢點(其實是慢很多)啦。最後會添加一下官網教程中沒有的安裝錯誤和修改信息。

本篇教程內容全部翻譯自官網

1.How It Works

先前的檢測系統多使用分類器(classifier)或者定位器(localizer)進行檢測任務,把圖片的不同局部位置和多種尺度輸入到模型中去,圖片得分較高的區域(region)作爲檢測目標。

YOLO是一個全新的方法,把一整張圖片一下子應用到一個神經網絡中去。網絡把圖片分成不同的區域,然後給出每個區域的邊框預測和概率,並依據概率大小對所有邊框分配權重。最後,設置閾值,只輸出得分(概率值)超過閾值的檢測結果。


輸入-檢測-輸出

我們的模型相比於基於分類器的模型有一些優勢,在測試階段,整張圖片一次輸入到模型中,所以預測結果結合了圖片的全局信息。同時,模型只是用一次網絡計算來做預測,而在R-CNN中一張圖片就需要進行上千次的網絡計算!所以YOLO非常快,比R-CNN快1000倍,比Fast R-CNN快100倍。整個系統的細節見paper

2.Detection Using A Pre-Trained Model

本節內容會知道你如何使用YOLO預訓練好的模型進行目標檢測。在這之前,你應該安裝好DarkNet,安裝方法戳這裏

安裝好DarkNet之後,在darknet的子目錄cfg/下已經有了一些網絡模型的配置文件,在使用之前,需要下載好預訓練好的權重文件yolo.weights(1.0 GB).

現在,使用DarkNet的yolo命令進行一下測試吧(假設你在darknet/目錄下,自己修改好yolo.weights和image的路徑)

 ./darknet yolo test cfg/yolo.cfg <path>/yolo.weights <image>        

如果你沒有現成的圖片,不妨直接使用darknet/data/下面的某張圖片。

進行上面的測試,Darknet會打印出檢測到的目標對象和可信度,以及耗時。使用CPU時,每張圖片耗時爲6-12秒,GPU版本會快,快很多。

如果安裝DarkNet的時候,沒有使用OpenCV,上面的測試不會直接顯示出圖片結果,你需要自己手動打開predictions.png. 打開你會看到類似於下圖的預測結果


predictions.png

如果想運行一次DarkNet檢測多張圖片的話,你應該先運行以下命令載入預訓練模型

./darknet yolo test cfg/yolo.cfg yolo.weights                  

模型載入成功後,會提示輸入圖片路徑Enter Image Path:

鍵入類似於data/eagle.jpg的路徑,檢測這張圖片,給出結果之後,會繼續提示Enter Image Path。注意如果你連續輸入了多張圖片,之前的結果會被下一次的檢測結果覆蓋掉,因爲預測結果都叫predictions.jpg。。。要退出/中斷程序的話,直接鍵入Ctrl-C(自己記住這個命令,後面會再用)即可。

3.A Smaller Model

上面的YOLO模型會佔用很多GPU內存,方法類似,只需要調用不同的配置文件,載入相應的權重文件即可。在這裏,提供一個更小版本的模型,使用yolo-small.cfg配置文件,調用yolo-small.weights(359MB),命令如下

 ./darknet yolo test cfg/yolo-small.cfg yolo-small.weights                   

這個小版本的YOLO大概佔用1.1GB的GPU內存~

4.A Tiny Model, yolo-tiny.weights(172 MB)

 ./darknet yolo test cfg/yolo-tiny.cfg yolo-tiny.weights                   

佔用611MB的GPU內存,在Titan X上的速度是150 fps

5.YOLO Model Comparison

yolo.cfg,基於extraction網絡,處理一張圖片的速度爲45fps,訓練數據來源2007 train/val + 2012 train/val + 2007、2012所有數據

yolo-small.cfg,全連接層變小,佔用內存變小,50fps,訓練數據來源2007 train/val + 2012 train/val

yolo-tiny.cfg,更加小型的網絡,基於DarkNet reference network,155fps,數據來源2007 train/val + 2012 train/val

6.Changing The Detection Threshold

YOLO默認返回可信度至少爲0.2的檢測結果,可以通過-thres <val>參數改變可信度閾值,例如設置爲0:

./darknet yolo test cfg/yolo.cfg yolo.weights data/dog.jpg -thresh 0

這將可能返回所有的檢測結果。

7.Real-Time Detection On VOC 2012

如果編譯時使用了CUDA,那麼預測的速度回遠遠超過你(手動)輸入圖片的速度。爲了更快速地檢測多張圖片的內容,應該使用yolo的valid子程序。

首先預備好數據並生成元數據給DarkNet。這裏我們使用VOC2012的數據(需要註冊一個賬號才能下載),下載2012test.rar文件之後,運行以下命令

tar xf 2012test.tar

cp VOCdevkit/VOC2012/ImageSets/Main/test.txt .

sed 's?^?'`pwd`'/VOCdevkit/VOC2012/JPEGImages/?; s?$?.jpg?' test.txt > voc.2012.test

這些命令首先解壓數據包,然後生成全路徑的測試圖像,然後把voc.2012.test移動到darknet/data子目錄下

mv voc.2012.test <path-to>/darknet/data

OKAY,現在使用這些圖片做檢測,我們使用CUDA版本的,超級快!運行下面命令

./darknet yolo valid cfg/yolo.cfg yolo.weights

運行上面命令後,你會看到一串數字在屏幕上飛,數字表示當前處理了多少圖片。VOC 2012 test數據集共有10991張圖片,共耗時250秒,相當於44fps。如果你用Selective Search方法的話,要耗時6小時!相比之下,咱的方法整個pipeline才耗時4分鐘,pretty cool!

預測結果在results/子目錄下,其格式爲Pascal VOC要求提交的特殊格式。

如果你想復現我們在Pascal挑戰賽中的結果,你得使用yolo-rescore.weights纔行。

8.Real-Time Detection on a Webcam

只是簡單地跑一下測試數據集,而且看不到實時的結果,真的挺無趣的。所以,我們把輸入改成webcam

挖個坑,後面填

9.Training YOLO

其實,你可以從頭開始訓練YOLO,如果你想的話。你可以嘗試不同的訓練方法,設置不同的超參數,以及使用自己的數據集。咱們下面嘗試自己訓練Pascal VOC數據集。

9.1下載Pascal VOC Data

咱們先下載2007年到2012年的VOC數據,下載之前,新建一個文件夾(比如VOC)存放這些數據,進入此文件夾,按如下方式下載數據,然後解壓。

curl -O http://pjreddie.com/media/files/VOCtrainval_11-May-2012.tar

curl -O http://pjreddie.com/media/files/VOCtrainval_06-Nov-2007.tar

curl -O http://pjreddie.com/media/files/VOCtest_06-Nov-2007.tar

tar xf VOCtrainval_11-May-2012.tar

tar xf VOCtrainval_06-Nov-2007.tar

tar xf VOCtest_06-Nov-2007.tar

解壓完之後,所有數據都自動存放在VOCdevkit/子目錄下了。

9.2生成VOC的標註信息

接下來生成DarkNet訓練所需的標籤文件,該文件擴展名爲.txt,文件內每一行對應一張圖片的標註信息,具體格式如下

<object-class> <x> <y> <width> <height>

其中的x, y, width和height是對應圖片上的座標和寬、高。只要運行一下DarkNet項目中scripts/子目錄下面的voc_label.py腳本,就會自動生成VOC的標註文件。如果你沒找到這個文件,可以再重新下載一下。下載和腳本運行方式如下

curl -O http://pjreddie.com/media/files/voc_label.py

python voc_label.py

這個腳本大概要運行幾分鐘,運行結束之後,你會看到多了兩個文件夾,VOCdevkit/VOC2007/labels/和VOCdevkit/VOC2012/labels/。

現在,你的VOC目錄下應該是這個樣子的

ls
2007_test.txt   VOCdevkit
2007_train.txt  voc_label.py
2007_val.txt    VOCtest_06-Nov-2007.tar
2012_train.txt  VOCtrainval_06-Nov-2007.tar
2012_val.txt    VOCtrainval_11-May-2012.tar

其中的文本文件,比如2007_test.txt,包含的內容是VOC 2007年的test數據集標註信息。DarkNet需要一個txt文件提供所有標註信息,所以我們還需要把這些信息導入到一個txt文件中。本例中,我們使用2007年的train和validation數據和2012年的train數據作爲訓練集,2012年的validation數據作驗證數據。具體使用如下命令

cat 2007_* 2012_train.txt > train.txt

OKAY,現在2007年的所有圖片和2012年的train數據集的圖片路徑都在train.txt文件裏面了。標註信息在下面兩個路徑中

/darknet/VOC/VOCdevkit/VOC2007/labels/ 

 /darknet/VOC/VOCdevkit/VOC2012/labels/ 

上面所做的就是訓練自己的數據集之前所要準備的數據信息了。

9.3重定向DarkNet到Pascal數據

進入DarkNet目錄中,src/子目錄裏面有一個yolo.c文件,打開並編輯一下其中的18、19行(54、55行?不重要,自己確定)

18    char *train_images = "/your_path/VOC_train/train.txt";
19    char *backup_directory = "/your_path/backup/";

其中,train_images指向的是訓練文件,backup_directory指向的是訓練過程中權重的備份路徑。編輯好yolo.c之後,保存,重新編譯一下DarkNet。

9.4下載預訓練之後的卷積權重

訓練的時候使用來自Extraction模型的卷積層權重,這個模型訓練時用的是Imagenet數據。從這(54MB)下載這些權重。如果你想直接用Extraction模型生成這些預訓練好的權重,你得先下載預訓練好的Extraction模型,運行下面的命令

./darknet partial cfg/extraction.cfg extraction.weights extraction.conv.weights 25

勸告大家直接下載權重會更簡單。。。

9.5訓練

運行下面命令開始訓練

./darknet yolo train cfg/yolo.cfg extraction.conv.weights

運行時,屏幕會提示一下數字和任務信息。

如果你想訓練更快些,同時降低提示信息頻率,首先終止訓練,然後在cfg/yolo.cfg中修改一下第三行的信息

3    subdivisions = 2

或修改成4,或更大,比如64。然後重新開始訓練

9.6訓練Checkpoints

每訓練128000張圖片之後,DarkNet自動保存checkpoint信息到你在src/yolo.c中指定的備份路徑下。checkpoint的文件名類似於yolo_12000.weights。你可以使用這些checkpoint信息重新開始訓練,避免從頭開始。

40,000次迭代之後,DarkNet會保存模型的權重,然後結束訓練,最後的權重會以yolo.weights命名。

恭喜,這就訓練結束了~

Good Luck!!

上兩張訓練時的截圖


running_1

running_2



下面是你安裝過程中可能遇到的問題和解決辦法

Q1.使用GPU=1,運行測試命令,例如

./darknet imtest data/eagle.jpg

或者

./darknet yolo demo cfg/yolo.cfg yolo.weights並鍵入圖片地址

報以下錯誤

L2 Norm: 372.007568

CUDA Error:invalid device function

darknet: ./src/cuda.c:21: check_error: Assertion `0' failed.

Aborted (core dumped)

看了看./src/cuda.c的代碼也沒發現啥。。。

出現這個問題是因爲DarkNet的配置信息Makefile文件裏面的GPU架構和實際安裝的GPU不對應。

ARCH= --gpu-architecture=compute_xx  --gpu-code=compute_xx

經測試,k40m和k40顯卡應該設置爲

ARCH= --gpu-architecture=compute_35  --gpu-code=compute_35

tk1顯卡的設置應該爲

ARCH=--gpu-architecture=compute_20 --gpu-code=compute_20

或許這些信息對你有所幫助


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章