COCO Dataset - 使用 Faster RCNN + MobileNet 進行 Object Detection
前言
最近選了一堂AI課程,這是第四個作業,主要教授內容為以下主題:
- Download Coco dataset
- User pre-trained version of Faster R-CNN to predict the bounding box
- Calculate IoU
作業要求
- 下載coco資料集:Download the file „2017 Val images [5/1GB]“ and „ 2017 Train/Val annotations [241MB]“ from
the Coco page. You can use the library pycocotools to load them into your notebook. - 隨機從dataset選擇十張:Randomly select 10 images from this dataset.
- 使用pre-trained模型FasterR-CNN預測bbox:Use a pre-trained version of Faster R-CNN (Resnet50 backbone) to predict the bounding box
of objects on the 10 images. Only keep regions that have a score > 0.8. - 把模型跟解答視覺化擺在一起:Visualize the predicted bounding boxes and label together with the ground truth bounding
boxes and label. Show all 10 pairs of images side by side in the jupyter notebook. - 使用另一個pre-trained模型Mobilnet:Repeat the steps from above using a Mobilenet backbone for the Faster R-CNN.
- 計算IoU比較模型:Wich backbone delivers the better results? Calculate the IoU for both approaches.
Task 1: 下載coco資料集
Task 1
- 下載coco資料集:Download the file „2017 Val images [5/1GB]“ and „ 2017 Train/Val annotations [241MB]“ from the Coco page. You can use the library pycocotools to load them into your notebook.
可以看照這個說明進行下載:https://jason-chen-1992.weebly.com/home/coco-dataset
1 | . |
- 去官網下載這兩個檔案如圖一
- 下載後資料夾解壓縮會如上面的檔案結構
Task 2: 隨機選十張
Task 2
2. 隨機從dataset選擇十張:Randomly select 10 images from this dataset.
這邊我們主要會做幾件事情:
- 匯入必要套件
- 設定coco api,讓他可以引入我們的資料集的相關資訊,像是預測框位置、標籤位置、圖片資訊
- 視覺化圖片並且進行標示
- 隨機選十個圖片
我們先匯入必要的套件
1 |
|
設定coco api
coco 有提供獲取資料集的 api,只要給他json檔案,我們就可以輕易的我們可以透過這個 api 來根據json檔案,獲取我們需要的資料,像是圖片、標籤、預測框等等。
1 | # 指定資料集位置 |
結果如下
1 | Annotation file: ../../Data/Coco/annotations/instances_val2017.json |
標註視覺化
為了確保會使用coco所提供的API這邊有一個練習,主要學習以下內容:
- 取得 image info by id
- 取得 annotation info by id
- 學會在 image 上畫 bounding box 並標籤
1 | import matplotlib.pyplot as plt |
輸出結果
隨機選10張
1 | def random_select(coco, cocoRoot, dataType, num_images=10): |
輸出結果
Task 3+5: FasterR-CNN v.s Mobilnet
Task 3 & 5
3. 使用pre-trained模型FasterR-CNN預測bbox:Use a pre-trained version of Faster R-CNN (Resnet50 backbone) to predict the bounding box
of objects on the 10 images. Only keep regions that have a score > 0.8.
5. 使用另一個pre-trained模型Mobilnet:Repeat the steps from above using a Mobilenet backbone for the Faster R-CNN.
引用 pre-train model
1 | # 引用 pre-train model (FasterR-CNN) |
圖片轉換成 tensor函式
我們要先能夠根據圖片的位置,圖取圖片出來。然後把讀書來得圖片,轉換成 tensor,才能放入 model 中進行預測。所以我們做了兩個函式:
- 一個是讀取圖片
- 一個是把圖片轉成 tensor。
1 | from PIL import Image |
訓練模型
前置作業都準備好了,我們就可以開始使用pre-trained好的模型進行預測,並儲存回傳的結果,等等視覺化使用。
1 | # 用來存放預測結果 |
只選擇>0.8的預測結果
在收集好所有的結果後,我們要特別從這一大堆預測框中,只挑選準確率大於 0.8 的預測框,這樣視覺化的時候才不會太亂。
1 | def filter_valid_boxes(predictions, threshold=0.8): |
Task 4+6: 視覺化 + IoU
Task 4 & 6
4. 把模型跟解答視覺化擺在一起:Visualize the predicted bounding boxes and label together with the ground truth bounding
6. 計算IoU比較模型:Wich backbone delivers the better results? Calculate the IoU for both approaches.
視覺話有很重要的幾點,步驟大概如下:
- 要先知道圖片id,根據id取得annotation的資訊,這樣才可以計算 IoU
- 我們將ann的資訊跟model的資訊,進行 IoU 的計算
- 我們讀取圖片在電腦中的位置,根據圖片路徑,把圖片先透過plt畫出來
- 然後基於這個圖片,才可以在上面畫上預測框跟標籤還有 IoU 的平均值
以下程式就是上述所描述的步驟,我們會把兩個模型的結果都畫出來,並且計算 IoU 的平均值。
1 | import matplotlib.pyplot as plt |
輸出結果
補充:IoU
- Ref: https://blog.csdn.net/IAMoldpan/article/details/78799857
- Ref: https://www.pyimagesearch.com/2016/11/07/intersection-over-union-iou-for-object-detection/
IoU (Intersection over Union) 是一個用來評估物件偵測演算法的指標,其定義為預測框
與真實框
其交集面積
/ 聯集面積
,其值介於 0 與 1 之間,值越大代表預測框與真實框的重疊程度越高,也就是預測框越準確。
取自:https://www.pyimagesearch.com/2016/11/07/intersection-over-union-iou-for-object-detection/
從上面的範例中,你可能會好奇,以下這段程式到底做了什麽?
1 | torchvision.ops.box_iou(bbox_tlist_anns, bbox_tlist_model) |
- 其實基本上他就是把 解答的所有預測框,跟 model 的所有預測框,兩兩計算 IoU,並且回傳一個 tensor,其 shape 為 (解答的預測框數量, model 的預測框數量),參考下圖。
這邊我們只需要取得每個解答預測框的最大 IoU,並且計算平均值即可,因此我們使用以下程式碼
1 | # 取得ann每個預測框的最大值後(可以看補充IoU了解詳細),進行 IoU 的平均值 |
你可能會好奇,使用 max()
, mean()
, sum()
這些函式,是否會影響我們的結果?
可以從上圖看到其實會發現
- 使用
sum()
你會發現他有可能會超過1,這並不是 IoU 合理的數值範圍。 - 使用
max()
他會針對解答的預測框,從 model 選一個最接近的預測框,當作該預測框的IoU,之後就可以取得解答的所有預測框
其最大值,並進行平均來獲得整體的 IoU。 - 使用
mean()
會有一個問題,這個 IoU的計算永遠不可能為1,因為你考慮到其他預測框的 IoU,這樣就會把 IoU 降低,舉例來說,解答預測框有兩個[A1,A2]
,而模型也產生兩個[B1,B2]
,一眼就知道,B1預測的是A1,而B2預測A2,而模型也預測的很準確。但是你卻透過 mean 把B1當作A2,B2當作A1,顯然是錯的,而且這兩組的 IoU 也很低,你如果透過 mean() 這樣就會把 IoU 降低,這樣就不合理了。