前言
論文網站:http://arxiv.org/abs/1404.3606
論文下載地址:PCANet: A Simple Deep Learning Baseline for Image Classification?
論文的matlab代碼(第一個就是):Matlab Codes for Download
本文的C++ 和 Scala 代碼:https://github.com/Ldpe2G/PCANet
該文提出了一個簡單的深度學習網絡,用於圖像分類,用於訓練的圖像的特徵的提取包含以下步驟:
1、cascaded principal component analusis 級聯主成分分析;
2、binary hashing 二進制哈希;
3、block-wise histogram 分塊直方圖
PCA(主成分分析)被用於學習多級濾波器(multistage filter banks),
然後用binary hashing 和 block histograms分別做索引和合並。
最後得出每一張訓練圖片的特徵,每張圖片的特徵化爲 1 x n 維向量,然後用這些特徵向量來訓練
支持向量機,然後用於圖像分類。
正文
訓練過程
首先假設我們的訓練圖片的爲N張,,每張圖片大小爲 m x n。
第一階段的主成分分析
首先對每一幅訓練圖像做一個處理,就是按像素來做一個分塊,分塊大小爲 k1 x k2。
上圖解釋什麼事按像素分塊,假設圖像是灰度圖大小爲 5 x 5,分塊大小爲 2 x 2。
然後得到的分片矩陣大小是 4 x 16,按照上述計算公式可以得到。
然後如果圖像是RGB 圖像,則首先將三個通道分開,每個通道都做上 訴的分片,得到的分塊矩陣,
做一個豎直方向上的合併得到RGB圖像的分塊矩陣,則如果RGB圖像大小爲 5 x 5,分塊大小2x2,
則得到的分塊矩陣大小爲 12 x 16。
需要注意的是按照論文的說法,分塊的矩陣的列數爲m*n,所以5x5矩陣的分塊矩陣應該有25列,
但是從代碼的實現上看,是按照上圖的公式來計算的。
假設第 i 張圖片,,分塊後得到的矩陣爲 ,然後對每一列減去列平均,得到。
接着對N張訓練圖片都做這樣一個處理,得到
c爲分快矩陣的列數。
然後接着求解的特徵向量,取前個最大的特徵值對應的特徵向量。
作爲下一階段的濾波器。數學表達爲:
然後第一階段的主成分分析就完成了。因爲我將matlab代碼移植到了opencv,所以對原來的代碼
比較熟悉,這是結合代碼來發分析的,代碼實現和論文的描述有些不同。
第二階段的主成分分析
過程基本上和第一階段一樣。不同的是第一階段輸入的N幅圖像要和第一階段得到的濾波器
分別做卷積,得到 L1 x N 張第二階段的訓練圖片。
。
在卷積之前首先做一個0邊界填充,使得卷積之後的圖片和大小相同。
同樣對每一張圖片做分塊處理,然後把由N張圖片和L1 個濾波器卷積得到的圖片的
分塊結果合在一起,首先得到:
這是N張圖片和其中一個濾波器卷積的分塊結果。
然後將所有的濾波器輸出合在一起:
但實際上在代碼的實現上,同一張圖片 對應的所有濾波器的卷積是放在一起的,
其實就是順序的不同,對結果的計算沒有影響。
然後求解的特徵向量,取前個最大的特徵值對應的特徵向量。
作爲濾波器。
哈希和直方圖
然後就來到特徵訓練的最後一步了。
然後對每一幅第二階段主成分分析的輸入圖片做以下計算:
每張圖片和L2個濾波器分別進行卷積。H(.)函數表示將一個矩陣轉換爲一個相同大小的
只包含0和1的矩陣,就是原來元素大於0,則新的矩陣對應的位置爲1,否則爲0.
然後乘以一個權值再加起來。權值由小到大依次對應的濾波器的也是由小到大。
然後對矩陣,將其分成B塊,得到的分塊矩陣大小爲 k1k2 x B,
然後統計分塊矩陣的直方圖矩陣,直方圖的範圍是,
直方圖矩陣大小爲 2^L2 x B。
然後將直方圖矩陣向量化爲行向量得到,
最後將所有的的鏈接起來
得到代表每張訓練圖的特徵向量。
上圖解釋直方圖統計:
然後訓練的步驟就完成了。
接着開始支持向量機的訓練和測試。
測試&結果
svm的核函數用的是線性核函數,論文的matlab用的是Liblinear,
由國立臺灣大學的Chih-Jen Lin博士開發的,主要是應對large-scale的data classification。
然後opencv的svm的類型我選擇了CvSVM::C_SVC,參數C設爲1。
這是我將論文的matlab代碼移植到opencv的測試結果,
用了120張圖片作測試,精確度爲65.5%,比論文中用同樣的數據集caltech101,
得到的精度68%要差一點。
對SVM有興趣的讀者可以參考這位博主的文章: