UFLDL教程:Exercise:Convolution and Pooling
Deep Learning and Unsupervised Feature Learning Tutorial Solutions
CNN的基本結構包括兩層
其一為特征提取層,每個神經元的輸入與前一層的局部接受域相連,并提取該局部的特征。一旦該局部特征被提取后,它與其它特征間的位置關系也隨之確定下來。
其二是特征映射層,網絡的每個計算層由多個特征映射組成,每個特征映射是一個平面,平面上所有神經元的權值相等。
由于一個映射面上的神經元共享權值,因而減少了網絡自由參數的個數。
由于同一特征映射面上的神經元權值相同,所以網絡可以并行學習,這也是卷積網絡相對于神經元彼此相連網絡的一大優勢.
權值共享降低了網絡的復雜性,特別是多維輸入向量的圖像可以直接輸入網絡這一特點避免了特征提取和分類過程中數據重建的復雜度。
卷積神經網絡中的每一個卷積層都緊跟著一個用來求局部平均與二次提取的計算層,這種特有的兩次特征提取結構減小了特征分辨率。
卷積神經元每一個隱層的單元提取圖像局部特征,將其映射成一個平面,特征映射函數采用 sigmoid 函數作為卷積網絡的激活函數,使得特征映射具有位移不變性。每個神經元與前一層的局部感受野相連。
不是局部連接的神經元權值相同,而是同一平面層的神經元權值相同,有相同程度的位移、旋轉不變性。每個特征提取后都緊跟著一個用來求局部平均與二次提取的亞取樣層。這種特有的兩次特征提取結構使得網絡對輸入樣本有較高的畸變容忍能力。也就是說,卷積神經網絡通過局部感受野、共享權值和亞取樣來保證圖像對位移、縮放、扭曲的魯棒性。
卷積神經網絡有兩種神器可以降低參數數目,第一種神器叫做局部感知野。第二種神器,即權值共享。
局部感受野
一般認為人對外界的認知是從局部到全局的,而圖像的空間聯系也是局部的像素聯系較為緊密,而距離較遠的像素相關性則較弱。因而,每個神經元其實沒有必要對全局圖像進行感知,只需要對局部進行感知,然后在更高層將局部的信息綜合起來就得到了全局的信息。網絡部分連通的思想,也是受啟發于生物學里面的視覺系統結構。視覺皮層的神經元就是局部接受信息的(即這些神經元只響應某些特定區域的刺激)。
權值共享
怎么理解權值共享呢?我們可以這100個參數(也就是卷積操作)看成是提取特征的方式,該方式與位置無關。這其中隱含的原理則是:圖像的一部分的統計特性與其他部分是一樣的。這也意味著我們在這一部分學習的特征也能用在另一部分上,所以對于這個圖像上的所有位置,我們都能使用同樣的學習特征。
權值共享,不是所有的紅色線標注的連接權值相同。而是每一個顏色的線都有一個紅色線的權值與之相等.
卷積
全聯通網絡
較大圖像,通過全聯通網絡來學習整幅圖像的特征,將會非常耗時。
在稀疏自編碼章節中,我們把輸入層和隱含層進行“全連接”的設計。
從計算的角度來講,在其他章節中曾經用過的相對較小的圖像(如在稀疏自編碼的作業中用到過的 8x8 的小塊圖像,在MNIST數據集中用到過的28x28 的小塊圖像),從整幅圖像中計算特征是可行的。
但是,如果是更大的圖像(如 96x96 的圖像),要通過這種全聯通網絡的這種方法來學習整幅圖像上的特征,從計算角度而言,將變得非常耗時。
比如說為96*96,隱含層有要學習100個特征,則這時候把輸入層的所有點都與隱含層節點連接,則大約需要學習10^6個參數,這樣的話在使用BP算法時速度就明顯慢了很多。
部分聯通網絡
解決這類問題的一種簡單方法是對隱含單元和輸入單元間的連接加以限制:每個隱含單元僅僅只能連接輸入單元的一部分。
例如,每個隱含單元僅僅連接輸入圖像的一小片相鄰區域。(對于不同于圖像的輸入形式,也會有一些特別的連接到單隱含層的輸入信號“連接區域”選擇方式。如音頻作為一種信號輸入方式,一個隱含單元所需要連接的輸入單元的子集,可能僅僅是一段音頻輸入所對應的某個時間段上的信號。)
網絡部分連通的思想,也是受啟發于生物學里面的視覺系統結構。視覺皮層的神經元就是局部接受信息的(即這些神經元只響應某些特定區域的刺激)。
自然圖像有其固有特性,它們具有穩定性,也就是說,圖像的一部分的統計特性與其他部分是一樣的。這也意味著我們在這一部分學習的特征也能用在另一部分上,所以對于這個圖像上的所有位置,我們都能使用同樣的學習特征。
更恰當的解釋是,當從一個大尺寸圖像中隨機選取一小塊,比如說 8x8 作為樣本,并且從這個小塊樣本中學習到了一些特征,這時我們可以把從這個 8x8 樣本中學習到的特征作為探測器,應用到這個圖像的任意地方中去。特別是,我們可以用從 8x8 樣本中所學習到的特征跟原本的大尺寸圖像作卷積,從而對這個大尺寸圖像上的任一位置獲得一個不同特征的激活值。
convolution移動是有重疊的。卷積神經網絡中的卷積是處理的一塊圖像不是處理的一個像素,這樣做法加強了圖像信息的連續性,使得神經網絡能夠看到圖形而非一個點,這種做法也有助于加深對圖像理解。對于圖像來說,單個的像素細粒度特征是沒有意義的。而一塊圖像的特征可能包含更多的邊緣信息,這樣更加有助于對圖像的理解。
層類型:Convolutionlr_mult: 學習率的系數,最終的學習率是這個數乘以solver.prototxt配置文件中的base_lr。如果有兩個lr_mult, 則第一個表示權值的學習率,第二個表示偏置項的學習率。一般偏置項的學習率是權值學習率的兩倍。在后面的convolution_param中,我們可以設定卷積層的特有參數。必須設置的參數:num_output: 卷積核(filter)的個數kernel_size: 卷積核的大小。如果卷積核的長和寬不等,需要用kernel_h和kernel_w分別設定其它參數:stride: 卷積核的步長,默認為1。也可以用stride_h和stride_w來設置。pad: 擴充邊緣,默認為0,不擴充。 擴充的時候是左右、上下對稱的,比如卷積核的大小為5*5,那么pad設置為2,則四個邊緣都擴充2個像素,即寬度和高度都擴充了4個像素,這樣卷積運算之后的特征圖就不會變小。也可以通過pad_h和pad_w來分別設定。weight_filler: 權值初始化。 默認為“constant",值全為0,很多時候我們用"xavier"算法來進行初始化,也可以設置為”gaussian"bias_filler: 偏置項的初始化。一般設置為"constant",值全為0。bias_term: 是否開啟偏置項,默認為true, 開啟輸入:n*c0*w0*h0 輸出:n*c1*w1*h1 其中,c1就是參數中的num_output,生成的特征圖個數w1=floor((w0+2*pad-kernel_size)/stride)+1;h1=floor((h0+2*pad-kernel_size)/stride)+1; 如果設置stride為1,前后兩次卷積部分存在重疊。如果設置pad=(kernel_size-1)/2,則運算后,寬度和高度不變。 由pad, kernel_size和stride三者共同決定。池化
在通過卷積獲得了特征 (features) 之后,下一步我們希望利用這些特征去做分類。理論上講,人們可以用所有提取得到的特征去訓練分類器,例如 softmax 分類器,但這樣做面臨計算量的挑戰。
例如:對于一個 96X96 像素的圖像,假設我們已經學習得到了400個定義在8X8輸入上的特征,每一個特征和圖像卷積都會得到一個 (96 ? 8 + 1) * (96 ? 8 + 1) = 7921 維的卷積特征,由于有 400 個特征,所以每個樣例 (example) 都會得到一個 89*89 * 400 = 3,168,400 維的卷積特征向量。學習一個擁有超過 3 百萬特征輸入的分類器十分不便,并且容易出現過擬合 (over-fitting)。而采用完全連接的網絡輸出只有100維。
使用卷積后的特征是因為圖像具有一種“靜態性”的屬性,這也就意味著在一個圖像區域有用的特征極有可能在另一個區域同樣適用。因此,為了描述大的圖像,一個很自然的想法就是對不同位置的特征進行聚合統計.
例如,人們可以計算圖像一個區域上的某個特定特征的平均值 (或最大值)。這些概要統計特征不僅具有低得多的維度 (相比使用所有提取得到的特征),同時還會改善結果(不容易過擬合)。這種聚合統計的操作就叫做池化 (pooling),有時也稱為均值池化 (mean pooling),最大值池化 (max pooling),隨機池化 (stochastic pooling) (取決于計算池化的方法)。 池化同時也通過統計區域信息,達到了一個降噪的目的,以及平移、旋轉、放縮的不變性。
池化可以理解為理解成下采樣(subsampling),池化是層層遞進的,底層的池化是在模糊底層特征,如線條等,高層的池化模糊了高級語義特征,卷積池化交替出現,保證提取特征的同時也強制模糊增加特征的旋轉不變性。
convolution得到的結果進行統計計算過程就叫做pooling。池化有一般池化(非重疊池化)、重疊池化、空金字塔池化。
下圖顯示池化如何應用于一個圖像的四塊不重合區域
池化的不變性
如果人們選擇圖像中的連續范圍作為池化區域,并且只是池化相同(重復)的隱藏單元產生的特征,那么,這些池化單元就具有平移不變性 (translation invariant)。這就意味著即使圖像經歷了一個小的平移之后,依然會產生相同的 (池化的) 特征。
池化可以提供基本的平移、旋轉不變性。最大化操作會提取出相同的值而不管你是否有一定程度內的平移或旋轉。
一般池化(General Pooling)
池化作用于圖像中不重合的區域(這與卷積操作不同),過程如下圖。
我們定義池化窗口的大小為sizeX,即下圖中紅色正方形的邊長,定義兩個相鄰池化窗口的水平位移/豎直位移為stride。一般池化由于每一池化窗口都是不重復的,所以sizeX=stride。
最常見的池化操作為平均池化mean pooling和最大池化max pooling:
平均池化:計算圖像區域的平均值作為該區域池化后的值。
最大池化:選圖像區域的最大值作為該區域池化后的值。
重疊池化(OverlappingPooling)
重疊池化正如其名字所說的,相鄰池化窗口之間會有重疊區域,此時sizeX>stride。
論文 Krizhevsky, I. Sutskever, andG. Hinton, “Imagenet classification with deep convolutional neural networks,”in NIPS,2012.中,作者使用了重疊池化,其他的設置都不變的情況下, top-1和top-5 的錯誤率分別減少了0.4% 和0.3%。
空金字塔池化(Spatial Pyramid Pooling)
空間金字塔池化可以把任何尺度的圖像的卷積特征轉化成相同維度,這不僅可以讓CNN處理任意尺度的圖像,還能避免cropping和warping操作,導致一些信息的丟失,具有非常重要的意義。
Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Su,Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition,LSVRC-2014 contest
一般的CNN都需要輸入圖像的大小是固定的,這是因為全連接層的輸入需要固定輸入維度,但在卷積操作是沒有對圖像尺度有限制,所有作者提出了空間金字塔池化,先讓圖像進行卷積操作,然后轉化成維度相同的特征輸入到全連接層,這個可以把CNN擴展到任意大小的圖像。
pooling層的運算方法基本是和卷積層是一樣的。輸入:n*c*w0*h0 輸出:n*c*w1*h1 和卷積層的區別就是其中的c保持不變w1=floor((w0+2*pad-kernel_size)/stride)+1;h1=floor((h0+2*pad-kernel_size)/stride)+1; 如果設置stride為2,前后兩次卷積部分不重疊。100*100的特征圖池化后,變成50*50. 由pad, kernel_size和stride三者共同決定。空間金字塔池化的思想來自于Spatial Pyramid Model,它一個pooling變成了多個scale的pooling。用不同大小池化窗口作用于卷積特征,我們可以得到1X1,2X2,4X4的池化結果,由于conv5中共有256個過濾器,所以得到1個256維的特征,4個256個特征,以及16個256維的特征,然后把這21個256維特征鏈接起來輸入全連接層,通過這種方式把不同大小的圖像轉化成相同維度的特征。
對于不同的圖像要得到相同大小的pooling結果,就需要根據圖像的大小動態的計算池化窗口的大小和步長。假設conv5輸出的大小為a*a,需要得到n*n大小的池化結果,可以讓窗口大小sizeX為,步長為 。下圖以conv5輸出的大小為13*13為例。
SPP其實就是一種多個scale的pooling,可以獲取圖像中的多尺度信息;在CNN中加入SPP后,可以讓CNN處理任意大小的輸入,這讓模型變得更加的flexible。
備注
convolution是為了解決前面無監督特征提取學習計算復雜度的問題,
而pooling方法是為了后面有監督特征分類器學習的,也是為了減小需要訓練的系統參數。
也就是說我們采用無監督的方法提取目標的特征,而采用有監督的方法來訓練分類器。
max pooling用來去掉卷積得到的Feature Map中的冗余信息,pooling是一種信息匯集,信息粗粒度化
實驗步驟
1.初始化參數,加載上一節實驗結果,即:10萬張8*8的RGB小圖像塊中提取的顏色特征,并把特征可視化。
2.先加載8張64*64的圖片(用來測試卷積和池化是否正確),再實現卷積函數cnnConvolve.m,并檢查該函數是否正確。
3.實現池化函數cnnPool.m,并檢查該函數是否正確。
4.加載2000張64*64RGB圖片,利用前面實現的卷積函數從中提取出卷積特征convolvedFeaturesThis后,再利用池化函數從convolvedFeaturesThis中提取出池化特征pooledFeaturesTrain,把它作為softmax分類器的訓練數據集;加載3200張64*64RGB圖片,利用前面實現的卷積函數從中提取出卷積特征convolvedFeaturesThis后,再利用池化函數從convolvedFeaturesThis中提取出池化特征pooledFeaturesTest,把它作為softmax分類器的測試數據集。
5.用訓練數據集pooledFeaturesTrain及其標簽訓練softmax分類器,得到模型參數softmaxModel。
6.利用訓練過的模型參數為pooledFeaturesTest的softmax分類器對測試數據集pooledFeaturesTest進行分類,即得到3200張64*64RGB圖片的分類結果。
cnnExercise.m
%% CS294A/CS294W Convolutional Neural Networks Exercise% Instructions % ------------ % % This file contains code that helps you get started on the % convolutional neural networks exercise. In this exercise, you will only % need to modify cnnConvolve.m and cnnPool.m. You will not need to modify % this file.%%====================================================================== %% STEP 0: Initialization % Here we initialize some parameters used for the exercise.imageDim = 64; % image dimension imageChannels = 3; % number of channels (rgb, so 3)patchDim = 8; % patch dimension numPatches = 50000; % number of patchesvisibleSize = patchDim * patchDim * imageChannels; % number of input units outputSize = visibleSize; % number of output units hiddenSize = 400; % number of hidden units epsilon = 0.1; % epsilon for ZCA whiteningpoolDim = 19; % dimension of pooling region%%====================================================================== %% STEP 1: Train a sparse autoencoder (with a linear decoder) to learn % features from color patches. If you have completed the linear decoder % execise, use the features that you have obtained from that exercise, % loading them into optTheta. Recall that we have to keep around the % parameters used in whitening (i.e., the ZCA whitening matrix and the % meanPatch)% --------------------------- YOUR CODE HERE -------------------------- % Train the sparse autoencoder and fill the following variables with % the optimal parameters:optTheta = zeros(2*hiddenSize*visibleSize+hiddenSize+visibleSize, 1); ZCAWhite = zeros(visibleSize, visibleSize); meanPatch = zeros(visibleSize, 1); %load STL10Features.mat;% --------------------------------------------------------------------% Display and check to see that the features look good W = reshape(optTheta(1:visibleSize * hiddenSize), hiddenSize, visibleSize); b = optTheta(2*hiddenSize*visibleSize+1:2*hiddenSize*visibleSize+hiddenSize);displayColorNetwork( (W*ZCAWhite)');%%====================================================================== %% STEP 2: Implement and test convolution and pooling % In this step, you will implement convolution and pooling, and test them % on a small part of the data set to ensure that you have implemented % these two functions correctly. In the next step, you will actually % convolve and pool the features with the STL10 images.%% STEP 2a: Implement convolution % Implement convolution in the function cnnConvolve in cnnConvolve.m% Note that we have to preprocess the images in the exact same way % we preprocessed the patches before we can obtain the feature activations.load stlTrainSubset.mat % loads numTrainImages, trainImages, trainLabels%% Use only the first 8 images for testing convImages = trainImages(:, :, :, 1:8); % NOTE: Implement cnnConvolve in cnnConvolve.m first!w和b已經是矩陣或向量的形式了 convolvedFeatures = cnnConvolve(patchDim, hiddenSize, convImages, W, b, ZCAWhite, meanPatch);%% STEP 2b: Checking your convolution % To ensure that you have convolved the features correctly, we have % provided some code to compare the results of your convolution with % activations from the sparse autoencoder% For 1000 random points for i = 1:1000 featureNum = randi([1, hiddenSize]);%隨機選取一個特征imageNum = randi([1, 8]);%隨機選取一個樣本imageRow = randi([1, imageDim - patchDim + 1]);%隨機選取一個點imageCol = randi([1, imageDim - patchDim + 1]); %在那8張圖片中隨機選取1張圖片,然后又根據隨機選取的左上角點選取1個patchpatch = convImages(imageRow:imageRow + patchDim - 1, imageCol:imageCol + patchDim - 1, :, imageNum);patch = patch(:); %這樣是按照列的順序來排列的 patch = patch - meanPatch;patch = ZCAWhite * patch;%用同樣的參數對該patch進行白化處理features = feedForwardAutoencoder(optTheta, hiddenSize, visibleSize, patch); %計算出該patch的輸出值if abs(features(featureNum, 1) - convolvedFeatures(featureNum, imageNum, imageRow, imageCol)) > 1e-9fprintf('Convolved feature does not match activation from autoencoder\n');fprintf('Feature Number : %d\n', featureNum);fprintf('Image Number : %d\n', imageNum);fprintf('Image Row : %d\n', imageRow);fprintf('Image Column : %d\n', imageCol);fprintf('Convolved feature : %0.5f\n', convolvedFeatures(featureNum, imageNum, imageRow, imageCol));fprintf('Sparse AE feature : %0.5f\n', features(featureNum, 1)); error('Convolved feature does not match activation from autoencoder');end enddisp('Congratulations! Your convolution code passed the test.');%% STEP 2c: Implement pooling % Implement pooling in the function cnnPool in cnnPool.m% NOTE: Implement cnnPool in cnnPool.m first! pooledFeatures = cnnPool(poolDim, convolvedFeatures);%% STEP 2d: Checking your pooling % To ensure that you have implemented pooling, we will use your pooling % function to pool over a test matrix and check the results. %將1~64這64個數字弄成一個矩陣,按列的方向依次遞增 testMatrix = reshape(1:64, 8, 8); %直接計算均值pooling值 expectedMatrix = [mean(mean(testMatrix(1:4, 1:4))) mean(mean(testMatrix(1:4, 5:8))); ...mean(mean(testMatrix(5:8, 1:4))) mean(mean(testMatrix(5:8, 5:8))); ];testMatrix = reshape(testMatrix, 1, 1, 8, 8);%squeeze去掉維度為1的那一維 pooledFeatures = squeeze(cnnPool(4, testMatrix));%參數值為4表明是對4*4的區域進行poolingif ~isequal(pooledFeatures, expectedMatrix)disp('Pooling incorrect');disp('Expected');disp(expectedMatrix);disp('Got');disp(pooledFeatures); elsedisp('Congratulations! Your pooling code passed the test.'); end%%====================================================================== %% STEP 3: Convolve and pool with the dataset % In this step, you will convolve each of the features you learned with % the full large images to obtain the convolved features. You will then % pool the convolved features to obtain the pooled features for % classification. % % Because the convolved features matrix is very large, we will do the % convolution and pooling 50 features at a time to avoid running out of % memory. Reduce this number if necessarystepSize = 50; assert(mod(hiddenSize, stepSize) == 0, 'stepSize should divide hiddenSize');%hiddenSize/stepSize為整數,這里分8次進行load stlTrainSubset.mat % loads numTrainImages, trainImages, trainLabels load stlTestSubset.mat % loads numTestImages, testImages, testLabelspooledFeaturesTrain = zeros(hiddenSize, numTrainImages, ... %image是大圖片的尺寸,這里為64floor((imageDim - patchDim + 1) / poolDim), ... %.poolDim為多大的區域pool一次,這里為19,即19*19大小pool一次.floor((imageDim - patchDim + 1) / poolDim) ); %最后算出的pooledFeaturesTrain大小為400*2000*3*3 pooledFeaturesTest = zeros(hiddenSize, numTestImages, ...floor((imageDim - patchDim + 1) / poolDim), ...floor((imageDim - patchDim + 1) / poolDim) ); %pooledFeaturesTest大小為400*3200*3*3tic();for convPart = 1:(hiddenSize / stepSize) %stepSize表示分批次進行原始圖片數據的特征提取,一次進行stepSize個隱含層節點featureStart = (convPart - 1) * stepSize + 1; %選取起始的特征featureEnd = convPart * stepSize; %選取結束的特征fprintf('Step %d: features %d to %d\n', convPart, featureStart, featureEnd); Wt = W(featureStart:featureEnd, :);bt = b(featureStart:featureEnd); fprintf('Convolving and pooling train images\n');convolvedFeaturesThis = cnnConvolve(patchDim, stepSize, ... %參數2表示的是當前"隱含層"節點的個數trainImages, Wt, bt, ZCAWhite, meanPatch);pooledFeaturesThis = cnnPool(poolDim, convolvedFeaturesThis);pooledFeaturesTrain(featureStart:featureEnd, :, :, :) = pooledFeaturesThis; toc();clear convolvedFeaturesThis pooledFeaturesThis;%這些大的變量在不用的情況下全部刪除掉,因為后面用的是test部分fprintf('Convolving and pooling test images\n');convolvedFeaturesThis = cnnConvolve(patchDim, stepSize, ...testImages, Wt, bt, ZCAWhite, meanPatch);pooledFeaturesThis = cnnPool(poolDim, convolvedFeaturesThis);pooledFeaturesTest(featureStart:featureEnd, :, :, :) = pooledFeaturesThis; toc();clear convolvedFeaturesThis pooledFeaturesThis;end% You might want to save the pooled features since convolution and pooling takes a long time save('cnnPooledFeatures.mat', 'pooledFeaturesTrain', 'pooledFeaturesTest'); toc();%%====================================================================== %% STEP 4: Use pooled features for classification % Now, you will use your pooled features to train a softmax classifier, % using softmaxTrain from the softmax exercise. % Training the softmax classifer for 1000 iterations should take less than % 10 minutes.% Add the path to your softmax solution, if necessary % addpath /path/to/solution/% Setup parameters for softmax softmaxLambda = 1e-4;%權值懲罰系數 numClasses = 4; % Reshape the pooledFeatures to form an input vector for softmax softmaxX = permute(pooledFeaturesTrain, [1 3 4 2]);%permute是調整順序,把圖片放在最后 softmaxX = reshape(softmaxX, numel(pooledFeaturesTrain) / numTrainImages,...numTrainImages); %為每一張圖片得到的特征向量長度 softmaxY = trainLabels;options = struct; options.maxIter = 200; softmaxModel = softmaxTrain(numel(pooledFeaturesTrain) / numTrainImages,...%第一個參數為inputSizenumClasses, softmaxLambda, softmaxX, softmaxY, options);%%====================================================================== %% STEP 5: Test classifer % Now you will test your trained classifer against the test imagessoftmaxX = permute(pooledFeaturesTest, [1 3 4 2]); softmaxX = reshape(softmaxX, numel(pooledFeaturesTest) / numTestImages, numTestImages); softmaxY = testLabels;[pred] = softmaxPredict(softmaxModel, softmaxX); acc = (pred(:) == softmaxY(:)); acc = sum(acc) / size(acc, 1); fprintf('Accuracy: %2.3f%%\n', acc * 100);%計算預測準確度% You should expect to get an accuracy of around 80% on the test images.cnnConvolve.m
function convolvedFeatures = cnnConvolve(patchDim, numFeatures, images, W, b, ZCAWhite, meanPatch) %cnnConvolve Returns the convolution of the features given by W and b with %the given images % % Parameters: % patchDim - patch (feature) dimension % numFeatures - number of features % images - large images to convolve with, matrix in the form % images(r, c, channel, image number) % W, b - W, b for features from the sparse autoencoder % ZCAWhite, meanPatch - ZCAWhitening and meanPatch matrices used for % preprocessing % % Returns: % convolvedFeatures - matrix of convolved features in the form % convolvedFeatures(featureNum, imageNum, imageRow, imageCol)patchSize = patchDim*patchDim; assert(numFeatures == size(W,1), 'W should have numFeatures rows'); numImages = size(images, 4);%第4維的大小,即圖片的樣本數 imageDim = size(images, 1);%第1維的大小,即圖片的行數 imageChannels = size(images, 3);%第3維的大小,即圖片的通道數 assert(patchSize*imageChannels == size(W,2), 'W should have patchSize*imageChannels cols');% Instructions: % Convolve every feature with every large image here to produce the % numFeatures x numImages x (imageDim - patchDim + 1) x (imageDim - patchDim + 1) % matrix convolvedFeatures, such that % convolvedFeatures(featureNum, imageNum, imageRow, imageCol) is the % value of the convolved featureNum feature for the imageNum image over % the region (imageRow, imageCol) to (imageRow + patchDim - 1, imageCol + patchDim - 1) % % Expected running times: % Convolving with 100 images should take less than 3 minutes % Convolving with 5000 images should take around an hour % (So to save time when testing, you should convolve with less images, as % described earlier)% -------------------- YOUR CODE HERE -------------------- % Precompute the matrices that will be used during the convolution. Recall % that you need to take into account the whitening and mean subtraction % stepsWT = W*ZCAWhite;%等效的網絡參數 b_mean = b - WT*meanPatch;%針對未均值化的輸入數據需要加入該項% --------------------------------------------------------convolvedFeatures = zeros(numFeatures, numImages, imageDim - patchDim + 1, imageDim - patchDim + 1); for imageNum = 1:numImagesfor featureNum = 1:numFeatures% convolution of image with feature matrix for each channelconvolvedImage = zeros(imageDim - patchDim + 1, imageDim - patchDim + 1);for channel = 1:imageChannels% Obtain the feature (patchDim x patchDim) needed during the convolution% ---- YOUR CODE HERE ----offset = (channel-1)*patchSize;feature = reshape(WT(featureNum,offset+1:offset+patchSize), patchDim, patchDim);%取一個權值圖像塊出來im = images(:,:,channel,imageNum);% Flip the feature matrix because of the definition of convolution, as explained laterfeature = flipud(fliplr(squeeze(feature)));% Obtain the imageim = squeeze(images(:, :, channel, imageNum));%取一張圖片出來% Convolve "feature" with "im", adding the result to convolvedImage% be sure to do a 'valid' convolution% ---- YOUR CODE HERE ----convolvedoneChannel = conv2(im, feature, 'valid');convolvedImage = convolvedImage + convolvedoneChannel;%直接把3通道的值加起來,理由:3通道相當于有3個feature-map,類似于cnn第2層以后的輸入。% ------------------------end% Subtract the bias unit (correcting for the mean subtraction as well)% Then, apply the sigmoid function to get the hidden activation% ---- YOUR CODE HERE ----convolvedImage = sigmoid(convolvedImage+b_mean(featureNum));% ------------------------% The convolved feature is the sum of the convolved values for all channelsconvolvedFeatures(featureNum, imageNum, :, :) = convolvedImage;end endendfunction sigm = sigmoid(x)sigm = 1./(1+exp(-x)); endcnnPool.m
function pooledFeatures = cnnPool(poolDim, convolvedFeatures) %cnnPool Pools the given convolved features % % Parameters: % poolDim - dimension of pooling region % convolvedFeatures - convolved features to pool (as given by cnnConvolve) % convolvedFeatures(featureNum, imageNum, imageRow, imageCol) % % Returns: % pooledFeatures - matrix of pooled features in the form % pooledFeatures(featureNum, imageNum, poolRow, poolCol) % numImages = size(convolvedFeatures, 2);%圖片數 numFeatures = size(convolvedFeatures, 1);%特征數 convolvedDim = size(convolvedFeatures, 3);%圖片的行數 resultDim = floor(convolvedDim / poolDim); pooledFeatures = zeros(numFeatures, numImages, resultDim, resultDim);% -------------------- YOUR CODE HERE -------------------- % Instructions: % Now pool the convolved features in regions of poolDim x poolDim, % to obtain the % numFeatures x numImages x (convolvedDim/poolDim) x (convolvedDim/poolDim) % matrix pooledFeatures, such that % pooledFeatures(featureNum, imageNum, poolRow, poolCol) is the % value of the featureNum feature for the imageNum image pooled over the % corresponding (poolRow, poolCol) pooling region % (see http://ufldl/wiki/index.php/Pooling ) % % Use mean pooling here. % -------------------- YOUR CODE HERE -------------------- for imageNum = 1:numImagesfor featureNum = 1:numFeaturesfor poolRow = 1:resultDimoffsetRow = 1+(poolRow-1)*poolDim;for poolCol = 1:resultDimoffsetCol = 1+(poolCol-1)*poolDim;patch = convolvedFeatures(featureNum,imageNum,offsetRow:offsetRow+poolDim-1,...offsetCol:offsetCol+poolDim-1);%取出一個patchpooledFeatures(featureNum,imageNum,poolRow,poolCol) = mean(patch(:));%使用均值poolendendend endend參考文獻
卷積特征提取
池化
Deep learning:十七(Linear Decoders,Convolution和Pooling)
Deep learning:二十三(Convolution和Pooling練習)
吳恩達 Andrew Ng 的公開課
池化方法總結(Pooling)
卷積神經網絡
總結
以上是生活随笔為你收集整理的UFLDL教程:Exercise:Convolution and Pooling的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 农行燃梦信用卡免息期有多长?一招教你享受
- 下一篇: 汇丰京东铂金会员联名卡好下卡吗?网申面签