-------------------------------------------------------------------------------------------------
訓練心得
1. 在yolo中訓練時,修改源碼文件detector后需要make clean 后重新make,修改cfg文件后不需要
2. 很多博客中會要求修改src中的yolo.c文件,其實那是早期的版本中訓練要求的,darknet不需要。原因是這樣的,在官網里有一段執行test的代碼是:
./darknet detect cfg/yolo.cfg yolo.weights data/dog.jpg
這是一段簡寫的執行語句。它的完整形式是這樣的:
./darknet detector test cfg/coco.data cfg/yolo.cfg yolo.weights data/dog.jpg
其實修改.c文件的作用就是讓我們可以使用簡寫的test執行語句,程序會自動調用.c里面設置好的路徑內容。我個人覺得這個很沒有必要。
3. 當有多塊GPU時,如果選擇不同的卡進行訓練時,輸入以下命令:0或者1表示GPU的序號
./darknet detector -i 0 test cfg/voc.data cfg/yolo-voc.cfg backup/yolo-voc_final.weights testpicture/001.jpg
4. 生成的最終的final模型與中間模型沒有太大區別,中間模型是不同數量的數據樣本進行訓練得到的。final其實就是max_batch訓練完之后的那一個
5. 當訓練過程中需要輸出log文件即日志文件時,需要在訓練時一起輸出,補充以下命令:
./darknet detector train cfg/tiny-yolo.cfg tiny-yolo_8000.conv.9 2>1 | tee person_train_log.txt
命令:tee person_train_log.txt :保存log時會生成兩個文件,文件1里保存的是網絡加載信息和checkout點保存信息,person_train_log.txt中保存的是訓練信息。
6. 當選取.cfg網絡,在darknet官網還有很多博文里面都是用的yolo-voc.cfg,我用這個網絡訓練一直失敗。體現在訓練好久后test,沒有bbox和predict結果。出現這種問題有兩種情況,一是訓練發散了;二是訓練不充分,predict結果置信概率太低。
(1)對於訓練發散,其實很容易發現的,就是在訓練的時候觀察迭代次數后邊的兩個loss值,如果這兩個值不斷變大到幾百就說明訓練發散啦。可以通過降低learning rate 和 提高batch數量解決這個問題;(2)對於訓練不充分的時候如何顯示出predict結果,可以在test的時候設置threshold,darknet默認是.25,你可以嘗試逐漸降低這個值看效果。
./darknet detector test cfg/voc.data cfg/yolo-voc.cfg backup/yolo-voc_final.weights testpicture/001.jpg -thresh 0.25
7. 我在訓練模型的時候輸出了中間模型,發現有的模型只有0kb,但是正常的模型應該是202.3MB。由於我用的是服務器,把darkent放到桌面上了,本來桌面的存儲空間就小,我又設置的迭代45000次,每1000次輸出一個模型,這就意味着要占用10G,明顯桌面沒有這么大,后來換了一個位置后訓練正常。
8. 開GPU跑,真的比只有CPU快很多很多倍,可以在Makefile中設置開啟GPU,GPU=1 CUDNN=1 NVCC的路徑也要修改。
9. 當訓練過程中被中斷,可以將最后一次的模型作為預訓練模型繼續訓練。如果一次訓練時間太長,可以用中間自動保存的模型繼續訓練,中間自動保存模型,默認文件夾不改變的情況下在backup里面,訓練命令:
./darknet detector train cfg/voc.data cfg/yolo-voc.cfg yolo-voc_final.weights
不過我一開始沒試成功,加上這個模型直接就除了final。
后面分析出了原因:cfg配置文件中max_batchs設置的為45000,中斷之后將中斷的模型作為預訓練模型的前提迭代次數沒有達到45000,如果之前已經訓練完成了45000次,再次訓練會直接輸出final模型呢。如果想當完全訓練完成后,會生成yolo-voc_final.weights模型,如果在現有的final模型之上繼續訓練,可以修改cfg配置文件。
預處理及測試
1.yolo
yolo的官網介紹了yolo的安裝與測試。建議大家多看看英文官網,因為中文網更新的慢,而且有部分內容省略了。按照官網的步驟就不會有錯。
2.數據的預處理
yolo的數據包括訓練數據和驗證數據(訓練數據用來訓練模型,驗證數據用來調整模型)。訓練數據和驗證數據都包括:a.圖片;b.標簽。需要說明的是,如果采用VOC的話,標簽需要特定xml格式,還要轉化為txt。下面以我目標檢測“貓”為例講解。
(1)在“Image”文件夾下存放所有的圖片樣本(包括訓練數據和驗證數據,而且最好是jpg格式)
(2)下載labelImg(一種圖像標記工具,給圖像中的目標打上標簽,且可以生成訓練需要的xml格式),具體的使用方法可以百度,操作起來很簡單。
(3)與“Image”文件夾同級新建“xml”文件夾,“xml”文件夾存放labelImg得到的所有圖片樣本的標簽。
(4)現在就是要將所有的樣本分成訓練集和驗證集,而且要將訓練集和驗證集對應的xml也分開。這里下載python腳本,直接放在“Image”和“xml”文件夾同級路徑。下載鏈接 密碼:wdv0
(5)運行traindata.py:生成trainImage文件夾,存放訓練圖片;生成trainImageXML文件夾,存放訓練圖片xml標簽;生成validateImage文件夾,存放驗證集圖片;生成validateImageXML文件夾,存放驗證集圖片的xml標簽。
(6)運行trans.py,生成trainImageLabelTxt文件夾,存放訓練圖片通過xml標簽轉化得到的txt文件(若在訓練過程提示txt文件找不到,則把此文件夾下的txt文件夾移動到trainImage文件夾);生成validateImageLabelTxt文件夾,道理一樣。
(7)另外得到的trainImagePath.txt和validateImagePath.txt存放着訓練圖片和驗證圖片的路徑。
3.修改配置文件
接下來就是修改配置文件了:
(1)cfg/voc.data文件中:
classes= 1 train = /home/pdd/pdwork/darknet2/darknet/VOC/cat/trainImagePath.txt valid = /home/pdd/pdwork/darknet2/darknet/VOC/cat/validateImagePath.txt names = data/cats.names
classes存放類別總數(這里只有cat一種),train 和valid 放着的是訓練圖片和驗證圖片的路徑
(2)yolo-voc.cfg
將[region]中的classes改為1(這里只有cat一類),將最后一個[convolutional](緊挨着[region]的前一個)中的filter改為30(filter的公式filters=(classes+ coords+ 1)* (NUM) ,我的是(1+4+1)* 5=30)。
(3)cats.names
在data文件夾下新建cats.names,具體見(1)。
4.下載預訓練文件
下載darknet19_448.conv.23,以在其他數據集上pretrain的模型做為初值,下載鏈接,密碼:ynhg。放在darknet文件夾下。
5.訓練
在darknet文件夾路徑下運行命令:
./darknet detector train cfg/voc.data cfg/yolo-voc.cfg cfg/darknet19_448.conv.23
系統默認會迭代45000次batch,如果需要修改訓練次數,進入cfg/yolo_voc.cfg修改max_batches的值。
6.測試
訓練完成后,模型成功保存,輸入命令測試一下這個模型吧:
./darknet detector test cfg/voc.data cfg/yolo-voc.cfg backup/yolo-voc_final.weights testpicture/001.jpg
參數解釋
1. cfg文件參數含義
batch: 每一次迭代送到網絡的圖片數量,也叫批數量。增大這個可以讓網絡在較少的迭代次數內完成一個epoch。在固定最大迭代次數的前提下,增加batch會延長訓練時間,但會更好的尋找到梯度下降的方向。如果你顯存夠大,可以適當增大這個值來提高內存利用率。這個值是需要大家不斷嘗試選取的,過小的話會讓訓練不夠收斂,過大會陷入局部最優。
subdivision:這個參數很有意思的,它會讓你的每一個batch不是一下子都丟到網絡里。而是分成subdivision對應數字的份數,一份一份的跑完后,在一起打包算作完成一次iteration。這樣會降低對顯存的占用情況。如果設置這個參數為1的話就是一次性把所有batch的圖片都丟到網絡里,如果為2的話就是一次丟一半。
angle:圖片旋轉角度,這個用來增強訓練效果的。從本質上來說,就是通過旋轉圖片來變相的增加訓練樣本集。
saturation,exposure,hue:飽和度,曝光度,色調,這些都是為了增強訓練效果用的。
learning_rate:學習率,訓練發散的話可以降低學習率。學習遇到瓶頸,loss不變的話也減低學習率。
max_batches: 最大迭代次數。
policy:學習策略,一般都是step這種步進式。
step,scales:這兩個是組合一起的,舉個例子:learn_rate: 0.001, step:100,25000,35000 scales: 10, .1, .1 這組數據的意思就是在0-100次iteration期間learning rate為原始0.001,在100-25000次iteration期間learning rate為原始的10倍0.01,在25000-35000次iteration期間learning rate為當前值的0.1倍,就是0.001, 在35000到最大iteration期間使用learning rate為當前值的0.1倍,就是0.0001。隨着iteration增加,降低學習率可以是模型更有效的學習,也就是更好的降低train loss。
最后一層卷積層中filters數值是 5×(類別數 + 5)。
region里需要把classes改成你的類別數。
最后一行的random,是一個開關。如果設置為1的話,就是在訓練的時候每一batch圖片會隨便改成320-640(32整倍數)大小的圖片。目的和上面的色度,曝光度等一樣。如果設置為0的話,所有圖片就只修改成默認的大小 416*416。
2. 訓練log中各參數的意義
Region Avg IOU:平均的IOU,代表預測的bounding box和ground truth的交集與並集之比,期望該值趨近於1。
Class:是標注物體的概率,期望該值趨近於1.
Obj:期望該值趨近於1.
No Obj:期望該值越來越小但不為零.
Avg Recall:期望該值趨近1
avg:平均損失,期望該值趨近於0
rate:當前學習率
-------------------------------------------------------------------------------------------------
如果上面的資料對你有啟發,麻煩點個推薦,讓更多人的人看到哦。
關注公眾號【兩猿社】,懂點互聯網,懂點IC的程序猿,帶你豐富項目經驗哦