自我学习就是稀疏编码器串联一个Softmax分类器。上一节看到。训练400次。准确率为98.2%

在此基础上。我们能够搭建我们的第一个深度网络:栈式自编码(2层)+Softmax分类器

 

简单地说。我们把稀疏自编码器的输出作为更高一层稀疏自编码器的输入。

和自我学习非常像,似乎就是新加了一层,可是事实上不然:

新技巧在于。我们这里有个微调的过程。让残差从最高层向输入层传递。微调整个网络权重。

 

这个微调对于网络性能的提高很明显,实际上后面将会看到。

 

网络结构如图所看到的:

从自我学习到深层网络——建立你的第1个深度网络分类器

图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%

 

可见微调对于深度网络的训练起着至关关键的数据。


欢迎參与讨论并关注本博客微博以及知乎个人主页兴许内容继续更新哦~

转载请您尊重作者的劳动,完整保留上述文字以及文章链接,谢谢您的支持!