從自我學習到深層網絡——建立你的第1個深度網絡分類器

自我學習就是稀疏編碼器串聯一個Softmax分類器,上一節看到,訓練400次,準確率爲98.2%

在此基礎上,我們可以搭建我們的第一個深度網絡:棧式自編碼(2層)+Softmax分類器

 

簡單地說,我們把稀疏自編碼器的輸出作爲更高一層稀疏自編碼器的輸入。

和自我學習很像,似乎就是新加了一層,但是其實不然:

新技巧在於,我們這裏有個微調的過程,讓殘差從最高層向輸入層傳遞,微調整個網絡權重。

 

這個微調對於網絡性能的提高非常明顯,實際上後面將會看到。

 

網絡結構如圖所示:


圖1

預先加載

minFunc
computeNumericalGradient
display_network
feedForwardAutoencoder
initializeParameters
loadMNISTImages
loadMNISTLabels
softmaxCost
softmaxTrain
sparseAutoencoderCost
train-images.idx3-ubyte
train-labels.idx1-ubyte


訓練第一個稀疏編碼器

addpath minFunc/
options.Method = 'lbfgs';
options.maxIter = 400;
options.display = 'on';
[sae1OptTheta, cost] = minFunc( @(p) sparseAutoencoderCost(p, ...
                                   inputSize,hiddenSizeL1, ...
                                   lambda, sparsityParam, ...
                                   beta, trainData), ...
                              sae1Theta, options);

訓練第二個稀疏編碼器

sae2options.Method = 'lbfgs';
sae2options.maxIter = 400; 
sae2options.display = 'on';
[sae2OptTheta, cost] = minFunc( @(p) sparseAutoencoderCost(p, ...
                                   hiddenSizeL1, hiddenSizeL2, ...
                                   lambda, sparsityParam, ...
                                   beta, sae1Features), ...
                              sae2Theta, sae2options);

訓練Softmax分類器

smoptions.maxIter = 100;
[softmaxModel] = softmaxTrain(hiddenSizeL2, numClasses, lambda, ...
                            sae2Features,trainLabels, smoptions);
saeSoftmaxOptTheta = softmaxModel.optTheta(:);

微調整個網絡

ftoptions.Method = 'lbfgs';
ftoptions.display = 'on';
ftoptions.maxIter = 100;
[stackedAEOptTheta, cost] = minFunc( @(p) stackedAECost(p,...
                                              inputSize,hiddenSizeL2, ...
                                              numClasses, netconfig, ...
                                              lambda,trainData,trainLabels), ...                                   
                              stackedAETheta, ftoptions);

代價函數與梯度

a2=sigmoid(bsxfun(@plus,stack{1}.w*data,stack{1}.b));
a3=sigmoid(bsxfun(@plus,stack{2}.w*a2,stack{2}.b));
temp=softmaxTheta*a3;
temp=bsxfun(@minus, temp, max(temp, [], 1));%防止數據溢出
hypothesis=bsxfun(@rdivide,exp(temp),sum(exp(temp)));%得到概率矩陣
cost=-(groundTruth(:)'*log(hypothesis(:)))/M+lambda/2*sumsqr(softmaxTheta);%代價函數
softmaxThetaGrad=-(groundTruth-hypothesis)*a3'/M+lambda*softmaxTheta;%梯度函數
Delta3=softmaxTheta'*(hypothesis-groundTruth).*a3.*(1-a3);
Delta2=(stack{2}.w'*Delta3).*a2.*(1-a2);
stackgrad{2}.w=Delta3*a2'/M;
stackgrad{2}.b=sum(Delta3,2)/M;
stackgrad{1}.w=Delta2*data'/M;
stackgrad{1}.b=sum(Delta2,2)/M;

預測函數

a2=sigmoid(bsxfun(@plus,stack{1}.w*data,stack{1}.b));
a3=sigmoid(bsxfun(@plus,stack{2}.w*a2,stack{2}.b));
[~,pred]= max(softmaxTheta*a3);%記錄最大概率的序號而不是最大值

經過2個多小時的訓練,最終效果非常不錯:

BeforeFinetuning Test Accuracy: 86.620%

AfterFinetuning Test Accuracy: 99.800%

 

可見微調對於深度網絡的訓練起着至關重要的作用。


歡迎參與討論並關注本博客微博以及知乎個人主頁後續內容繼續更新哦~

轉載請您尊重作者的勞動,完整保留上述文字以及文章鏈接,謝謝您的支持!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章