計算機視覺3-> yolov5目標檢測1 |從入門到出土

climerecho發表於2022-01-20

本來就想著是對自己第一次跑yolov5的coco128的一個記錄,沒想到現在準備總結一下的時候,一方面是繼續學習了一些,另一方面是學長的一些任務的要求,挖出了更多的東西,所以把名字改為了“從入門到出土“。

00 GitHub訪問加速

首先我們要把yolov5框架從GitHub上拉下來,國內如果要快速訪問GitHub的話呢,需要把Github的相關域名寫入Hosts檔案。

00-1 修改hosts的原理

  1. hosts檔案原理

    hosts檔案是一個用於儲存計算機網路中各節點資訊的計算機檔案。這個檔案負責將主機名對映到相應的IP地址。hosts檔案通常用於補充或取代網路中DNS的功能。

    和DNS不同的是,計算機的使用者可以直接對hosts檔案進行控制。

    關於DNS解析,我在CTF的學習中有所記錄

    https://www.cnblogs.com/Roboduster/p/15575207.html 00-03瀏覽器。

  2. 作用過程

    當我們在瀏覽器中輸入一個需要登入的網址時,系統會先檢查系自己的Hosts檔案中是否有這個域名和IP的對映關係。

    如果有,則直接訪問這個IP地址指定的網路位置;

    如果沒有, 再向已知的DNS(Domain Name System,域名系統)伺服器提出域名解析請求。

    也就是說Hosts的IP解析優先順序比DNS解析要高。

  3. 我們把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

  1. --project 把得到的結果存放到什麼目錄下;預設為runs/detect

  2. --name 把結果儲存在目錄裡的哪個位置;預設exp。

  3. --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主頁上也有):

Modelsize (pixels)mAPval 0.5:0.95mAPval 0.5Speed CPU b1 (ms)Speed V100 b1 (ms)Speed V100 b32 (ms)params (M)FLOPs @640 (B)
YOLOv5n 640 28.4 46.0 45 6.3 0.6 1.9 4.5
YOLOv5s 640 37.2 56.0 98 6.4 0.9 7.2 16.5
YOLOv5m 640 45.2 63.9 224 8.2 1.7 21.2 49.0
YOLOv5l 640 48.8 67.2 430 10.1 2.7 46.5 109.1
YOLOv5x 640 50.7 68.9 766 12.1 4.8 86.7 205.7
YOLOv5n6 1280 34.0 50.7 153 8.1 2.1 3.2 4.6
YOLOv5s6 1280 44.5 63.0 385 8.2 3.6 12.6 16.8
YOLOv5m6 1280 51.0 69.0 887 11.1 6.8 35.7 50.0
YOLOv5l6 1280 53.6 71.6 1784 15.8 10.5 76.7 111.4
YOLOv5x6 + TTA 1280 1536 54.7 55.4 72.4 72.3 3136 - 26.2      

可見越往下,模型越複雜,花費時間會相對較多,但是效果相對會比較好,表格裡面右側就是一些指標,可以看出效果會好一些。



相關文章