本來就想著是對自己第一次跑yolov5的coco128的一個記錄,沒想到現在準備總結一下的時候,一方面是繼續學習了一些,另一方面是學長的一些任務的要求,挖出了更多的東西,所以把名字改為了“從入門到出土“。
00 GitHub訪問加速
首先我們要把yolov5框架從GitHub上拉下來,國內如果要快速訪問GitHub的話呢,需要把Github的相關域名寫入Hosts檔案。
00-1 修改hosts的原理
-
hosts檔案原理
hosts檔案是一個用於儲存計算機網路中各節點資訊的計算機檔案。這個檔案負責將主機名對映到相應的IP地址。hosts檔案通常用於補充或取代網路中DNS的功能。
和DNS不同的是,計算機的使用者可以直接對hosts檔案進行控制。
關於DNS解析,我在CTF的學習中有所記錄
https://www.cnblogs.com/Roboduster/p/15575207.html 00-03瀏覽器。
-
作用過程
當我們在瀏覽器中輸入一個需要登入的網址時,系統會先檢查系自己的Hosts檔案中是否有這個域名和IP的對映關係。
如果有,則直接訪問這個IP地址指定的網路位置;
如果沒有, 再向已知的DNS(Domain Name System,域名系統)伺服器提出域名解析請求。
也就是說Hosts的IP解析優先順序比DNS解析要高。
-
我們把github相關IP寫入hosts,就能在DNS解析之前通過hosts檔案的IP解析訪問我們想要訪問的域名。
00-2 修改hosts檔案
瞭解了原理,其實就很簡單,我們在域名解析網站上搜github相關的IP,找到ttl值小的寫入hosts即可。
我們選用http://tool.chinaz.com/dns/這個網站。
搜尋以下域名
1 github.global.ssl.fastly.net 2 3 github.com 4 5 codeload.github.com
找到比較小的ttl值的ip,放入hosts檔案:
1 sudo gedit /etc/hosts
1 # 然後更新配置 2 sudo /etc/init.d/networking restart
注意ip每隔一段時間會變動,所以每隔一段時間需要更新。
01 YOLOv5框架獲取
1 # 用git獲取原始碼 在上一步配置好的情況下 會很快 2 git clone https://github.com/ultralytics/yolov5 3 # 進入yolov5資料夾下 4 cd yolov5 5 # 依據包裡的requirements.txt安裝 需要的庫 6 # 優先考慮清華源下載 不然可能會很慢 7 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 8 9 # 這種辦法在windows下也可以,通過pycharm開啟終端進行命令列的輸入
02 測試 / 預測
02-0 目錄框架
對於初學者而言,把YOLOv5跑起來的難點之一就是目錄結構,這裡我簡單介紹以下我的專案的目錄結構:
再來重點看一下yolov5目錄下的data和runs目錄,這兩個目錄下的內容前者將成為yolo框架的輸入,後者將作為輸出。
02-1 對於圖片的detect
在yolov5的目錄下(畫重點)執行:
1 # 執行detect.py 2 python detect.py 3 # 或者 4 python detect.py --source data/images/ --weights ./yolov5s.pt 5 # 解釋: 使用權重檔案為yolov5s.pt的模型,使用data/images下的圖片作為推理圖片 6 7 #或者 8 python detect.py --weights yolov5s.pt --img 640 --conf 0.25 --source data/images/ 9 # 解釋:使用權重檔案為yolov5s.pt的模型,推理圖片為640(pixels),最小置信度為0.25,使用yolov5資料夾中data/images資料夾下的檔案作為處理圖片(預設儲存到yolov5/runs/detect/exp資料夾下)
實際上官網給出的命令引數為:
python detect.py --source 0 # webcam img.jpg # image video.mp4 # video檔案 path/ # directory path/*.jpg # 所有jpg檔案 'https://youtu.be/Zgi9g1ksQHc' #指定連結 'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP stream #備註 # rtsp等是各種傳輸協議,將攝像頭等裝置連線到電腦,通過一些方式獲得這種連結,作為引數成為輸入,進而可以實現實時檢測。 # 除了source引數,還有weights,用於指定不同的權重模型,具體模型在04部分
執行完畢後輸出:
這裡我已經跑過一次了,所以終端裡輸出的東西少了很多。下圖是我儲存的當時跑的截圖,圖片裡是正在下載5s權重檔案。
按照終端最後的提示,結果被儲存在runs/detect/exp3,此外source源下的兩張圖片中的目標情況也被終端列出,比如bus.jpg中是4個人、1個bus。
我們在上面提到的目錄下就可以找到檢測之後的結果
ps:
在windows下用pycharm或是在ubuntu下使用pycharm圖形化介面的話,其實也可以使用pycharm裡的終端進行命令列的輸入。
此外我們可以在編輯器裡檢視detect.py的原始碼,裡面在parse_opt()函式裡設定了一些引數,比如原始碼中預設指定了yolov5s.pt作為權重檔案......這也是為什麼直接python detect.py可行的原因。這點後面再講;
(使用yolov5的不同模型會出現不同的效果,這點後面04部分會講解)
(注意我在裡使用的是yolov5的v6.0分支的程式碼)
閱讀這些原始碼我的感受之一就是python學的還不夠,用法真挺多的。
02-2 對於視訊的detect
對圖片的檢測其實沒多大意思,我們可以看一看對於視訊的檢測。
我們可以在yolov5所在的資料夾YOLO裡下載視訊,這裡我切換到了實驗室的伺服器上來做這件事情,因為伺服器快且容量大。
伺服器的目錄架構如圖:
我在yolov5-master下的data裡新建一個資料夾video,然後把我們下載的視訊放進來。不會下載視訊??這個我回頭總結一下,有一個命令列神器是annie,當然也可以在b站解析工具上下載並另存為。這裡放一個連結:
https://www.zhihu.com/question/290690588/answer/2005192819
這裡我把放在yolov5-master/data/video下:
在yolov5-master(相當於我電腦上的yolov5)資料夾下開啟終端
1 python detect.py --source data/video/123.mp4 2 3 # 實際上就是上面官方教程中的引數模型的套用 4 5 # 同樣,這個引數可以在原始碼的對應位置進行修改
然後開始跑:對每一幀圖片進行檢測
程式結果儲存在runs/detect/exp6
我們看一看效果。附一張截圖:
感覺海星,左側有一輛自行車被認成了摩托車hhhh。
02-3 實時檢測的detect
更有意義的莫過於實時檢測了,yolov5的優勢就正是實時檢測的準確性。這個待我下次研究研究,目前尚未實現,涉及將攝像頭資訊轉換成相關協議的流。
不過連線電腦本地的攝像頭還是很容易實現的。
1 python detect.py --source 0
看見攝像頭視訊流的實時檢測結果:
但是檢測效果不太好,可能是寢室裡光的影響,也有可能是隻出現了半張人像,以及手完美遮擋了部分手機。
同時一個手機出現了兩個同名框,如果細究的話是一些引數對於這種情景下預設設定的不夠合適。
02-4 一些引數的理解
02-4-1 --img 640
這個640是指畫素,是指傳入yolo框架用於處理的圖片大小,需注意我們傳出的圖片和原圖片大小是一致的。可知這裡這個引數設定了我們用yolo處理的圖片的規模。
最後會對畫出的框框進行再次縮放,標在原圖片上。
02-4-2 --conf 0.25
這個引數的意思就是當某個區域的置信度>0.25的時候,程式才相信這是一個目標,才會把它作為目標框出來。
02-4-3 --iou 0.45
當多個框有重合時,我們需要有一個閥值來控制:大於某個閥值的重合框就應該算為一個框,而小於就算作兩個框。
iou的計算公式就是交併比:兩框交/兩框並。預設閥值0.45。
02-4-4 --view-img
1 # 示例 2 python detect.py --view-img
這樣可以顯示正在檢測的圖片,這個就可以應用在視訊的檢測上,我們對視訊進行這個引數的設定,就可以實時看到視訊每一幀處理的情況。
1 # 具體引數 2 python detect.py --view-img --source data/video/123.mp4
02-4-5 --save-txt
把每一張原始檔圖片的目標檢測結果儲存為txt檔案。
02-4-6 --classes 0
對於目標檢測結果進行篩選,比如--classes 0就是隻保留第一個類別的目標,其他類別的目標都不框出來。
02-4-7 --agnostic-nms | --augment
對資料進行增強的兩種命令,使用它們會使我們的監測結果的值更優(即標註框的數字)。
02-4-8 --project | --name | --exist-ok
-
--project 把得到的結果存放到什麼目錄下;預設為runs/detect
-
--name 把結果儲存在目錄裡的哪個位置;預設exp。
-
--exist-ok 開啟這個引數(即為True),即每次訓練的結果exp不再預設增加1,會儲存在--name指定的位置。
03 訓練
03-1 /本地訓練
03-1-1 準備資料集
事實上因為coco128是官方例程,所以如果沒有下載128,執行train.py會自動下載。
但是為了我們的經驗更有普適性,我們把128下載到YOLO目錄下,與yolov5同級,我在這裡命名為datasets。大家可以通過我的vscode專案框架看一下這個結構:
03-1-2 執行train.py
(本地電腦)在YOLO/yolov5目錄下,開啟終端
python train.py --img 160 --batch 16 --cfg ./models/yolov5s.yaml --weights ''
注意這裡的--img引數預設是640,而我改小為160,是因為640我的視訊記憶體總是不夠:RuntimeError: CUDA out of memory.
我呼叫nvidia-smi可以看出確實是視訊記憶體不夠,而不是N卡呼叫比例的問題。所以我決定更改命令引數,犧牲一些效能,先把模型跑通。當然推薦的做法是修改batch-size,把改動得小一點。
PS:
關於batch-size的設定問題,根據交流獲知的情況,3060的顯示卡用的是8,普通顯示卡可以用4試一下。
0118補充:
下圖也可以看出我的小破gpu視訊記憶體極小,1G都不到..
所以擁有一個伺服器的使用權,多是一件美事阿
下面是執行的截圖:有一點點了解為啥別稱煉丹了。
圖中的Epoch299是訓練輪次,這個可以在原始碼中見到這個引數。
記憶裡跑了大概有快一個小時。結果出來了。放在YOLO/yolov5/runs/train/exp8裡
03-1-3 一些分析
我們看看我們的run資料夾下都產生了點什麼東西。
best.pt是選取的最優訓練輪次的網路模型引數;同理last.pt是最後一個訓練的輪次的網路模型引數。
hpy.yaml是訓練過程中的一些超引數,一些圖表圖片是對目標分佈、訓練效果的描述。
result.csv是訓練過程的一個記錄。
最後的train_batchxxxx.jpg是訓練圖片的拼接,我們在這裡可以看到訓練圖片的結果。
03-1-4 一些引數
A --weights | --cfg | --data
-
--weights
前面提到過,是選擇使用哪個已有模型來初始化前面提到過的引數,有5s、5x、5n等等,當然如果我們有自己的模型(比如上一部分提到的best.pt),可以在命令列中,把這個模型的路徑跟在後面,用自己的模型來賦值訓練過程。
我們的訓練一般上是 從頭訓練,所以這個引數一般初始化為空。
在程式中:
parser.add_argument('--weights', type=str, default='', help='initial weights path')
-
--cfg
config的縮寫,是關於模型的配置,存放在models/.yaml裡,相當於C語言的開局define,為每個模型固定了一些引數,指定這些會固定訓練的結構。
例如:(與上一個引數結合)
parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='model.yaml path')
如果與上一個引數結合來看,就是我們使用yolov5s的模型,訓練的初始化引數我們使用程式中給出的初始引數,不使用已經訓練好的引數作為初始引數。
-
--data
指定資料集,比如源程式是coco128資料集,就要引入它的設定引數檔案:
default=ROOT / 'data/coco128.yaml',
B --hyp | --epochs | batch-size | img-size
-
--hyp 使用哪一超引數進行初始化,我的資料夾下沒有,但是剛才訓練完成之後是產生了一個超引數文字,這個對於不同的資料集不同的訓練自然是不一樣的。
-
--epochs 訓練輪次/迭代次數
-
--batch-size 把多少資料打包成一個batch送進網路中
-
--img-size 設定圖片預設大小
C --rect | --resume
-
--rect 原本對於一個圖片的處理,程式會預設填充為正方形,那麼對於長條形的圖片來說,填充的無效資訊就很多,使用這個引數就可以對圖片進行最小填充,加快推理過程。
-
--resume 管理是否以最近訓練得到的模型為基礎進行繼續的訓練。預設是False,但是要讓其生效,要指定模型的位置。比如指定
runs/train/exp/weights/last.pt
會接著迭代之前的過程。
D --nosave | --notest | --noautoanchor
-
--nosave 預設為false,如果設定為true,就只保留最後一次的迭代結果
-
--notest 只對最後一個epoch進行測試
-
--noautoanchor 錨點,目標檢測模型包括有無錨點兩種型別。這個引數預設開啟(true)
E --evolve | --cache | --image-weights
-
--evolve 對引數進行進化,是尋找最優引數的一個方式。
-
--cache 是否對圖片進行快取,進行更好的訓練,預設未開啟。
-
--image-weights 對訓練效果不佳的圖片加一些權重
03-1-5 授人以漁 | 讀程式碼的一些技巧
A 原始碼跟蹤
如果對於一個引數進行分析,我們時常需要對一個引數在程式中起到的作用進行追蹤。
可以選中一個變數,然後Ctrl + F,pycharm和Vscode都會出現一個框,點選框右側的向上向下箭頭,就能實現自動跳轉。
引數傳入一個模組函式,我們可以右鍵檢視它的相關定義、引用、快速瀏覽等等,以瞭解具體的實現過程。
也可以按住Ctrl,點選這個函式,也會自動跳轉程式碼到原始碼相關處。
B 瀏覽查詢
看似困難實際上方便的一個做法是(比如YOLOv5),就在它的GIthub上的issues(https://github.com/ultralytics/yolov5/issues)進行查詢,在closed板塊檢視相關話題,檢視比較權威且經得起考驗的回答。
03-2 /雲端GPU
我是有本地GPU的,不過電腦是便攜本,GPU配置不高,視訊記憶體只有2G,所以高度依賴實驗室的伺服器,所以也想了解一下雲端GPU的事情。
但是我現在的ubuntu空間不多了,所以不想下載Google來訪問Colab(Colab本身也有不便之處),所以這件事情就先擱置,因為有實驗室的伺服器,暫時也用不著。可以回頭再探索,先做事情要緊。
04 不同模型(models)對比
現在github上的預訓練模型有如下這些(Github主頁上也有):
Model | size (pixels) | mAPval 0.5:0.95 | mAPval 0.5 | Speed CPU b1 (ms) | Speed V100 b1 (ms) | Speed V100 b32 (ms) | params (M) | FLOPs @640 (B) |
---|---|---|---|---|---|---|---|---|
640 | 28.4 | 46.0 | 45 | 6.3 | 0.6 | 1.9 | 4.5 | |
640 | 37.2 | 56.0 | 98 | 6.4 | 0.9 | 7.2 | 16.5 | |
640 | 45.2 | 63.9 | 224 | 8.2 | 1.7 | 21.2 | 49.0 | |
640 | 48.8 | 67.2 | 430 | 10.1 | 2.7 | 46.5 | 109.1 | |
640 | 50.7 | 68.9 | 766 | 12.1 | 4.8 | 86.7 | 205.7 | |
1280 | 34.0 | 50.7 | 153 | 8.1 | 2.1 | 3.2 | 4.6 | |
1280 | 44.5 | 63.0 | 385 | 8.2 | 3.6 | 12.6 | 16.8 | |
1280 | 51.0 | 69.0 | 887 | 11.1 | 6.8 | 35.7 | 50.0 | |
1280 | 53.6 | 71.6 | 1784 | 15.8 | 10.5 | 76.7 | 111.4 | |
1280 1536 | 54.7 55.4 | 72.4 72.3 | 3136 - | 26.2 |
可見越往下,模型越複雜,花費時間會相對較多,但是效果相對會比較好,表格裡面右側就是一些指標,可以看出效果會好一些。