本來就想着是對自己第一次跑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 |
可見越往下,模型越復雜,花費時間會相對較多,但是效果相對會比較好,表格里面右側就是一些指標,可以看出效果會好一些。