close

main.jpg

輸入圖片來源:http://www.lovelive-anime.jp/uranohoshi/cd.php#cd26

初嘗 CNN on Aqours Classifier (上) 實作object detection & classification by CNN (上) 實作

簡介:

  今天這篇文章的主題是我初次嘗試深度學習神經網路,花費兩個月的空閒時間,從開始入門到自己處裡數據集再到最終完成作品 (如上圖) 的心得,所以這篇文章不會有太多的知識教學,比較像是一個經驗分享同時帶入我的主觀想法希望可以幫助到其他想入門的人,內容相較於我其他的文章會多一些,希望它除了是一個分享文外也是我的一個實作記錄。

 

雜談:

  神經網路 (以下簡稱Neural Network,NN) 不單是在農場新聞上吵的熱,由於它本身應用廣泛,現在大部分的實驗室中你都可以找到有研究生的題目是使用 NN 配上自身研究的組合。不過我主要的研究領域是啟發式演算法,也就是所謂的演化計算,在我們的領域中比較少見到 NN 的蹤影,主要是利用演化計算優化 NN 的計算需求過於龐大,反之在講求效率的演化計算中嵌入 NN 也不是一件容易的事情。鑑於以上原因,兩個月前的我大概是工科碩士生中少數完全沒有用過 NN 的人了。而這篇文章就是在記錄我初嘗 NN 的一些經驗跟心得。

 

動機:

  我嘗試 NN 的動機不外乎就是風向吹得有點明顯,當每個實驗室的人都在談論的同時自然就會覺得輸人不輸陣,輸陣歹看面。所以就在這學期修了系上的 NN 課程配合觀看線上教學與文章學習。並在開始前我就預計要使用自己收集的數據產出一個小成品,主要的原因在於我過去不是研究 NN 的,所以我不認為自己可以在 NN 架構上做出什麼漂亮的變化,一定是使用經典架構稍作修改,當我已經使用被評為經典的架構,如果再使用大家範例都用過的通用數據,這樣一定會動的東西實在不符合我心中作品的定義。

 

作品介紹:

arch.jpg

輸入圖片來源:LoveLive! School idol festival 角色卡

  首先介紹我的作品成果,它的功能就是辨識《LoveLive! Sunshine!!》中的學園偶像團體 Aqours 九位成員的一個偵測與分類器,詳細的角色資料我就直接貼官網了。架構如圖,這個應用屬於 object detection,我先在前方用了 window sliding 配合 haar cascade classifier 來做 object localization 偵測出人臉後再傳遞給 CNN 做 classification。使用此架構最主要的原因就是初次嘗試 CNN 我認為已經確認整張圖就是一張臉的前提下 classification 會容易一點,所以就在前方加上我略懂的 haar cascade classifier。

 

先備知識:

  我在這邊只會提及個人學習前的背景知識跟我認為開始實作之前應該要知道的知識,不包含任何的教學,因為我認為網路上已經有相當多優質的入門資源了。例如,有關數學線性代數上 3Blue1Brown 的影片使用幾何角度講解且沒有深入到過分複雜的公式,有關 NN 相關知識上莫烦Python 有多元的優質教學,其他還有很多好的教學資源,我認為難度不是重點,重點是資源太多太雜,所以最主要是先找到一個基礎完整且自己可以吸收的,有基礎觀念後再到處去吸收自己需要的雜項甚至研讀論文。

數學

我的大學是光電系畢業,主要研究有關波動光學的繞射最佳化演算法,所以基本上微積分、線性代數、工程數學等對我來說問題都不大,反倒是一般資工的離散跟統計我比較不太行。基礎部分讀起來覺得 NN 需要的數學很廣、但是沒有很深。我認為實作前一定要會的有向量分析、偏微分 (梯度)、矩陣基本操作 (加減乘、轉置、反矩陣等)。

程式:

寫 NN 一定會用到框架,除了用手刻一個 NN 是一件大工程外,社群上的討論群也都是框架使用者,所以我會建議找一門當紅的幾個框架都有支援的直譯語言 (對,我就是在說 python)。而大型框架通常在設計上都使用 OOP 的概念,對 OOP 有一定的認識會比較好上手。同時部分框架更新速度相當快,除了 Google 大神以外也要有上網看官方英文文檔的習慣,此外再給一個個人建議,在開始前建立虛擬環境,小則 virtualenv 大則 docker,因為真的很容易下幾個 pip 就裝一大堆工具,要是事後發現不相容要改版本或是要移植程式等等的,沒有虛擬環境會超麻煩。

演算法:

我的演算法是碩一讀了資工後才學的,所以程度上應該跟資工系大學生差不多,我個人的感覺是如果有讀過一點圖論相關的東西,會比較能在腦中抽象出 NN 的架構與操作,不過我身邊也有不少完全沒修過基本算法就直上 NN 的人,真的要用到時再回頭補也是 ok 的。

神經網路知識:

這方面我的背景是零,我沒有接觸過神經網路,所以全部都是新學的,我認為要會的有感知機、多層感知機、BackPropagation (自己手推幾次最後一兩層就可以滿清楚的知道概念了)、一些訓練會出現的專有名詞 (epoch、iteration、batch size、learning rate、Activation Function、Cost Function、dropout 等),幾個優化網路的經典算法 (SGD、Momentum、Adam等),看起來很多不過他們其實都息息相關,你想讀懂 A 的時候就會一併了解到 B、C 的原理,所以如果你找的教學夠完整,讀完後應該都會知道我上面提到的東西算是很前面的基礎。同時如果你跟我一樣想做的是圖像辨識就要再加上一些 CNN 跟圖像處裡的知識 (基本的openCV、Convolution、max pooling 等) 。

 

數據收集:

  由於我準備實作的是自己感興趣的資料集,所以對於資料要有一定程度的熟悉度,像是知道每個分類的關鍵差別跟基本特徵 (因為要自己標記),數據量夠多,取得容易等都是必備的需求。

  數據取得這部分我看過不少文章都會建議爬蟲,當然在你的數據有網站可以爬的前提下我也建議爬,不然真的會收集到永無止境。我自己也是爬蟲加手工都有用,當數據來源多到我認為特別去分析網站寫爬蟲是值得的我就會寫。比較需要提及的有兩點,一是不要造成他人的困擾,我看過不少文章的爬蟲都是迴圈撞撞撞、過分一點的再開多線程,想想人家 server 都已經讓我們爬,沒有加一堆反爬機制了,就不要影響到他人的正常運作吧。沒有時間壓力的前提下,爬蟲開下去你可以去吃一頓晚餐、逛街、運動,只要是自動的你就算賺到了,拜託在迴圈中加點 sleep 吧。

  另外一點就是爬下來的東西一定要自己看過,你才會知道現在總量多少、數量比、資料狀態夠不夠多樣等訊息。舉例來說,我在收集中就發現髮色是一個很容易注意到但其實不穩定的特徵,在不同燈光效果與不同繪師筆下的色差相當大。為了避免我的 NN 把髮色當作太重要的資訊,我加入了 10% 漫畫的黑白圖片來強迫它去學到其他髮色以外的特徵。

 

haar cascade classifier:

openCV.png

  這邊要先講 object localization 部分,因為數據處裡跟標記時它幫了我不少忙。所使用的 sliding window 跟 haar cascade classifier 演算法的原理我就不再說明了,網路上已經有很多大神分享。我要做的偵測是人臉,所以 openCV 內建就有相對應的 model 不用我去訓練。不過後來我又找到有人專門訓練漫畫跟動畫的人臉,所以就換成那套 model (lbpcascade_animeface) 來做 localization,要注意的是使用 openCV 提供的 detectMultiScale 做 sliding window 時很吃重那些輸入參數,一定要理解他的涵義,然後多嘗試幾組參數會很有感。其他包括輸入前圖像有沒有欲處理的差別也很大,灰階、對比度增加等都可以試試,如上圖我就有做灰階跟直方圖均衡化的操作。值得一提的是 detectMultiScale 的 scaleFactor 是乘法,輸入圖太大時掃描框到後期會變大的很快很容易錯過偵測物,我發現之後才又補上 resize 避免這個問題。

 

數據處裡、標記:

dataSet.png

  我最終的數據集總共一萬張角色臉部圖,一個角色有 1000 張當作 training data,100張當作 testing data。因為我的架構是偵測跟分類分開,所以我還需要裁切圖的處理,數據處理盡量配合工具不然很累,不分強弱,總比沒有好,反正最終還是要自己看過一次全部的結果,而這也是我先講 haar cascade classifier 的原因,因為我就是用它先處理過再人工調整的,我覺得這也算分兩層架構的好處,前層可以預處裡後層的數據,畢竟最後組合在一起時也是這樣運作的。

標記上也不能出錯,我所採用的方法是多次確認

  1. 第一次是看爬蟲資料的時候可以順手就先做個分類 (我是照角色分,另外還有個多人區,所以第一次分10區)。
  2. 第二次 haar cascade classifier 處裡的時候可以大概知道他有沒有抓不到的臉,因為已經知道預先有幾個人 (比如說多人區掃描結果小於 2 就是一定有錯誤),掃不出的另外放,等著人工處裡或是改 haar cascade classifier 參數再掃一次看看。
  3. 第三次就是檢查剛剛裁完的九個人分別有沒有錯誤的人或是不是臉部的東西,同時分類多人區裁切出來的東西。
  4. 最後一次就是自己再掃過一次全部的數據 (這時只剩下九區)。

多次確認的方式一張圖會被看過三次左右,分類標記錯的機率很低。

 

CNN 部分:

KerasApplications.png

  NN 部分就不太可能有訓練好的 model,畢竟每個人要解決的問題不同,這也是我們收集數據的原因,準備用這些收集來的數據訓練我們自己的 model。在搭建 NN 架構與訓練 model 上稍微有點名氣的 NN 框架都包裝的不錯,其實就是用你看得順眼的。我個人推薦用 kares 因為他的 ImageDataGenerator 跟 flow_from_directory 可以讓你很方便增強、使用自己的資料集。還有就是我的數據是自己處理的,如果沒有搭建 NN 的經驗,出錯時會不好確認到底是 NN 架構還是數據有問題,甚至框架的 API 用的不正確,而 kares 有內建幾個很強的 CNN 架構可以直接用 (如上圖就來自 kares 官網),這些很強的 CNN 架構在原論文中都被用來解決更困難的問題 (1000 類分類等),所以如果這些很強的 CNN 架構在我的數據上表現都超差,就很可能是數據本身有問題了。那如果是自己建立架構,可以先放內建的簡易數據集 MNIST,或是放你的問題的簡化版 (減少分類數),並觀察前一兩個 epoch 的狀況確定他有在學習就可以先一路訓練到完獲得第一個 model。

train.png

  此文章的分類器所使用的 CNN 部分是直接用 kares 內建的 ResNet50 並改輸入來對應圖片大小、改輸出來對應九個種類後直接開始訓練,優化演算法也直接採用最常見的 adam,其參數皆為預設。結論上 ResNet50 名不虛傳的在完全沒有參數調教下,依靠預設的參數達到高達 99% 的準確率 (如上圖)。順帶一提我還有試過不管是 adam、sgd 還是 rmsprop 都可以達到 99%,可見 ResNet50 就如同預測的一樣對於我要解決的問題是牛刀殺雞,在架構上已經強大到不論哪種優化器都不會影響到結果。

 

最終組合:

  我的組合方式是,放寬 haar cascade classifier 偵測器的參數,至少抓到臉的機率要高不然人臉不傳到 CNN 就完全沒機會了,而抓錯的由 CNN 輸出去排除,主要就是看其機率肯不肯定是某個角色 (機率 < 0.95 都當作抓錯等機制),這樣就完成了。完成第一次的實作後我覺得 CNN 真的是比我預期的強很多,我原本的心態是隨便建起來有七成機率就要偷笑了,結果最後 ResNet50 正確率直接衝到 99% 反倒是我前面用的 haar cascade classifier 顯得跟不上,看是要想辦法優化 haar cascade classifier 還是改連 object localization 都給 CNN 做等都是我想再繼續玩下去的方向。

 

結果展示:

  這邊展示幾種錯誤的狀況,這張 9 人圖分類上都正確不過下方有個不是人臉的東西不只在 object localization 部分很容易被偵測為臉部,在CNN 的輸出也有很高的機率屬於某個角色,所以造成錯誤。

demo1.jpg

輸入圖像來源:http://www.lovelive-anime.jp/uranohoshi/cd2.php

 

這張 9 人圖一樣是有辨識到的都正確,但是我 object localization 用的 model 對於側臉的偵測不太擅長,所以有幾個角色完全沒被傳到 CNN 做 classification。

demo2.jpg

輸入圖像來源:https://www.pixiv.net/artworks/66521372

 

這張 9 人圖有兩個沒偵測到是人臉,同時有一個在 CNN 分類錯誤,中間從左邊抱住 mari 的不是 chika 是 hanamaru。

demo3.jpg

輸入圖像來源:https://www.pixiv.net/artworks/73989474

 

最後付上兩組我很喜歡的成功結果。

demo4.jpg

輸入圖像來源:https://www.pixiv.net/artworks/66556783

demo5-1.jpg

demo5-2.jpg

demo5-3.jpg

demo5-4.jpg

demo5-5.jpg

demo5-6.jpg

demo5-7.jpg

demo5-8.jpg

demo5-9.jpg

輸入圖像來源:https://www.pixiv.net/artworks/67530485

 

結論:

  本篇文章實作了一個用來辨識《LoveLive! Sunshine!!》中的學園偶像團體 Aqours 九位成員的一個偵測與分類器。這個應用屬於 object detection,我將其分為兩部分,前方用 opencv 的 sliding window 加上 haar cascade classifier 演算法來做 object localization 並使用 lbpcascade_animeface 這個別人訓練好的 model,後面再使用 CNN 演算法做 classification 並使用 ResNet50 這個 CNN 架構來重新訓練專用的分類 model。做完一次不只會讓你有更多新的疑惑必須要去理解,同時可以再更深入研究的點也非常多,像是去體驗其他其他的領域 (NLP等)、NN 架構的研究,其他辨識類經典架構 YOLO、R-CNN 等、優化方法研究。但是不論結果為何,做出自己喜歡的主題確實是一件令人開心的事情,同時也踏入 NN 領域的第一步,本次的分享就到此為止,謝謝正在觀看的你。

 

參考資料:

[1] lbpcascade_animeface (此分類器在 haar cascade classifier 中使用的動漫畫人臉偵測 model)

https://github.com/nagadomi/lbpcascade_animeface

[2] cv::CascadeClassifier Class Reference (openCV sliding window 與 haar cascade classifier 相關參數)

https://docs.opencv.org/3.4/d1/de5/classcv_1_1CascadeClassifier.html

[3] Keras Applications (那些內建的有名 NN 模型)

https://keras.io/api/applications/

[4] Deep Residual Learning for Image Recognition (ResNet50 原論文)

https://arxiv.org/abs/1512.03385

(其他 Demo 用的圖片皆在使用圖片時附上引用網址,如有遺漏或不妥請告知,將移除或補上)

 

 

arrow
arrow

    迷宮兔 發表在 痞客邦 留言(0) 人氣()