UFLDL学习笔记5(Building Deep Networks for Classification)

UFLDL学习笔记5(Building Deep Networks for Classification)

最近在学习UFLDL Tutorial,这是一套关于无监督学习的教程。在此感觉Andrew Ng做的真的是非常认真。下面把我的代码贴出来,方便大家学习调试。所有代码已经过matlab调试通过。

 

Building Deep Networks for Classification练习

这一章是用fine-tune的多层网络进行mnist数字的识别。特征提取层使用unlabeld数据训练多层的sparse autoencoder,分类层使用labeled数据训练softmax regression分类器,最后再用labeled数据对整个网络进行fine-tune。本章需要用到前面几章的一些.m文件。因此需要先做前面章节的练习。

本章识别mnist的网络结构图如下

流程

(1)逐层训练Sparse Autoencoder权重(先W1,再W2)

(2)以Sparse Autoencoder的输出训练Softmax分类器权重(W3)

(3)用labeled的数据fine-tune所有权重。

优点

(1)物理意义更明显,逐层抽取特征。

(2)与普通ANN相比,避免陷入局部最优。

其它

(1)若labeled数据多则fine-tune有效。

(2)层间的非线性映射函数是为了增加非线性表征力,若层间是线性映射则无论多少层都是线性的。

 

代码编写

好了,下面贴出我的matlab代码。一共有3个.m文件需要自己编写。

一、stackedAEExercise.m 主函数

Step 0. 参数设置。无需编写

Step 1. 读取mnist数据。无需编写。

Step 2. 训练第一层Sparse Autoencoer权重。代码:

 

[plain] view plaincopy
 
  1. % 参考前面章节给出的代码  
  2. addpath minFunc/  
  3. sae1options.Method = 'lbfgs';   
  4. sae1options.maxIter = 100;<span style="white-space:pre">    </span>  % 迭代次数,调试时可设为较小值  
  5. sae1options.display = 'on';  
  6. [sae1OptTheta,cost] = minFunc( @(p) sparseAutoencoderCost(p, ...  
  7.                                    inputSize, hiddenSizeL1, ...  
  8.                                    lambda, sparsityParam, ...  
  9.                                    beta, trainData), ...  
  10.                               sae1Theta, sae1options);  

Step 3. 训练第二层Sparse Autoencoder权重。代码:

 

 

[plain] view plaincopy
 
  1. % 参考前面章节给出的代码  
  2. ftoptions.Method = 'lbfgs';   
  3. ftoptions.maxIter = 100;      % 迭代次数,调试时可设为较小值  
  4. ftoptions.display = 'on';  
  5. [sae2OptTheta,cost] = minFunc( @(p) sparseAutoencoderCost(p, ...  
  6.                                    hiddenSizeL1, hiddenSizeL2, ...  
  7.                                    lambda, sparsityParam, ...  
  8.                                    beta, sae1Features), ...  
  9.                               sae2Theta, ftoptions);  

Step 4. 训练Softmax分类器权重。代码:

 

 

[plain] view plaincopy
 
  1. smOptions.maxIter = 100; %Softmax训练迭代次数  
  2. sampleN = size(sae2Features,2);  %[输入维数,样本数]  
  3. [softmaxModel] = softmaxTrain(hiddenSizeL2, numClasses, lambda, sae2Features, trainLabels, smOptions);  %训练Softmax分类器  
  4. saeSoftmaxOptTheta = reshape(softmaxModel.optTheta,hiddenSizeL2*numClasses,1);  

Step 5. Finetune softmax model。代码:

 

 

[plain] view plaincopy
 
  1. % 参考前面章节给出的代码  
  2. ftoptions.Method = 'lbfgs';   
  3. ftoptions.maxIter = 100;      % 迭代次数,调试时可设为较小值  
  4. ftoptions.display = 'on';  
  5. [stackedAEOptTheta,cost] = minFunc( @(p) stackedAECost(p, ...  
  6.                                    inputSize, ...  
  7.                                         hiddenSizeL2, numClasses, netconfig, ...  
  8.                                         lambda, trainData, trainLabels), ...  
  9.                               stackedAETheta, ftoptions);  

 

 

二、stackedAEPredict.m 根据模型预测结果。代码:

[plain] view plaincopy
 
  1. W1 = stack{1}.w;  
  2. b1 = stack{1}.b;  
  3. W2 = stack{2}.w;  
  4. b2 = stack{2}.b;  
  5.   
  6. sampleN = size(data,2);  
  7. h1 = sigmoid(W1*data + repmat(b1,1,sampleN));  
  8. h2 = sigmoid(W2*h1 + repmat(b2,1,sampleN));  
  9. y = softmaxTheta*h2;  
  10. [tmp,pred] = max(y);  


三、stackedAECost.m 计算整个模型的误差和所有权重梯度。用于fine-tune。这个.m文件花了我很长很长时间。。原本想尽量用矩阵形式去掉for,但是最后还是保留了两个,为了结构清晰。我的建议是,求导仔细,大胆编程。代码:

 

[plain] view plaincopy
 
  1. % ----------初始化值-------------------  
  2. format long  
  3. sampleN = size(data,2);  
  4. outputSize = size(groundTruth,1);  
  5.   
  6. W1 = stack{1}.w;  
  7. b1 = stack{1}.b;  
  8. W2 = stack{2}.w;  
  9. b2 = stack{2}.b;  
  10. W3 = softmaxTheta;  
  11.   
  12. N2 = size(W2,2);    %第一隐层节点数  
  13. N3 = size(W3,2);    %第二隐层节点数  
  14.   
  15. A1 = data;  
  16. A2 = sigmoid(W1*A1+repmat(b1,1,sampleN));  
  17. A3 = sigmoid(W2*A2+repmat(b2,1,sampleN));  
  18. A4 = exp(W3*A3) ./ repmat(sum(exp(W3*A3)),outputSize,1);  
  19.   
  20. P = A4;             %输出值  
  21. X = A1;             %输入值  
  22. Y = groundTruth;    %label值  
  23.   
  24. % -----------损失函数--------------------  
  25. cost = -1/sampleN * sum(sum(Y.*log(P)));            %损失函数  
  26.   
  27. % -----------softmax层权值梯度-----------  
  28. softmaxThetaGrad = -1/sampleN * (Y-P)*A3';  %softmax层权值梯度  
  29.   
  30. % -----------第二隐层权值梯度-------------  
  31. % 完全按照求导公式来,弄了很久  
  32. dEdA3 = zeros(N3,sampleN);  
  33. sumK = zeros(N3,sampleN);  
  34. for k = 1:outputSize  
  35.     sumL = zeros(N3,sampleN);  
  36.     for l = 1:outputSize  
  37.         sumL = sumL + (W3(l,:)-W3(k,:))' * exp((W3(l,:)-W3(k,:))*A3);  
  38.     end  
  39.     sumK = sumK + repmat(Y(k,:),N3,1) .* repmat(A4(k,:),N3,1) .* sumL;  
  40. end  
  41. dEdA3 = sumK;  
  42.   
  43. dEdO3 = dEdA3.*A3.*(1-A3);  
  44. stackgrad{2}.w = 1/sampleN * dEdO3*A2';  
  45. stackgrad{2}.b = 1/sampleN * sum(dEdO3,2);  
  46.   
  47. % -----------第一隐层权值梯度-------------  
  48. dEdO2 = W2'*dEdO3.*A2.*(1-A2);  
  49. stackgrad{1}.w = 1/sampleN * dEdO2*X';  
  50. stackgrad{1}.b = 1/sampleN * sum(dEdO2,2);  


运行结果

 


这个表是我在debug的过程中得到的,由表中可看到经过fine-tune的结果要好很多。

小结

本章的练习花了好几天的时间,最主要在Softmax对前面求导花了很长时间。推算也比较复杂。这一章做的效率不高,但做完后就会有一种豁然开朗的感觉。建议各位自行推导这些公式。

posted @ 2015-11-17 19:17  菜鸡一枚  阅读(178)  评论(0编辑  收藏  举报