圖像分類的方法之深度學習與傳統機器學習
圖像分類,顧名思義,是一個輸入圖像,輸出對該圖像內容分類的描述的問題。它是計算機視覺的核心,實際應用廣泛。
圖像分類的傳統方法是特征描述及檢測,這類傳統方法可能對于一些簡單的圖像分類是有效的,但由于實際情況非常復雜,傳統的分類方法不堪重負。現在,我們不再試圖用代碼來描述每一個圖像類別,決定轉而使用機器學習的方法處理圖像分類問題。
目前,許多研究者使用CNN等深度學習模型進行圖像分類;另外,經典的KNN和SVM算法也取得不錯的結果。然而,我們似乎無法斷言,哪種方法對于圖像分來問題效果最佳。
本項目中,我們做了一些有意思的事情:
1. 將業內普遍用于圖像分類的CNN和遷移學習算法與KNN,SVM,BP神經網絡進行比較。
2. 獲取深度學習經驗。
3. 探索谷歌機器學習框架TensorFlow。
下面是具體實施細節。
系統設計
在本項目中,用于實驗的5種算法為KNN、SVM、BP神經網絡、CNN以及遷移學習。我們采用如下三種方式進行實驗:
1. KNN、SVM、BP神經網絡是我們在學校能夠學到的。功能強大而且易部署。所以第一步,我們主要使用sklearn實現KNN,SVM,和BP神經網絡。
2. 由于傳統的多層感知機模型在圖像識別方面效果甚佳,但由于其節點間的全連接模式對于其延展性造成了阻礙,因此對于高分辨率的圖像,識別率不是很理想。所以這一步,我們用Google TensorFlow框架構建CNN。
3. 對于已經預訓練過的深度神經網絡Inception V3進行重訓練。Inception V3由TensorFlow提供,使用ImageNet自2012年以來的數據進行訓練。ImageNet是計算機視覺領域一個經典挑戰,參賽者試圖用模型將全部圖像放至1000個分類中。為了要重新訓練已經預訓練好的模型,我們必須保證我們自己的數據集沒有被預訓練過。
實施
第一種方法:使用sklearn預處理數據以及實現KNN,SVM和BP神經網絡。
步驟1,使用openCV包,定義2個預處理函數,分別是圖像特征向量(用來調整圖像大小并將圖像扁平化成一系列行像素)和提取顏色直方圖(使用cv2.normalize從HSV色域中提取一個3D顏色直方圖并做平滑處理)。
步驟2,構造參數。由于我們試圖在整個數據集以及具有不同類別數目的子數據集上進行性能測試,所以我們把各個數據集看作為參數,以便進行實驗分析。另外,我們還設置了KNN中的鄰居數目作為參數。
步驟3,提取圖像特征并寫入數組。我們使用cv2.imread函數讀取圖像,根據規范化的圖像名稱進行分類。然后運行第步驟1中提到的2個函數,分別得到2種圖像特征并寫入數組。
步驟4,使用函數train_test_split分割數據集。85%的數據作為訓練集,15%的數據作為測試集。
步驟5,使用KNN,SVM和BP神經網絡方法去評估數據。對于KNN,使用KNeighborsClassifier,對于SVM,使用SVC,對于BP神經網絡,使用MLPClassifier。
第二種方法:基于TensorFlow構建CNN。使用TensorFlow得到計算圖并在C++中實現,比Python更高效。
TensorFlow中使用到的的幾個概念:占位符,變量,數學公式,成本計量,最優方法,CNN體系結構。
步驟1,第一層放置圖像。
步驟2,構建3層卷積層(3 Convolutional layers),2X2的max-pooling和ReLU。輸入是4維張量:【圖像編號,Y坐標,X坐標,通道】。輸出是另一個經處理得到的4維張量:【圖像編號(不變),Y坐標,X坐標,通道】。
步驟3,構建2層全連接層(2 Fully-Connected Layers)。輸入是2維張量:【圖像編號,輸入編號】。輸出是2維張量【圖像編號,輸出編號】。使用
步驟4,使用合并層(Flatten Layer)鏈接卷積層和全連接層。
步驟5,使用softmax layer標準化輸出。
步驟6,優化訓練結果。我們使用交叉熵(cross entropy)作為成本計量函數,取其均值。最優方法使用tf.train.AdamOptimizer()。
第三種方法:Retrain Inception V3。使用Retrain Inception V3 ,并利用遷移學習減少工作量。
我們得到pre-trained模型,移除原有頂層,訓練新模型。然后分析在磁盤上的所有圖像并計算它們的bottleneck值。腳本會運行4000次。每次運行都會從訓練集中隨機選取10個圖像,找到它們的bottleneck值并注入最后一層得到預測結果。然后在反向傳播過程中,根據預測結果和實際標簽的比較結果去更新每層的權重。
實驗
實驗中使用到的數據集是Oxford-IIIT Pet 數據集。
http://www.robots.ox.ac.uk/~vgg/data/pets/
其中有犬類25類,貓類12類。每類有200個圖像。我們使用到該數據集中的10個類別的貓的數據,分別是[‘Sphynx’,’Siamese’,’Ragdoll’,’Persian’,’Maine-Coon’,’British-shorthair’,’Bombay’,’Birman’,’Bengal’,’Abyssinian’]。即,共有2000個圖像,由于圖像大小不一,我們調整大小統一為固定尺寸64X64或128X128。
本項目中,我們主要使用OpenCV預處理圖像。一般通過變形、剪裁或亮化隨機處理訓練集。
github:https://github.com/aleju/imgaug
賦值
第一種方法:KNN,SVM,和BP神經網絡
第一部分:使用sklearn預處理數據以及實現KNN,SVM和BP神經網絡。在image_to_feature_vector函數中,我們設定尺寸128X128。經試驗表明,圖像尺寸越大,結果越精確,運行負擔越大。最終我們決定使用128X128的尺寸。在extract_color_histogram函數中,設定每個通道的容器數量為32,32,32。對于數據集,使用3種數據集。第一個是具有400個圖像,2個標簽的子數據集。第二個是具有1000個圖像,5個標簽的子數據集。第三個是整個數據集,1997個圖像,10個標簽。
在KNeighborsClassifier中,我們只改變鄰居數量且存儲結果作為每個數據集的最佳K值,其他參數默認。
在MLPClassifier中,我們設定每層有50個神經元。
在SVC中,最大迭代次數是1000,類權重是“balanced”。
依據數據集,2個標簽到10個標簽不同,運行時間大約為3到5分鐘不等。
第二種方法:基于TensorFlow構建CNN
由于在整個數據集中運行時間過長,我們在每個迭代中分批次處理。每批次一般有32個或64個圖像。數據集分為1600個圖像的訓練集,400個圖像的驗證集,300個圖像的測試集。
本方法中有大量的參數可調整。學習速率設定為1x10^-4;圖像大小設定為64x64和128x128;然后是層和形狀,然而有太多的參數可調整,我們依據經驗并進行實驗去得到最佳結果。
為了得到最佳的layers,我們進行實驗。首先,參數如下:
# Convolutional Layer 1. filter_size1 = 5 num_filters1 = 64
# Convolutional Layer 2. filter_size2 = 5 num_filters2 = 64
# Convolutional Layer 3. filter_size3 = 5 num_filters3 = 128
# Fully-connected layer 1. fc1_size = 256
# Fully-connected layer 2. fc1_size = 256
我們使用了3個卷積層和2個全連接層,然而悲劇的是過度擬合。經過研究發現,對于該構造,我們的數據集過小,網絡過于復雜。
最終,我們使用如下參數:
# Convolutional Layer 1. filter_size1 = 5 num_filters1 = 64
# Convolutional Layer 2. filter_size2 = 3 num_filters2 = 64
# Fully-connected layer 1. fc1_size = 128
# Number of neurons in fully-connected layer.
# Fully-connected layer 2. fc2_size = 128
# Number of neurons in fully-connected layer.
# Number of color channels for the images:
# 1 channel for gray-scale. num_channels = 3
我們只使用了2個卷積層和2個全連接層。依然不盡人意,經過4000次迭代,結果仍舊過擬合,不過好在測試結果10%優于前者。最終,經過5000次迭代,我們得到43%的精確度,運行時間是半小時以上。
?
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%