北科資工二多媒體技術與應用 第七次團隊作業 - 使用 google colab 與 yolo 訓練後進行圖像辨識

筆記說明

此筆記用途在於台北科技大學資訊工程系大二下多媒體技術與應用作業紀錄
並非所有人都適用,部分對我而言稍加容易的內容並不會寫在此內。
這是學習後心得的筆記,可能不太適用會未來的學生

由於我沒有學習過裡面的理論,因此這是資工大二學生透過網路與自身理解的筆記,學習價值並不高、且可能擁有大量錯誤。

訓練的資料是助教同意讓我們在這堂課做使用,並非同意我將訓練資料拿來散步,因此不將訓練資料生出來。

專案說明

如紅色線條上方說明文字

此文章的目的是紀錄如何透過 yolo 與 google colab 來進行圖像辨識

yolo 說明

yolo 是一種需要高度運算,但在建立模型時則不需要大量的圖像背景知識就可以順利完成,yolo 擁有著高辨識度,且只要一開始的辨識物件訓練有做好,那 yolo 能夠辨識每一張圖片中的物件,是個非常方便的圖像辨識。

安裝 labelIMG 在 Windows OS、VS code

labelIMG 介紹

labelIMG 是 open source 軟體,專用於 yolo 的圖像標記,也就是 yolo 所需要的訓練集。

下載連結 windows 請安裝 zip
安裝的一些操作手冊

下面會說明如何在 window 安裝,以及一些說明,依序是

  • 安裝 labelImg
  • 產生訓練集
  • 透過 labelImg 標記影像
  • 使用 google colab 進行圖像訓練
  • 完美結果

如果需要跳至其特定章節,可以點選右邊,右邊有針對每一個大項目進行連結(錨點)

windows 環境安裝 labelImg

  • 先確認 cmd 環境中是否有安裝 python、pip
    如果沒有可以點擊此教學說明
  • 在 vscode 中安裝 python
  • python 安裝 pyqt5
    安裝語法 pip install PyQt5
  • python 安裝 lxml
    安裝語法 pip install lxml
  • 再來我們要把 pyqt5 加入 windows 的環境變數,順便確認 python 是否在 windows 環境變數,沒有就加入
    • 點擊 控制台 -> 系統及安全性 -> 系統 -> 進階系統設定 -> 點擊 -> 進階 -> 環境變數,最後畫面應該如下

    • 點擊系統變數 -> path -> 編輯

    • 找出存在 python.exe 的資料夾路徑並加入環境變數,如果曾經有則不需要,紅色線條為 python.exe 資料夾路徑

    • 找出 pyqt5 的資料夾路徑並加入環境變數,通常應該在 python.exe 資料夾中的 script 資料夾,紅色線條為 pyqt5 資料夾路徑

  • 再來我們需要編譯
    編譯語法如下 For pyqt5, pyrcc5 -o libs/resources.py resources.qrc
  • 我們在 VScode 打開 labelImg.py,直接執行 F5,
  • 如果可以成功,畫面如下

產生訓練集

由於助教給我們的影片有四部且每部都是長達 20s 的影片,於是我將前 3 部影片視為訓練集,將影片每幀擷取下來,擷取後的每張照片就可以當作我們的測試集。

因此我們寫一個程式碼,每 10 幀就擷取一張圖片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import cv2
import os

path = "D:/NTUT/大二下/多媒體技術與應用/hw07/helmet/"
os.chdir(path) #設定要讀取圖片的資料夾路徑

fname = "helmet3.mp4"
video_capture = cv2.VideoCapture(fname) #讀取影片

ret = False #ret 判斷這幀是否有圖片
if video_capture.isOpened(): #判斷 video_capture 是否有被打開
ret, frame = video_capture.read() # ret 回傳這一幀是否有圖片,fname 為圖片本體
else:
print("此影片正在被使用中!")
print("影片路徑:", os.getcwd(), "\\", fname)

timeFormat = 10 #每 10 幀取一張
timeCount = 1 #紀錄現在讀到哪一幀
pictureCount = 1 #紀錄輸出第幾張圖片
while ret: #如果上幀有圖片
ret, frame = video_capture.read() #這幀再讀一次
if not ret: break #如果這幀沒有就離開迴圈

if(timeCount % timeFormat == 0): #已經是第 10 幀就輸出圖片
picName = ".\\images\\" + "helmet3_" + str(pictureCount) + ".jpg"
cv2.imwrite(picName, frame)
print("影片路徑:", picName, sep='')

pictureCount += 1 #紀錄圖片 +1
timeCount = 0 #重新計算
timeCount += 1
#cv2.waitKey(1)

video_capture.release() #python opencv 不再讀取此圖片

透過這種方式就能夠讓資料夾裡面出現大量圖片了!

如何使用 labelImg

  • 點擊 open dir,之後應該會出現圖片,右下角的 file list 也會有大量圖片
  • 再來我們可以點擊 Next Image, Prev Image 而到下一張圖片或是前一張圖片
  • 再來將此圖示點至 yolo 模式

  • 之後點擊 Create\nReactBox,選取想要辨識的畫面

  • 然後輸入你定義此畫面的 label,記住,如果要進行圖像辨識那理論上相同 label 的圖片至少要 20 個,且要不同張。
  • 持續你的人工辨識,找到你的耐心。
  • 經過一段痛苦的 label 後

完成

  • 完成後資料夾內應該要有一個 class.txt、一堆圖片和圖片名子相同,但檔名是 txt 的資料
  • 其中標記的 txt 必須與圖片在同個位置

  • 隨意點擊某一個 txt 的資料,內容大致如下
    1
    2
    3
    4
    5
    16 0.567578 0.327778 0.146094 0.563889
    16 0.468750 0.211806 0.095312 0.420833
    15 0.777344 0.790972 0.328125 0.418056

    #資料依序是 class(根據 class.txt 的行數) ,x 座標, y 座標, x 長度, y 長度
  • class.txt 則是所有你定義的 label 名稱

使用 google colab 來進行圖像辨識

google colab 提供一個環境讓你能夠使用 google 資源來圖像辨識,且 google 的顯卡、處理器規格都是屬於非常棒的規格,因此如果只是簡單的事情我都建議用 google colab 來做。

但 google colab 有一些限制

  • 太久沒有使用 google colab 會被強制退出
  • 訓練模型最多只能夠使用 12 小時

一開始的環境處理

  • 先在 google 雲端硬碟建立一個資料夾,以下的資料夾舉例會是 /content/drive/MyDrive/NTUT/'大二下- 資工多媒體技術與應用/yolo'
  • 將你透過 labelImg 完成 label 標記的資料夾壓縮後放入雲端硬碟,在這邊我的資料夾名稱為 dataset
  • 網路上下載 yolov4.conv.137 檔案,之後放入雲端硬碟,此檔案是我們在進行圖像辨識時,用於訓練的必備檔案。
  • 將我們手工標記好的 label 資料夾中的 class.txt rename 為 obj.names,上傳至 google 雲端硬碟

使用 google colab 與進行 yolo 訓練

接下來我們要使用 google colab 來進行圖像辨識,內容會比較麻煩,因為必須與本機和雲端硬碟交互操作。

  • 根據我們原本建立的 google 雲端硬碟資料夾,對空白處右鍵 -> 更多 -> 連結我的應用程式 -> 搜尋 colab

  • 建立一個 google colab 與進行 yolo 訓練
    • 以下全部都是在 google colab 運行
    • 開啟 google GPU 運算
    • 我們必須允許 colab 對我們的雲端硬碟操作,因此需要勾選;也許會需要你同意 google colab 使用

    • !git clone https://github.com/AlexeyAB/darknet
    • %cd darknet/
    • 接下來我們先找 /content/darknet/Makefile 進行修改,修改內容如下
      • 開啟 GPU 加速,將 GPU 設定改為 1
      • OPENCV 開啟,才可讀取影片、影像,將 OPENCV = 1
      • CUDNN = 1,用於加速深度學習框架
      • CUDNN_HALF = 1,加速偵測物件
      • 示意圖如下

    • 完成後,我們進行 !make
    • 再來我們要去修改 yolov4-custom.cfg
      • 選擇資料夾 /content/darknet/cfg/yolov4-custom.cfg
      • 我們必須將裡面的 filter 參數修改成 \((n+5)*3\),n 為總共有多少 class,並且必須是數字,不可以是公式(類似於 css)
      • class 則必須改成我們標記的 class 數字
      • 上面講的兩點只在 yolov4-custom.cfg 的 963、970、1051、1058、1139、1146 修改
      • 如果接下來在下方訓練時,有遇到 out of memory 問題時,必須改為 subdivisions = 32 or 64

      • max_batches 則是資料集 class 個數乘以 2000

      • steps 則是 max_batches 的 80% and 90%

      • 再來我們將這份修改好的檔案 copy 下來到我們的電腦上,取名為 yolov4-custom.cfg

      • 再來我們在將 yolov4-custom.cfg 上傳至雲端硬碟上,位置為 /content/drive/MyDrive/NTUT/'大二下- 資工多媒體技術與應用'/yolo/
    • 再來我們將 /content/drive/MyDrive/NTUT/'大二下- 資工多媒體技術與應用'/yolo/ google 雲端硬碟資料夾做一個 link,讓我們只要輸入此名詞就可以成功 link 到此資料夾
      1
      2
      !ln -f -s /content/drive/MyDrive/NTUT/'大二下- 資工多媒體技術與應用'/yolo /drive
      !ls /drive
    • 再來我們要將上傳的 dataset.zip 解壓縮,並且放入 yolo/ 資料夾中
      1
      !unzip /drive/dataset.zip -d /drive
    • 將所有圖片收錄到 train.txt、valid.txt
      由於我們是要讓 google colab 來幫我們做圖像辨識,因此我們必須要產生一個檔案,讓 google coloab 在訓練時知道有哪些資料需要訓練。
      • 其中
        • train.txt 為訓練集資料
        • valid.txt 為測試集資料
        • 如果沒有測試集資料,那我們直接將 train.txt 資料 copy 一份至 valid.txt 即可。
      • train.txt 裡面要收錄著我們全部的測試集圖片,並且路徑必須是 google 雲端上絕對路徑
      • 我們可以寫一份程式來快速產生出所有的訓練集圖片資訊
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        import os 

        path = "D:/NTUT/大二下/多媒體技術與應用/hw07/yolo" #讀本機資料夾路徑
        output_path = "/drive/yolo/" #google drive 絕對路徑,支援捷徑
        images_file = list()
        os.chdir(os.path.join(path, "dataset")) # dataset 為圖片訓練集

        for fname in os.listdir(os.getcwd()): #不斷讀入資料
        if fname.endswith(".jpg"): #必須是 jpg
        images_file.append("dataset/" + fname)

        os.chdir("..") #回到上一層
        with open("train.txt", "w") as output: #打開 train.txt
        for image in images_file: #不斷讀入 images_file 並且將路徑 + 圖片輸入至 train.txt
        output.write(output_path + image)
        output.write("\n")
        output.close()
        os.chdir("..")
    • 再來我們設定 obj.data
      • 其中所有的路徑都必須是 google driver 的絕對路徑
      • class 為 label 總共有幾個
      • train 為訓練集資料位置
      • valid 為測試集資料位置
      • names 為這些 label 的名字
      • backup 為訓練好的模型輸出位置
      • 語法如下
        1
        2
        3
        4
        5
        classes = 17
        train = /drive/yolo/helmet/train.txt
        valid = /drive/yolo/helmet/valid.txt
        names = /drive/yolo/helmet/obj.names
        backup = /drive/yolo/helmet/
      • 再來我們在將 obj.data 上傳至雲端硬碟上,位置為 /content/drive/MyDrive/NTUT/'大二下- 資工多媒體技術與應用'/yolo/
    • 我們這邊檢查是否路徑是否設對,如果沒有設對可以回去進行檢查
      • 語法 %cat /drive/obj.data
      • 會輸出的畫面必須是

    • 再來我們就來進行 yolo 模型訓練拉,第一個是 obj.data、第二個是 cfg 設定、第三個是我們上傳的權重,基本上訓練模型時間一定要 1 小時以上,因此我們需要將,語法如下
      1
      2
      3
      4
      5
      6
      !./darknet detector train /drive/obj.data \
      /drive/yolov4-custom.cfg \
      /drive/yolov4.conv.137 -dont_show

      #之後如果再跑此模型有問題,下方有附註我有遇到的問題。
      #可以看右邊標題列中的,訓練模型遇到的錯誤問題
    • 可以檢查 /content/drive/MyDrive/NTUT/'大二下- 資工多媒體技術與應用'/yolo/ 是否有 yolov4-custom_last.weights 此檔案,如果有就表示已經訓練完成了!
    • 進行 yolo 辨識
      1
      2
      3
      4
      5
      6
      7
      8
      !./darknet detector demo /drive/obj.data  \
      /drive/yolov4-custom.cfg \
      /drive/yolov4-custom_last.weights \
      -dont_show /drive/test.mp4 \
      -out_filename /drive/test_out.mp4

      #之後如果再跑此模型有問題,下方有附註我有遇到的問題。
      #可以看右邊標題列中的,辨識模型遇到的錯誤問題
    • 如果最後 YOLO 辨識完有輸出此圖就表示成功了!

  • 如果需要我的 google colab 這邊開放給大家,但是跟我的上面教學不太一樣,請斟酌使用

一些範例影片

如果可以被成功輸出,那應該會出現類似這樣的影片

訓練模型遇到的錯誤問題

  • Can't open label file,圖片資訊如下

    • 解決方法是必須檢查你的每一個路徑是否有設錯的可能性
  • out of memory,已經有將 subdivisions 設定為 32 or 64
    • 調整 width、height,個人建議為 416

辨識模型遇到的錯誤問題

  • 使用別人訓練好的 yolov4-custom_last.weights,但卻一直出錯
    檢查別人的 yolov4-custom.cfg 是否與你相同
  • darknet: ./src/utils.c:331: error: Assertion '0' failed,圖片資訊如下

    • 這有很多種可能的解決方式,我的解決方式是 調整 width、height,個人建議為 416

其他問題

  • 在設定路徑的捷徑後,透過 ls 此捷徑卻沒有辦法輸出正確的當前路徑下的所有檔案內容,圖片資訊如下
    • 錯誤的捷徑

    • 正確的捷徑

    • 你必須檢查你當前目錄的資料夾 !ls 中的檔案名字是否有與你設定的捷徑名字相同
  • 當你在訓練模型後一直告訴你 gpu isn't used
    必須回去重新設定 /content/darknet/Makefile,之後進行 !make

心得

天啊,這真的好難….。 我根本就是 google colab 踩雷大師,我一開始還以為 yolov4-costom.cfg 支持運算,害我在每一個 filiter 都放入 \(5 + n)*3\) QQ。

google colab 每次都會把我登出,我就必須要重新登入,每一次重新登入就必須要重新設定一次 makefile,我常常會不小心就直接 make 而沒修改 makefile…。

為甚麼設定捷徑運氣那麼不好,剛好設定與 ls 資料夾中相同名稱的捷徑導致衝突!ಥ⌣ಥ

助教的 ppt 都沒有跟我說 vaild.txt and yolov4.conv.137 是拿來幹嘛的QQ,害我在旁邊摸索好久。

為甚麼 google 的路徑這麼難設定,我一直設定失敗,中文是不是有毒QQ,在訓練模型的時候加入中文路徑都不可以…,但是在捷徑的時候設定中文路徑就可以過!

雖然我有很多東西想要抱怨的,不過我還是很謝謝助教可以出這個題目讓我學習到這麼多知識,看看我打這麼多訊息就知道了XD。

也要謝謝陳力瑋一直不厭其煩的教導我,幫我排除困難,還給我他的金魚 weights 讓我做測試,要是這次沒有他,我看我弄個 1 個禮拜都弄不完八…。
新手入行總是特別辛苦嘛,有個師父帶非常感動QQQQ。

要是沒有力瑋在旁邊提點我要怎麼做,我可能做一做就生氣了八..。

我覺得我這次的圖像辨識沒有到很精準,主要原因是因為我在 labelImg 時是圈出每個人的輪廓,而非圈出頭 + 帽子,在我訓練的過程中,我將有些只有下半身的人也視為沒戴帽子的人,也許是這個原因才讓 yolo 在辨識中畫圖特別凌亂八。

像這樣子,我也會視為是一個沒戴帽子的人

最後最後,我想要說 labelImg 能不能聰明一點啦QQQQQ,我不想要一直去用人工辨識去辨識一大堆圖片拉QQQQ。
整個手都點到酸了…,才發現自己只有辨識 60 張。

有時候都想說還是我請個國中生給他 168,讓他幫我做。資本主義的力量

總之,謝謝助教、力瑋來讓我學會這份專案。

參考來源

Installing PyQt5 on windows with pip by stack overflow
python编程:使用opencv按一定间隔截取视频帧 by CSDN 张某人ER
[darknet yolov4训练遭遇 darknet: ./src/utils.c:326: error: Assertion `0‘ failed. by CSDN 江湖夜雨十年灯。。。](https://blog.csdn.net/xgd2016/article/details/107716702)
YOLO 簡單訓練自己的資料集 by Titi
yolov4 custom object detection error during training by stackoverflow

  • 版權聲明: 本部落格所有文章除有特別聲明外,均採用 Apache License 2.0 許可協議。轉載請註明出處!
  • © 2020-2024 John Doe
  • Powered by Hexo Theme Ayer
  • PV: UV: