在本文中,會向您展示幾種不同的技術。幫助您開發可用於經典影像分類問題的演算法:從影像中檢測狗品種。
並且在本文末,作者將為使用者提供可以輸入任何影像的程式碼,返回對不同狗品種的估計。此外,如果檢測到人類,演算法將提供最相似狗的品種的估計值。
注:這個專案是作為Udacity機器學習Nanodegree(GitHub回購)的一部分完成的。
1.什麼是卷積神經網路?
卷積神經網路(也稱為CNN或ConvNet)是一類深度神經網路,它在計算機視覺和視覺影像應用方面得到廣泛採用。
有關CNN應用的著名案例可以參照史丹佛研究團隊的研究論文。,他們通過單個CNN證明了皮膚損傷的級別。在這裡需要注意的是,神經網路僅需使用畫素和疾病標籤作為輸入項來訓練影像。
卷積神經網路由多層組成。與其他影像分類演算法相比,它對預處理的要求相對較少。
他們通過使用過濾器將卷積神經網路應用於影像來進行學習。演算法是採用一個小方塊(或“視窗”)把它應用在影像上。通過過濾器讓CNN識別影像中的某些圖案。以達到CNN通過零件濾鏡,尋找與原圖內容匹配的影像。
用於影像分類的CNN層體系結構的示例(來源:https://bit.ly/2vwlegO)
網路的前幾層可以檢測簡單的特徵,如線條,圓形,邊緣。在每層中,網路能夠將這些發現結合起來,不斷深入到神經網路的各個層面,學習更復雜的概念。
1.1有什麼樣的圖層?
CNN的總體結構由輸入層,隱藏層和輸出層組成。它們是型別層,例如,卷積,啟用,合併,壓差,密集和SoftMax層。
神經網路由輸入層,隱藏層和輸出層組成(來源:https://bit.ly/2Hxhjaw)
卷積層(或Conv層)是構成卷積神經網路的核心。Conv層由一組濾波器組成。每個濾波器可以被認為是一個小的正方形(具有固定的寬度和高度)。
在每次過程中,過濾器會在輸入體積的寬度和高度上“卷積”。這個過程會產生一個二維啟用圖。這個圖會給出在每個空間位置上該濾波器的響應。
為了避免過度擬合。在啟用圖中,Pooling圖層應用於非線性下采樣。換句話說,Pooling圖層在丟棄資訊時具有侵略性。但如果使用得當,則會非常有用。所以在CNN構架中,Pooling圖層通常會跟隨一個或兩個Conv圖層。
在啟用圖中,合併圖層應用非線性縮減取樣(來源:https://bit.ly/2Hxhjaw)
Dropout圖層也用於在隨機忽略某些啟用函式的情況下,來減少過度擬合。而密集圖層則是完全連線的圖層,並且通常位於神經網路的末端。
1.2什麼是啟用功能?
啟用函式用於處理圖層和神經網路的輸出。啟用函式是新增到隱藏圖層和輸出圖層的節點。
您經常會發現ReLu啟用函式用於隱藏層,而最後一層通常由SoftMax啟用函式組成。作者的想法是通過疊加線性和非線性函式層,進行大量的模式檢測並準確預測給定影像的標籤。
作為一個標準化器,SoftMax通常被發現在最後一層,併產生一個離散的概率分佈向量。這也符合作者的目的,因為作者想要的CNN輸出是影像對應於特定類的概率。
最常見的啟用功能包括ReLU和Sigmoid啟用功能
通過模型評估和效能評估,選擇損失函式。在影像分類的CNN中,經常選擇分類交叉熵。使用漸變下降來使錯誤最小化 - 在本文中,作者將依靠“rmsprop”(自適應學習速率方法)作為優化器,並將精度作為度量標準。
2.設定演算法的構建塊
為了構建演算法,作者將使用TensorFlow,Keras(執行在TensorFlow之上的神經網路API)和OpenCV(計算機視覺庫)。
2.1檢測影像是否包含人臉
為了檢測提供的影像是否包含人臉,作者將使用OpenCV的人臉檢測演算法(之一)。在使用任何人臉檢測器之前,將影像轉換為灰度是標準程式。以下是檢測儲存在face_cascade多尺度函式並將灰度影像作為引數的具體步驟。
2.2檢測影像是否包含狗
為了檢測所提供的影像是否包含狗的面部,作者使用了預先訓練中使用的ImageNet資料集的ResNet-50模型。該模型可以對來自1000個類別中的物件進行分類。假如給定一幅影像,預先訓練的ResNet- 50模型將返回影像中對包含物件的預測。
使用TensorFlow作為後端時,Keras CNN需要一個4D陣列作為輸入。下面的path_to_tensor函式將一個字串值的檔案路徑作為輸入,並將其調整為一個224x224畫素的正方形影像。
此外,所有預先訓練的模型都有額外的標準化步驟。所以必須從每個影像的每個畫素中減去平均畫素才行。
通過匯入的函式preprocess_input實現。
對於最終預測,如上面的程式碼所示。作者通過預測概率向量的argmax來獲得與模型的預測物件類相對應的整。在這裡,您可以通過使用ImageNet標籤字典來識別物件類別。
3.使用轉移學習構建您的CNN分類器
具備了檢測影像中人和狗的功能後,作者現在需要一種方法來預測影像中的品種。在本節中,作者將建立一個分類狗品種的CNN。
為了在不犧牲準確性的情況下減少訓練時間,作者將使用轉移學習來培訓CNN--這是一種允許使用並且已經在大型資料集上預先訓練過的網路的方法。通過保持先前層次和新增加的訓練層,作者可以利用預訓練演算法獲得的知識將其用於程式上。
Keras包括幾種預先訓練的深度學習模型,可用於預測,特徵提取和微調。
3.1模型架構
如前所述,ResNet-50模型輸出為輸入層 - 又稱為瓶頸特徵。在下面的程式碼塊中,作者通過執行以下內容來提取對應的瓶頸特徵。
作者將建立模型架構,使得ResNet-50的最後卷積輸出作為輸入回到模型中。作者僅新增全域性平均池和全連線層,其中後者包含每個狗類別的一個節點並具有Softmax啟用功能。
在上面的程式碼輸出中看到的,最終得到了一個有272,517個引數的神經網路!
3.2編譯和測試模型
現在,可以使用CNN來測試在狗影像測試資料集中品種識別的程度了。為了微調模型,作者通過20個迭代,以減少使用RMS Prop優化後的損失函式(分類交叉熵)。
測試準確度:80.0239%
可以看到該演算法的測試準確度達到了80%,完全沒有問題!
3.3用模型預測狗品種
現在已經有了演算法,來編寫一個函式,將影像路徑作為輸入並返回狗品種的預測模型。
4.測試CNN分類器
現在,可以編寫一個函式。除了確定它接受影像的檔案路徑外,還要確定影像是否包含人類,狗或兩者都不包含。
如果在影像中檢測到狗,則返回預測的品種。如果在影像中檢測到人體,則返回類似的狗品種。如果在影像中均未檢測到,則提供指示錯誤的輸出。
在幾個樣本影像上進行演算法測試:
這些預測看起來很準確!現在看看當作者輸入人臉時會發生什麼!
顯然,根據演算法,作者(藍色箭頭)看起來像一隻小獵犬。
最後,我們發現演算法很容易出錯。因為它通常不是一個很清晰的鏡頭,有噪點或額外的資訊。因此,使用影像增強可能是一個不錯的選擇。