2020年1月7日 星期二

深度學習進階應用-YOLO實作-心得篇

去年(2019)開始學了人工智慧
總想有所應用
而且既然是工作上學的,最好也是用在工作上
能把一些事情自動化處理最好
這樣就能多花心思在其它更花頭腦的事上
想了好一陣子,最近才想到個應用可以試試看
只不過,很快就卡在第一關
因為雖然現在已經會對圖片進行分類了
但只能一張圖一樣東西
一張圖同時有兩件以上的東西,分不出來........
更不用說,還要知道東西在圖的哪裡了

很快地想到了一開始學的時候
有老師介紹過的YOLO(You only look once),是一種對物件分類與進行定位的技術
然後資料查啊,找啊,才知道這樣技術,叫作Object Detection
目前除了YOLO之外
還有SSD(不是硬碟那個,是Single Shot MultiBox Detector)與Retinanet等演算法可以做這樣的事
這發展已有一陣子了,所以自然是有人寫了可以用的函式庫
那麼自然是拿別人寫好了來當基底啊
哈哈哈哈,想的這麼簡單,自然是撞壁了........


首先,學了點皮毛的我,當然是想自己建一個輕量級的識別網路
而要能這麼運用就要搞懂這個神經網路怎麼運作的
然後就是馬上被一堆看不懂的名詞淹沒
bounding box還好,這個學Ogre3D時就知道了
anchors、IoU等等就陷入完全混亂了
即使現在回頭看那些說明文章寫的其實還蠻好懂的
但當時根本完全看不下去,無法構築出YOLO的運作
只好用老招,從程式回頭看吧
登登!這邊更慘,因為是從keras開始入門,一堆用TensorFlow寫的根本就看不懂
好吧,那找找有沒有用keras寫的好了
喔喔喔,好不容易找到一個
Object Detection with YOLOv3 using Keras
也是看不懂
先不管模型怎麼建,權重怎麼轉成Keras用
把圖片轉成矩陣後餵進去,跑出來的是一個非常看不懂的新矩陣
然後經過一堆有的沒的運算,才跑出想要的包覆盒、分類與預測分數
為什麼要經過這些運算?原始輸出矩陣到底是什麼?
還是一頭霧水啊

那先放棄完全了解好了
先學著怎麼用別人寫好的東西,直接用總行了吧
下載了labelimg,然後一張一張為圖片畫區域,建類別
一開始就建了20個左右的類別
接著使用這個在github上星數最高,號稱用keras寫的
keras-yolo3
可是我還是看不懂predit怎麼出來的...因為它是用session.run跑
換言之,還是靠Tensorflow原生的處理
接著照著說明修改,丟進去餵餵,訓練了一整天,最後Loss還是高卡在80
權重拿來用,找不到東西
不過一開始訓練張數太少,直接偷懶,拿現有張數變三倍資料用
想說就算overfitting也無所論,還是失敗...
一次訓練要好久,那麼有文章說,用解析度低的訓練會比較省時
那縮一下解析度好了...還是失敗
想了一想,顯示20種類別太多,縮小一點好了,改成只有5種
最後Loss還是有再低了一些,卡在60,實際拿來用,還是找不到東西
玩到這裡差不多想要放棄了
莫非是我給的圖片對訓練模型根本是垃圾?
(嗯,還真的是 XD)

雖然轉為應用為主,但訓練期間還是有一直在看相關文件
也有在測試完全用Keras寫的那個寫法到底算了什麼東西出來
然後在一行一行地看程式碼時終於發現了一件事
YOLO在輸入模型裡時用的解析度是416*416
在把我要訓練的原圖縮成416*416時......
(其實蠻慚愧的,如果介紹YOLO的文章有好好讀的話,應該會注意到這件事)
很明顯地,圈出來的元件根本太小到無法識別其特徵
畢竟那些元件大多是以原圖的面積不到10%的存在
縮成416*416時,那真的就是垃圾等級的訓練資料

明白了這一點,那麼要做的事就簡單了:重構訓練集
先把原圖砍成4等分
再用4分之一大小的圖去圈出想識別的元件
一開始還是不能太貪心,依然用5種去做分類就行
丟進去訓練.......耶!loss低於60啦
最後loss停在22左右
到底這樣的權重能不能識別出我想要的東西呢?
成功啦!!!
反覆測了幾張圖,心中概算了一下,成功率約有8成
呼~~總算成功了,雖然走了些冤枉路

最後重新整理,律定了13個類別
並針對可能會不好識別的小元件
剪出解析更高的圖來進行訓練
訓練結束後,loss值還是沒壓到20以下是有點可惜
不過搭配偵測閥值設在0.4
並將解析度放大到928*928的等級,強化了識別的能力後
幾乎有95%的準度了,對我來說已達堪用等級
接下來要進行計畫的第二步啦

沒有留言: