更多優質內容請關注微信公眾號“AI 前線”,(ID:ai-front)
在 TensorFlow 的許多功能和工具中,有一個名為 TensorFlow Object Detection (目標檢測)API 的元件。顧名思義,這個庫的目的就是訓練一個神經網路,能夠識別視訊幀中的目標,例如一個影象。
在我之前的一項工作中,我曾發表了一篇文章,闡述了我在 Android 裝置上使用 TensorFlow 軟體包檢測皮卡丘的過程。此外,我還介紹了這個庫,並討論了它提供的不同架構和功能,以及如何使用 TensorBoard 評估訓練過程的演示。
AI 前線注:該文章可訪問以下連結檢視 http://suo.im/4GPhqa
幾個月後,我開始著手改進之前訓練過的皮卡丘檢測的模型,希望能夠在視訊中檢測到皮卡丘,我使用了 Python、OpenCV,當然還有 TensorFlow Object Detection。這個模型的程式碼可以在 Github 上找到:
https://github.com/juandes/pikachu-detection
超級萌物皮卡丘
本文記錄了我為實現這個目標所採取的步驟。首先,我將闡述我在原始模型中注意到的問題,以及為改善這些問題所做的工作。然後,我將繼續闡述如何使用這個改進的新模型,並基於它開發了一個視訊檢測系統。最後,你們將能看到有著幾個皮卡丘檢測的兩個視訊。
在我們開始之前,先看一副 gif 動圖,演示如何快速檢測皮卡丘。
皮卡丘被檢測到
綠框處即檢測到的皮卡丘
如前所述,在之前的工作中,我對一個皮卡丘檢測模型進行了最初的訓練,目標是在 Android 裝置和 Python notebook 使用這個模型。然而,我對這個模型的表現並不是很滿意,想做出皮卡丘檢測系統的動機驅使我持續改進這個模型,於是便有了本文。
我所關心的主要問題是用來構建該系統所需的皮卡丘圖片的數量:230 張。其中約 70% 用於訓練,其餘 30% 用於測試,因此訓練並不太多。儘管這在技術上並不是什麼問題(因為該模型的表現是“良好”),但我還是在訓練集上增加了 70 多張圖片(雖然不是很多,但總比沒有好)。
由於我現在有了更多的圖片,因此必須延長模型的訓練。我並沒有從頭開始訓練,而是使用了早期模型的訓練檢查點,並從那裡繼續;前者在 15000 個輪數訓練,而新訓練則需 20000 個輪數。如下兩張圖所示,顯示了總損失(total loss)和精度(precision)(來源:TensorBoard);從這兩張圖很容易看出,從 15000 個輪數到 20000 個輪數(特別是在損失中),並沒有多少變化。
損失度曲線
精度曲線
我做的最後一個(也是比較小的)改進,是修改了 Android 應用的檢測閾值,將預設值 0.6,增加到 0.85。
你可能會問,這些改進能改變什麼嗎?就算摒棄我的偏見,我也會說,是的!我確實注意到了小小的改進。我注意到的最大變化就是,Android 應用的假正類(False Positive)數量減少了,原因是目標看起來像一個黃色的斑點;當然,也有可能是因為門檻提高所致。
現在,我有了一個最新的(承載著我的希望)改進模型,我已經準備好用它來檢測視訊中的皮卡丘。在此之前,我想指出的是,我將略過模型凍結和匯入的整個過程,因為在我之前的工作中,已經解決了這個問題。
從視訊中進行目標檢測並不像聽起來那麼困難或複雜。從外行的角度來說,我們可以認為視訊是由一系列按順序排列的影象組成的,因此檢測過程與從正常影象檢測的過程非常相似。為什麼會相當相似呢?嗯,由於視訊的性質,在將其饋送到檢測模型前必須解決幀的預處理和準備還需要幾個步驟。在接下來的文章中,我將會解釋這一點,再加上我執行檢測的過程,以及如何建立一個新視訊來展示檢測效果。
我的大部分程式碼都是基於 TensorFlow Object Detection 中提供的 Python notebook;這段程式碼完成了大部分工作,因為它包含了許多簡化檢測過程的函式。另外,我建議你看一下我的指令碼,並在閱讀以下段落時,使用這段指令碼作為指導。
從高層次的角度來看,我寫的程式碼完成了三個主要任務:
首先,要載入凍結模型、資料標籤和視訊。為了簡單起見,我建議使用一個簡短的中型視訊,因為處理一整部電影的話可能會需要更多的時間。
該指令碼的主要功能是基於迴圈遍歷視訊的每一個幀。在每次迭代中,讀取幀並更改其顏色空間。接下來,通過實際的檢測過程找出所有那些漂亮的皮卡丘。然後返回皮卡丘所在邊界框的座標(如果找到的話)以及檢測到的置信度值。隨後,這個指令碼將建立一個幀的副本,其中包含皮卡丘的邊界框,只要置信度的值高於給定閾值即可。對於這個專案,我將置信度的閾值設定為非常低的 20%,因為我注意到在視訊中檢測到的假正類的數量非常小,所以我決定“冒險”設定這樣的閾值,只是為了能夠檢測到更多的皮卡丘。
所有新建立的帶有前面步驟中所提到的檢測框的幀副本,都用來構建新的視訊。要構建這個視訊,需要一個VideoWriter
物件,並在前面所提到的迴圈的每次迭代中,幀的副本將寫入這個物件(沒有任何聲音)。
這兩個視訊展示了模型的表現。
該模型在第一個視訊的檢測結果非常好。儘管皮卡丘在整個視訊中一直拿著番茄醬瓶子,但該模型在大多數場景中都能檢測到皮卡丘。另一方面,在 0:22 處沒有檢測到皮卡丘,而且,0:40~0:44 這段出現飛天螳螂打碎番茄醬瓶子被檢測為假正類。
該模型在第二個視訊的表現不如第一個視訊好,主要問題在於畫面上有兩個皮卡丘,在這種情況下,這個模型似乎將這兩個皮卡丘視為一個,而不是每個皮卡丘都檢測為一個:一個明顯的例子就是在 0:13 處開始,兩個皮卡丘互相抽打耳光。
在本文中,我談到了如何使用 TensorFlow Object Detection 包在視訊中檢測皮卡丘。在本文開頭,我談論了以前的工作,提及我使用早期版本的模型在 Android 裝置上進行檢測皮卡丘。該模型儘管發揮了作用,但仍存在一些我想解決的問題;這些改進讓我得以完成這個新專案,併為視訊構建了一個檢測皮卡丘的模型。
這個新模型確實按照我的預期發揮了作用。當然,也有檢測不到的時候,這與假正類有關,但模型做到了它必須做的事。作為未來的研究方向,我希望在我的訓練集中新增更多不同角度的皮卡丘影象,例如,皮卡丘的側檢視和後檢視,以使資料更加多樣化,從而獲得更好的結果。
原文連結:
https://towardsdatascience.com/detecting-pikachu-in-videos-using-tensorflow-object-detection-cd872ac42c1d