北科資工二多媒體技術與應用 期末報告 - 物件辨識,使用 colab 與 yolov4 實作

筆記說明

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

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

訓練的資料從 KITTI 資料集產生出來,後面會留下的成果。

如果需要點選某些特定章節,請善用右上的章節列

專案說明

如紅色線條上方說明文字





下載資料

根據專案要求先前往此網站獲得資料集,你會收到一封驗證信,點擊驗證信網址後就會自動下載,由於我們使用 colab 來進行訓練,因此就不需要下載到本地。

保留此網址

開啟 colab,並且將 KITTI 資料下載到雲端硬碟

前情概要,如果不熟悉 colab 可以看這篇網站的解說,這邊我們不會對 colab 多做介紹,已完成專案需求為主。

以下的 colab 可能都有路徑問題,因為 colab 在久沒有使用時,會自動斷開,因此路徑會有混亂的問題,對每位讀者非常抱歉。

必要條件與須知

  • 先將 gpu 功能開啟
  • colab 在處理大量資料時會有時間差,也就是你在 colab 已經刪除這個資料,但在 google drive 還沒看到資料被刪除,這時必須耐心等待。我也是這樣撐過來的

google drive 與 colab 串接

輸入以下指令

1
2
from google.colab import drive
drive.mount('/content/drive')

再來我們設定一個捷逕,方便我們之後在操作時可以直接透過此捷徑迅速到我們的物件辨識專區

1
2
!ln -f -s /content/drive/MyDrive/NTUT/'大二下- 資工多媒體技術與應用'/'期末報告-物件辨識' /drive  #這是我資料夾的路徑
!ls /drive

再來我們將 KITTI 下載到雲端硬碟

  • 在專案說明中有提到我們必須下載三個檔案,其中有兩個檔案有驗證信、一個可以直接下載,我們將這三個網址都複製起來,並透過 colab 直接進行下載。
  • 下面我只列出一個網址,但實際上我們並須下載三個網址。
1
2
3
4
5
%cd /drive/ #將資料存放到物件辨識專區
!pwd
!wget https://s3.eu-central-1.amazonaws.com/avg-kitti/data_object_image_2.zip #大概有 7800 多張照片
!wget https://s3.eu-central-1.amazonaws.com/avg-kitti/data_object_label_2.zip
!wget https://s3.eu-central-1.amazonaws.com/avg-kitti/devkit_object.zip

google colab 的網速真的神,我的爛到一個不行…。下載/上傳 16/3 mpbs 好慘QQ。

再來我們將這三個檔案進行解壓縮

1
2
3
4
#可能會有路徑問題,請大家注意,如果已在 drive 內,就不需要
!unzip /drive/data_object_image_2.zip -d /drive/training
!unzip /drive/data_object_label_2.zip -d /drive/training
!unzip /drive/devkit_object.zip -d /drive/training

檢查下是否都有成功被解壓縮到正確位置

1
2
%cat ./label/000000.txt
#如果有成功輸出 3 0.622194 0.609351 0.080335 0.44573,表示成功

colab 下載 darknet

請按照這邊的步驟,即可成功,但有幾點需要特別注意。

  • 必須先將我們的雲端硬碟更改權限為可以讀出、寫入
    1
    2
    #必須先做,第一步非常重要! 
    !chmod +x ./ #讓我的雲端硬碟可被寫入
  • 下載 darknet
    1
    2
    3
    #抓預訓練模型
    %cd ./darknet/
    !wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.conv.137
  • Makefile 修改 4 點,之後進行 make
  • 修改 /content/darknet/cfg/yolov4-custom.cfg
    其中讀者可以從 readme.txt 得知有 9 個 class。

將 KITTI 資料集 label 轉換為 yolo 格式

專案說明有提到,KITTI 資料集的 label 並不是 yolo 格式,因此要進行轉換。
轉換程式碼如下,謝謝林紀瑋的編寫。

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
35
36
37
38
39
40
41
42
import os 
import numpy as np

path = "/drive/training"
images_file = list()
os.chdir(os.path.join(path, "label")) # KITTI 標籤位置
print(os.getcwd())

for fname in os.listdir(os.getcwd()):
ID = ""
x = 0
y = 0
width = 0
height = 0
f = open(fname)
for line in f.readlines():
s = line.split(' ')
ID = (s[0])
x = ((float(s[4])+float(s[6]))/2) #x
y = ((float(s[5])+float(s[7]))/2) #y
width = (float(s[6]) -float(s[4])) #width
height = (float(s[7]) -float(s[5])) #height

print(ID)
print(x)
print(y)
print(width)
print(height)
f.close()

##path = 'output.txt'
##f = open(path, 'w')
##lines = ['Hello World\n', '123', '456\n', '789\n']
##f.writelines(lines)
##f.close()

f = open(fname,'w')
f.write(ID+'\t')
f.write(str(x)+'\t')
f.write(str(y)+'\t')
f.write(str(width)+'\t')
f.write(str(height)+'\n')

將 yolo 格式的資料放到圖片的資料夾中

這裡我們直接使用 linux 語法來操作

1
2
3
4
5
6
#將 label 資料放到圖片位置,透過正規表達式來處理
!cp /drive/training/label/*.txt /drive/training/image

#檢查是否都有成功的將資料集標籤放到圖片資料夾下
%cd /drive/training/image/
!ls

訓練前處理

根據專案說明,我們訓練的資料至少有 5000 張、其他為驗證集,因此我們寫一個 py 程式來將檔名 > 5500 的圖片放到另一資料夾與訓練集分開

驗證集資料路徑我們使用 /drive/testing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#移動 5000 以上的資料至 testing 
#%pwd
import os
import shutil
path = "/drive/testing/"
files = list()
os.chdir(os.path.join(path, "label"))
print(os.getcwd())

for fname in os.listdir(os.getcwd()):
num = fname.split(".")[0] #判斷檔名是不是為資料集中的圖片,資料集中的圖片都已數字編號完成
if(not num.isdigit()):
continue
move_path = "/drive/testing/image/"
if int(num) > 5500: #移動路徑
shutil.move(os.path.join(os.getcwd(), fname), os.path.join(move_path, fname))
print(os.path.join(move_path), fname)

正確輸出時會產生這樣的資料

將訓練集資料、驗證集資料收錄到 train.txt, valid.txt

前情概要,如果不熟悉 colab 可以看這篇網站的解說,這邊我們不會對 colab 多做介紹,已完成專案需求為主。

直接寫 py 來根據資料夾內容圖片收錄至 train.txt, valid.txt,因此下面這份程式要被執行兩次分別是 train.txt, valid.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import os 
#path = "/drive/training" #訓練集路徑
path = "/drive/testing" #驗證集路徑
images_file = list()
os.chdir(os.path.join(path, "image"))
print(os.getcwd())

for fname in os.listdir(os.getcwd()):
if fname.endswith(".png"):
images_file.append("/image/" + fname)
print(fname)

os.chdir("..")
with open("train.txt", "w") as output: #驗證集則使用 valid.txt
for image in images_file:
output.write(path + image)
output.write('\n')
output.close()

檢查 train.txt, valid.txt 是否有成功被收錄

1
2
%cat /drive/training/train.txt
%cat /drive/testing/valid.txt

再來在本地產生兩個檔案,並放入 training 資料夾內

obj.data

1
2
3
4
5
classes = 9
train = /drive/training/train.txt
valid = /drive/testing/train.txt
names = /drive/training/obj.names
backup = /drive/training

obj.names

1
2
3
4
5
6
7
8
9
Car
Van
Truck
Pedestrian
Person_sitting
Cyclist
Tram
Misc
DontCare

訓練模型

我們就來訓練模型

1
2
3
4
5
#初次訓練模型
%cd ./darknet
!./darknet detector train /drive/training/obj.data \
/drive/darknet/cfg/yolov4-custom.cfg \
/drive/darknet/yolov4.conv.137 -dont_show

ERROR: Can't open label file. (This can be normal only if you use MSCOCO): /drive/training/image_2/001318.txt

表示你的路徑位置並不正確,需要在檢查

當 colab 因為使用過久而中斷後,再次進行訓練

記住,如果訓練過久中斷,你必須重新連接 google drive 並設置捷徑,並且讓雲端硬碟可讓 colab 寫入

1
2
3
4
5
%cd /drive/
#%cd
%ls
%pwd
!chmod 755 -R ./ #讓我的雲端硬碟可被寫入

再次進行訓練模型時則使用此語法

1
2
3
4
5
#不斷訓練模型
%cd ./darknet
!./darknet detector train /drive/training/obj.data \
/drive/darknet/cfg/yolov4-custom.cfg \
/drive/training/yolov4-custom_last.weights -dont_show

訓練完成後,您會看到有一個檔名叫做 yolov4-custom_final.weights 這個就是完整的訓練模型了。之後都靠她來辨識拉!

到底還要訓練多久?

有看到用紅筆畫底線的數字嗎? 那個是 max_batches 的數字,只要訓練到 max_batches 就會停止了。如果希望可以訓練的快點就將 yolov4-custom.cfg max_batches 修改。

使用訓練好的模型來辨識圖片

1
2
3
4
5
6
7
%cd ../
!./darknet/darknet detector test /drive/training/obj.data \
/drive/darknet/cfg/yolov4-custom.cfg \
/drive/training/yolov4-custom_final.weights \
-dont_show /drive/testing/image/005510.png \
-out_filename /drive/testing/image/005510.png \
#隨意一張照片,沒有要求

ERROR: 如果辨識出來的圖片沒有標籤文字怎麼辦? 如下圖所示

很不幸的,你必須自己去修改程式碼。
路徑為 darknet > src > image.c:276,必須將他修改到符合你的雲端硬碟檔案路徑位置。
也就是說你的 darknet > data > labels 資料夾這邊不更動,理論上是沒有吃到你雲端硬碟的路徑,因此將 darknet 前面改成你的雲端硬碟路徑即可。

示意如下:

當你修改完成後,請記住需要再 !make darknet

QUESTION: 我可以讓輸出的圖片到我指定的資料夾嗎?

當然沒問題,但是很麻煩QQ。 這是我跟林紀瑋學長一起嘗試用出來的。
我用圖片來表示那些地方要修改,變數命名很髒就不要笑了XD。

路徑為 darknet > src > detector.c:1693 開始

QUESTION: 我想要大量產生透過 yolo 辨識後的圖片,該怎麼辦呢?

我們可以將想要透過 yolo 辨識的圖片放到同一個資料夾中,然後使用 linux 語法來寫迴圈。
我之前有使用過 py 來操作,但發現 colab 並沒有辦法使用 os package,因此使用 linux 語法解決。

1
2
3
4
5
!for i in {6111..7218}; do ./darknet/darknet detector test  /drive/training/obj.data \
/drive/darknet/cfg/yolov4-custom.cfg \
/drive/training/yolov4-custom_final.weights \
-dont_show /drive/testing/image/00$i.png \
-out_filename /drive/testing/image/00$i.png \ ;done

利用 yolo 訓練完的模型來對驗證集做驗證,看看效果如何

1
2
3
4
5
6
7
%cd ./darknet/
!./darknet detector map /drive/training/obj.data \
/drive/darknet/cfg/yolov4-custom.cfg \
/drive/training/yolov4-custom_last.weights \
-dont_show /drive/testing/image_2/007007.png \
-out_filename /drive/testing/image_2/007007.png >> pic_map.log
#將結果存到 pic_map.log

結果如下
其中 TP 為正確數、FP 為錯誤數
average IOU 位置準確率為 68.07%,並不算很完美,但算是尚可的表現。
準確率達到 0.88,相當優秀。

使用訓練好的模型來辨識圖片有哪些物件,並且將驗證集的圖片都進行辨識。

此資料夾將所有的驗證集圖片都進行辨識,希望可以幫助到大家

參考連結

Can’t open label file. (This can be normal only if you use MSCOCO) #1726 by github
Moving files in Google Colab by stackoverflow
/bin/bash: ./darknet: Permission denied by stackoverflow
建立自己的YOLO辨識模型 – 以柑橘辨識為例 by CH.Tseng
複製目錄(cp 指令) by IBM
files in colab is not in sync with google drive by github
【機器學習】利用Google Colab訓練YOLO by MAKERPRO
YOLOv3批量测试图片并保存在自定义文件夹下 by CSDN
YOLO (Darknet): How to change the output file directory of a detection (predictions.jpg)? by stackoverflow
darknet评测自己的数据集 recall map计算 by 華為雲
How to run YOLO on multiple images and save predictions to a txt file by stackoverflow
Cannot load image “data/labels/*.png” by stackoverflow

心得

真的是好累壓,上多媒體課程學習到了好多東西。老實講,很喜歡這堂課。這堂課讓我學習到了好多事務。而且也讓我願意一個字一個字慢慢打,來整理我所學習到的事物。

從原本討厭 yolo、colab 到慢慢可以接受,老實講心境真的變蠻多的XDDDD,果然上手了就有差,還沒突破撞牆期之前的話都不能算數阿XDD。

總之,希望自己未來也能夠像現在一樣努力,整理著自己學習的回憶。

願未來一切安好,我努力成功。

也謝謝組員林紀瑋、郭梓琳一路的陪伴,讓我這個外系生不需要自己一個人扛起全部,不然每次修外系課都很怕遇到雷隊友呢!

專案報告 ppt

我將專案報告 ppt 分享給大家,希望大家也能從我的 blog 中學到!
多媒體技術與應用-期末報告

我的 colab

我在這邊共享我的 colab 副本,開放檢視權,讓讀者可以看到一些我可能文字敘述不好的地方

yolov5 in colab

其中在我學習的過程中,班上的好朋友力瑋提醒我說現在 yolov5 比 yolov4 更簡單,讀者們也可以去試試看。
YOLOv5 Tutorial - Colaboratory

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