在之前的章節中,我們已經很好地解決了手寫體識別問題(維數爲28*28)。但如果是更大的圖像(維數爲96*96)呢?如果你還是要學習400個特徵,那麼網絡權重參數就有400*96*96即近400萬個。
卷積特徵提取
如果我們從大型彩色圖像(64*64*3)中隨機抽取一些小patch(8*8),學到了一些特徵,然後用這些特作爲濾波器去掃過整張大圖,即逐行逐列做卷積。這樣做可以大幅減小網絡參數W的數量,然而會使輸入分類器的特徵維數大幅度上升。
池化
池化是在卷積特徵提取的基礎上,對每個卷積特徵進行取平均等,繼續縮小隱藏節點對於的卷積特徵維數,減小分類器的設計負擔。
下面列表說明
原始圖像爲64*64*3的彩色圖像
卷積特徵提取採樣8*8的patch
隱藏層節點數統一爲400
池化採用19*19的尺寸
可以看到,通過卷積特徵提取和池化後,W數量和分類器輸入特徵數量都同時大幅度下降了。
下面是核心代碼,使用的數據庫有四種圖片:飛機、汽車、貓、狗,每幅圖的大小就是64*64*3,train圖片2000幅,test圖片3200幅,最後經過漫長的等待:時間已過 3288.054248 秒。
Accuracy:80.406%,結果令人滿意。
cnnExercise
loadSTL10Features%加載線性解碼器提到的特徵
這裏是之前得到的400個特徵
現在拿來當卷積濾波器用
圖1
計算卷積
cnnConvolve
這裏太零散了,直接粘過來整個M文件好了。
function convolvedFeatures = cnnConvolve(patchDim, numFeatures, images, W, b, ZCAWhite, meanPatch)
numImages = size(images, 4);
imageDim = size(images, 1);
imageChannels = size(images, 3);
convolvedFeatures = zeros(numFeatures, numImages, imageDim - patchDim + 1, imageDim - patchDim + 1);
WT=W*ZCAWhite;%等效W
bT = b - WT*meanPatch;%等效b,這裏要補償均值
convolvedFeatures = zeros(numFeatures, numImages, imageDim - patchDim + 1, imageDim - patchDim + 1);
for imageNum = 1:numImages
for featureNum = 1:numFeatures
convolvedImage = zeros(imageDim - patchDim + 1, imageDim - patchDim + 1);
for channel = 1:imageChannels
feature = reshape(WT(featureNum,(channel-1)*patchDim*patchDim+1:channel*patchDim*patchDim),patchDim,patchDim); % 取出各通道patch
feature = flipud(fliplr(squeeze(feature)));
im = squeeze(images(:, :, channel, imageNum));
convolvedImage=convolvedImage+conv2(im,feature,'valid'); %計算卷積
end
convolvedImage=sigmoid(convolvedImage+bT(featureNum));
convolvedFeatures(featureNum, imageNum, :, :) = convolvedImage;
end
end
end
function sigm = sigmoid(x)
sigm = 1./(1+exp(-x));
end
計算池化
cnnPool
cnnPool
for imageNum=1:numImages
for featureNum=1:numFeatures
for poolRow=1:convolvedDim/poolDim
offsetRow=1+(poolRow-1)*poolDim;
for poolCol=1:convolvedDim/poolDim
offsetCol=1+(poolCol-1)*poolDim;
patch=convolvedFeatures(featureNum, imageNum,offsetRow:offsetRow+poolDim-1,offsetCol:offsetCol+poolDim-1);
pooledFeatures(featureNum,imageNum,poolRow,poolCol) = mean(patch(:));
end
end
end
end
歡迎參與討論並關注本博客和微博以及知乎個人主頁後續內容繼續更新哦~
轉載請您尊重作者的勞動,完整保留上述文字以及文章鏈接,謝謝您的支持!