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权重。代码:

% 参考前面章节给出的代码addpath minFunc/sae1options.Method = ‘lbfgs’;sae1options.maxIter = 100; % 迭代次数,调试时可设为较小值sae1options.display = ‘on’;[sae1OptTheta,cost] = minFunc( @(p) sparseAutoencoderCost(p, … inputSize, hiddenSizeL1, … lambda, sparsityParam, … beta, trainData), … sae1Theta, sae1options);Step 3. 训练第二层Sparse Autoencoder权重。代码:% 参考前面章节给出的代码ftoptions.Method = ‘lbfgs’; ftoptions.maxIter = 100; % 迭代次数,调试时可设为较小值ftoptions.display = ‘on’;[sae2OptTheta,cost] = minFunc( @(p) sparseAutoencoderCost(p, …hiddenSizeL1, hiddenSizeL2, …lambda, sparsityParam, …beta, sae1Features), …sae2Theta, ftoptions);Step 4. 训练Softmax分类器权重。代码:smOptions.maxIter = 100; %Softmax训练迭代次数sampleN = size(sae2Features,2); %[输入维数,样本数][softmaxModel] = softmaxTrain(hiddenSizeL2, numClasses, lambda, sae2Features, trainLabels, smOptions); %训练Softmax分类器saeSoftmaxOptTheta = reshape(softmaxModel.optTheta,hiddenSizeL2*numClasses,1);Step 5.Finetune softmax model。代码:% 参考前面章节给出的代码ftoptions.Method = ‘lbfgs’; ftoptions.maxIter = 100; % 迭代次数,调试时可设为较小值ftoptions.display = ‘on’;[stackedAEOptTheta,cost] = minFunc( @(p) stackedAECost(p, …inputSize, …hiddenSizeL2, numClasses, netconfig, …lambda, trainData, trainLabels), …stackedAETheta, ftoptions);

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

W1 = stack{1}.w;b1 = stack{1}.b;W2 = stack{2}.w;b2 = stack{2}.b;sampleN = size(data,2);h1 = sigmoid(W1*data + repmat(b1,1,sampleN));h2 = sigmoid(W2*h1 + repmat(b2,1,sampleN));y = softmaxTheta*h2;[tmp,pred] = max(y);三、stackedAECost.m 计算整个模型的误差和所有权重梯度。用于fine-tune。这个.m文件花了我很长很长时间。。原本想尽量用矩阵形式去掉for,但是最后还是保留了两个,为了结构清晰。我的建议是,求导仔细,大胆编程。代码:% ———-初始化值——————-format longsampleN = size(data,2);outputSize = size(groundTruth,1);W1 = stack{1}.w;b1 = stack{1}.b;W2 = stack{2}.w;b2 = stack{2}.b;W3 = softmaxTheta;N2 = size(W2,2); %第一隐层节点数N3 = size(W3,2); %第二隐层节点数A1 = data;A2 = sigmoid(W1*A1+repmat(b1,1,sampleN));A3 = sigmoid(W2*A2+repmat(b2,1,sampleN));A4 = exp(W3*A3) ./ repmat(sum(exp(W3*A3)),outputSize,1);P = A4;%输出值X = A1;%输入值Y = groundTruth; %label值% ———–损失函数——————–cost = -1/sampleN * sum(sum(Y.*log(P)));%损失函数% ———–softmax层权值梯度———–softmaxThetaGrad = -1/sampleN * (Y-P)*A3′; %softmax层权值梯度% ———–第二隐层权值梯度————-% 完全按照求导公式来,弄了很久dEdA3 = zeros(N3,sampleN);sumK = zeros(N3,sampleN);for k = 1:outputSizesumL = zeros(N3,sampleN);for l = 1:outputSizesumL = sumL + (W3(l,:)-W3(k,:))’ * exp((W3(l,:)-W3(k,:))*A3);endsumK = sumK + repmat(Y(k,:),N3,1) .* repmat(A4(k,:),N3,1) .* sumL;enddEdA3 = sumK;dEdO3 = dEdA3.*A3.*(1-A3);stackgrad{2}.w = 1/sampleN * dEdO3*A2′;stackgrad{2}.b = 1/sampleN * sum(dEdO3,2);% ———–第一隐层权值梯度————-dEdO2 = W2’*dEdO3.*A2.*(1-A2);stackgrad{1}.w = 1/sampleN * dEdO2*X’;stackgrad{1}.b = 1/sampleN * sum(dEdO2,2);运行结果如果困难是堵砖墙,拍拍它说你还不够高。

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

相关文章:

你感兴趣的文章:

标签云: