0步:初始化一些参数和常数

 

1步:利用训练样本集训练第一个稀疏编码器

 

2步:利用训练样本集训练第二个稀疏编码器

 

3步:利用第二个稀疏编码器提取到的特征训练softmax回归模型

 

4步:利用误差反向传播进行微调

 

5步:利用测试样本集对得到的分类器进行精度测试

下面将程序实现过程中的关键代码post出,欢迎各位网友指点!

stackedAEExercise.m

clc
clear
close all addpath ../common/
addpath ../common/minFunc %%======================================================================
%% STEP : 设置多层自编码器的相关参数
% 整个网络的输入输出结构
inputSize = * ;
numClasses = ;
% 稀疏自编码器结构
hiddenSizeL1 = ; % Layer Hidden Size
hiddenSizeL2 = ; % Layer Hidden Size
% 一些权值
sparsityParam = 0.1; % desired average activation of the hidden units.that is ρ in the lecture
beta = ; % weight of sparsity penalty term
lambda = 3e-; % weight decay parameter %%======================================================================
%% STEP : 载入MNSIT数据集及标签集
addpath mnist\
trainData = loadMNISTImages('mnist/train-images-idx3-ubyte');
trainLabels = loadMNISTLabels('mnist/train-labels-idx1-ubyte');
trainLabels(trainLabels == ) = ; % Remap to since our labels need to start from %%======================================================================
%% STEP : 训练第一个稀疏自编码器(训练样本集为trainData,看作是无标签训练样本集) % Randomly initialize the parameters
sae1Theta = initializeParameters(hiddenSizeL1, inputSize); % 利用无标签样本集对稀疏自编码器进行学习,学习到的参数存放在向量sae1OptTheta中
% 优化函数的一些参数设置
options.Method = 'lbfgs';
options.maxIter = ; % Maximum number of iterations of L-BFGS to run
options.display = 'on';
% 调用优化函数,得到优化向量sae1OptTheta [sae1OptTheta, ~] = minFunc( @(p) sparseAutoencoderCost(p, ...
inputSize, hiddenSizeL1, ... %输入维数、输出维数
lambda, sparsityParam, ...
beta, trainData), ...
sae1Theta, options);
%save('sae1OptTheta.mat','sae1OptTheta')
% % 权值可视化(Visualize weights)
% W11 = reshape(sae1OptTheta(:hiddenSizeL1 * inputSize), hiddenSizeL1, inputSize);
% display_network(W11');
% load('sae1OptTheta.mat'); %%======================================================================
%% STEP : 训练第二个稀疏自编码器(训练数据是第一个自编码器提取到的特征) % 求解第一个自编码器的输出sae1Features(维数为hiddenSizeL1)
[sae1Features] = feedForwardAutoencoder(sae1OptTheta, hiddenSizeL1, ...
inputSize, trainData); % Randomly initialize the parameters
sae2Theta = initializeParameters(hiddenSizeL2, hiddenSizeL1); % 开始训练第二个自编码器,输入维数是hiddenSizeL1,输出维数是hiddenSizeL2,优化向量存放在sae2OptTheta中
[sae2OptTheta, ~] = minFunc( @(p) sparseAutoencoderCost(p, ...
hiddenSizeL1, hiddenSizeL2, ... %输入维数、输出维数
lambda, sparsityParam, ...
beta, sae1Features), ...
sae2Theta, options);
% save('sae2OptTheta.mat','sae2OptTheta')
% % Visualize weights
% % W21 = reshape(sae2OptTheta(:hiddenSizeL2 * hiddenSizeL1), hiddenSizeL2, hiddenSizeL1);
% % display_network(W21'); %无法可视化!!
% load('sae2OptTheta.mat');
%%======================================================================
%% STEP : 训练softmax classifier(它的输入为第二个自编码器提取到的特征sae2Features) % 求解第二个自编码器的输出sae1Features(维数为hiddenSizeL2)
[sae2Features] = feedForwardAutoencoder(sae2OptTheta, hiddenSizeL2, ...
hiddenSizeL1, sae1Features); % Randomly initialize the parameters
saeSoftmaxTheta = 0.005 * randn(hiddenSizeL2 * numClasses, ); % 开始优化softmax classifier,得到优化向量
options.maxIter = ;
softmaxModel = softmaxTrain(size(sae2Features,), numClasses, lambda, ...
sae2Features, trainLabels, options);
saeSoftmaxOptTheta=softmaxModel.optTheta(:);
% load('saeSoftmaxOptTheta.mat') %%======================================================================
%% STEP : 微调多层自编码器 % 利用稀疏自编码(stack)和softmax分类器(saeSoftmaxOptTheta)学习到的参数作为微调模型的初始值
% 稀疏自编码的参数stack
stack = cell(,);%存放稀疏自编码器参数的元胞
stack{}.w = reshape(sae1OptTheta(:hiddenSizeL1*inputSize), ...
hiddenSizeL1, inputSize);
stack{}.b = sae1OptTheta(*hiddenSizeL1*inputSize+:*hiddenSizeL1*inputSize+hiddenSizeL1);
stack{}.w = reshape(sae2OptTheta(:hiddenSizeL2*hiddenSizeL1), ...
hiddenSizeL2, hiddenSizeL1);
stack{}.b = sae2OptTheta(*hiddenSizeL2*hiddenSizeL1+:*hiddenSizeL2*hiddenSizeL1+hiddenSizeL2);
[stackparams, netconfig] = stack2params(stack);%所有stack转化为向量形式,并提取稀疏自编码器的结构
% 整个模型参数(saeSoftmaxOptTheta+stack)
stackedAETheta = [ saeSoftmaxOptTheta ; stackparams ]; % 是否进行梯度检验
DEBUG=;
if DEBUG
checkStackedAECost()
end % 开始进行微调优化 (Use minFunc to minimize the function)
[stackedAEOptTheta, cost] = minFunc( @(p) stackedAECost(p, ...
inputSize, hiddenSizeL2,...%输入层维数、最后一个稀疏编码器隐藏层维数
numClasses, netconfig, ...%稀疏自编码器的结构
lambda, trainData, trainLabels), ...
stackedAETheta, options); %%======================================================================
%% STEP : Test
% 获取有标签样本集
testData = loadMNISTImages('mnist/t10k-images-idx3-ubyte');
testLabels = loadMNISTLabels('mnist/t10k-labels-idx1-ubyte');
testLabels(testLabels == ) = ; % Remap to % 进行预测(微调后的)
[pred] = stackedAEPredict(stackedAEOptTheta, inputSize, hiddenSizeL2, ...
numClasses, netconfig, testData);
acc = mean(testLabels(:) == pred(:));% 计算预测精度
fprintf('After Finetuning Test Accuracy: %0.3f%%\n', acc * ); % 进行预测(微调前的)
[pred] = stackedAEPredict(stackedAETheta, inputSize, hiddenSizeL2, ...
numClasses, netconfig, testData);
acc = mean(testLabels(:) == pred(:));% 计算预测精度
fprintf('Before Finetuning Test Accuracy: %0.3f%%\n', acc * ); % Accuracy is the proportion of correctly classified images
% The results for our implementation were: % Before Finetuning Test Accuracy: 87.7%
% After Finetuning Test Accuracy: 97.6%
%
% If your values are too low (accuracy less than %), you should check
% your code for errors, and make sure you are training on the
% entire data set of 28x28 training images
% (unless you modified the loading code, this should be the case)

 stackedAEPredict.m

% stackedAEPredict: Takes a trained theta and a test data set,
% and returns the predicted labels for each example. % theta: trained weights from the autoencoder
% visibleSize: the number of input units
% hiddenSize: the number of hidden units *at the 2nd layer*
% numClasses: the number of categories
% data: Our matrix containing the training data as columns. So, data(:,i) is the i-th training example. % Your code should produce the prediction matrix
% pred, where pred(i) is argmax_c P(y(c) | x(i)). function [pred] = stackedAEPredict(theta, inputSize, hiddenSize, numClasses, netconfig, data) %% Unroll theta parameter % We first extract the part which compute the softmax gradient
softmaxTheta = reshape(theta(:hiddenSize*numClasses), numClasses, hiddenSize); % Extract out the "stack"
stack = params2stack(theta(hiddenSize*numClasses+:end), netconfig); %% ---------- YOUR CODE HERE --------------------------------------
% Instructions: Compute pred using theta assuming that the labels start from . %% 前向传播计算
a{}=data;
depth=numel(netconfig.layersizes);
for i=:depth
a{i+}=sigmoid(bsxfun(@plus,stack{i}.w*a{i},stack{i}.b));
end %% softmax模型的输出Htheta
softmaxData=a{depth+};%softmax的输入即为stack自编码器最后一层的输出
M=softmaxTheta*softmaxData;%矩阵M
M=bsxfun(@minus,M,max(M));%减去行向量α,防止数据溢出
Htheta=bsxfun(@rdivide,exp(M),sum(exp(M)));%softmax模型的假设函数输出 %% 计算Htheta每一列最大元素所在位置,即为该列所对应样本的类别
[~,pred]=max(Htheta); end % You might find this useful
function sigm = sigmoid(x)
sigm = ./ ( + exp(-x));
end

stackedAECost.m

%{
Takes a trained softmaxTheta and a training data set with labels,
and returns cost and gradient using a stacked autoencoder model. Used for finetuning.
输入:
theta:整个网络的权值向量
visibleSize: 网络的输入层维数
hiddenSize: 最后一个稀疏自编码器的隐藏层维数
numClasses: 类别总数
netconfig: the network configuration of the stack
lambda: the weight regularization penalty
data: 训练样本集,data(:,i) is the i-th training example.
labels: 训练样本集的标签, where labels(i) is the label for the i-th training example
输出:
cost:代价函数
grad:梯度向量
%} function [ cost, grad ] = stackedAECost(theta, ...
inputSize, hiddenSize, ...%输入层维数、最后一个稀疏编码器隐藏层维数
numClasses, netconfig, ...%总类数、稀疏自编码器的结构
lambda, data, labels) %% 从输入的网络参数向量theta中得到softmax分类器和稀疏自编码器的参数
softmaxTheta = reshape(theta(:hiddenSize*numClasses), numClasses, hiddenSize);%softmax的参数矩阵
stack = params2stack(theta(hiddenSize*numClasses+:end), netconfig);% Extract out the "stack" %% 初始化
%样本个数
numCases = size(data, );
%样本标签矩阵groundTruth(即I阵)
groundTruth = full(sparse(labels, :numCases, ));
% softmax分类器的梯度
softmaxThetaGrad = zeros(size(softmaxTheta));
% 稀疏自编码器的梯度(权值w和偏执项b)
stackgrad = cell(size(stack));
for d = :numel(stack)
stackgrad{d}.w = zeros(size(stack{d}.w));
stackgrad{d}.b = zeros(size(stack{d}.b));
end %% 前向传播算法
% 初始化工作
depth=numel(stack);% 稀疏自编码器隐藏层的层数(the layor of the network)
z=cell(depth+,); % stack网络各层的激励值
a=cell(depth+,); % stack网络各层的激励值
a{}=data; % 输入层数据 % 各稀疏自编码器输出a{},...,a{depth+}
for i=:depth
%各稀疏编码器提取到的features
z{i+}=bsxfun(@plus,stack{i}.w*a{i},stack{i}.b);
a{i+}=sigmoid(z{i+});
end % softmax分类器的输出Htheta
softmaxData=a{depth+};%softmax的输入即为stack自编码器最后一层的输出
M=softmaxTheta*softmaxData;%矩阵M
M=bsxfun(@minus,M,max(M));%减去行向量α,防止数据溢出
Htheta=bsxfun(@rdivide,exp(M),sum(exp(M)));%softmax分类器的假设函数输出 %% 多层网络代价函数的计算(%要对整个网络的所有参数,包括softmax分类器和自编码器的所有参数)
cost=-sum(sum(groundTruth.*log(Htheta)))/numCases+lambda*sum(softmaxTheta(:).^)/; %% 梯度计算 % softmax层的梯度
softmaxThetaGrad=-(groundTruth-Htheta)*softmaxData'/numCases+lambda*softmaxTheta; % 稀疏自编码层
% 敏感度
delta=cell(depth+,);
delta{depth+}=-softmaxTheta'*(groundTruth-Htheta).*a{depth+1}.*(1-a{depth+1});
for i=depth:-:
delta{i}=stack{i}.w'*delta{i+1}.*(a{i}).*(1-a{i});
end
% 梯度值
for i=depth:-:
stackgrad{i}.w=delta{i+}*a{i}'/numCases;
stackgrad{i}.b=sum(delta{i+},)'/numCases;
if size(stackgrad{i}.b,)~=
stackgrad{i}.b=stackgrad{i}.b';
end
end %% Roll gradient vector
grad = [softmaxThetaGrad(:) ; stack2params(stackgrad)]; end % You might find this useful
function sigm = sigmoid(x)
sigm = ./ ( + exp(-x));
end

UFLDL教程(六)之栈式自编码器的更多相关文章

  1. UFLDL教程(一)---稀疏自编码器

    神经网络模型 简单的神经网络 前向传播 代价函数 对于单个例子 .其代价函数为: 给定一个包括m个例子的数据集,我们能够定义总体代价函数为: 以上公式中的第一项  是一个均方差项. 第二项是一个规则化 ...

  2. Deep Learning 8_深度学习UFLDL教程:Stacked Autocoders and Implement deep networks for digit classification_Exercise(斯坦福大学深度学习教程)

    前言 1.理论知识:UFLDL教程.Deep learning:十六(deep networks) 2.实验环境:win7, matlab2015b,16G内存,2T硬盘 3.实验内容:Exercis ...

  3. Deep Learning 9_深度学习UFLDL教程:linear decoder_exercise(斯坦福大学深度学习教程)

    前言 实验内容:Exercise:Learning color features with Sparse Autoencoders.即:利用线性解码器,从100000张8*8的RGB图像块中提取颜色特 ...

  4. Deep Learning 12_深度学习UFLDL教程:Sparse Coding_exercise(斯坦福大学深度学习教程)

    前言 理论知识:UFLDL教程.Deep learning:二十六(Sparse coding简单理解).Deep learning:二十七(Sparse coding中关于矩阵的范数求导).Deep ...

  5. Deep Learning 19_深度学习UFLDL教程:Convolutional Neural Network_Exercise(斯坦福大学深度学习教程)

    理论知识:Optimization: Stochastic Gradient Descent和Convolutional Neural Network CNN卷积神经网络推导和实现.Deep lear ...

  6. C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)

    微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...

  7. 栈式自动编码器(Stacked AutoEncoder)

    起源:自动编码器 单自动编码器,充其量也就是个强化补丁版PCA,只用一次好不过瘾. 于是Bengio等人在2007年的  Greedy Layer-Wise Training of Deep Netw ...

  8. Deep Learning 7_深度学习UFLDL教程:Self-Taught Learning_Exercise(斯坦福大学深度学习教程)

    前言 理论知识:自我学习 练习环境:win7, matlab2015b,16G内存,2T硬盘 练习内容及步骤:Exercise:Self-Taught Learning.具体如下: 一是用29404个 ...

  9. 基于NodeJS的全栈式开发

    前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异.痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的 NodeJS,试 ...

随机推荐

  1. shell脚本实现检測回文字符串

    全部回文字的结构特征例如以下: 假设字符数是偶数,那么它在结构上表现为:一个字符序列连着还有一个字符同样但次序恰好相反的字符序列. 假设字符数为奇数,那么它在结构上表现为:一个字符序列连着还有一个字符 ...

  2. [Redux] Using withRouter() to Inject the Params into Connected Components

    We will learn how to use withRouter() to inject params provided by React Router into connected compo ...

  3. 【转】学习Flex ActionScript 3.0 强烈推荐电子书

    学习Flex ActionScript 3.0 强烈推荐电子书 AdvancED ActionScript 3.0 Animation(<Make things  move>姐妹篇,强烈推 ...

  4. iOS之ASIHttp简单的网络请求实现

    描述: ASIHttpRequest是应用第三方库的方法,利用代码快,减少代码量,提高效率 准备工作: 一.导入第三方库ASIHttpRequest 二.会报很多的错,原因有两个,一个是要导入Xcod ...

  5. ThreadLocal 笔记

    synchronized 同步的机制可以解决多线程并发问题,这种解决方案下,多个线程访问到的都是同一份变量的内容.为了防止在多线程访问的过程中,可能会出现的并发错误.不得不对多个线程的访问进行同步,这 ...

  6. SQL排序 空值的后面

    按sort排序,sort为空的在后面 end),sort

  7. 【转】Angular Input格式化

    今天在Angular中文群有位同学问到:如何实现对input box的格式化.如下的方式对吗? <input type="text" ng-model="demo. ...

  8. java web hello world

    首先在eclipse 里面创建一个java 动态项目, 记住路径,这里是直接通过根目录直接访问的webContent目录下面 的文件, 创建好后 ,在本地配置Tomcat服务器, 将server加入到 ...

  9. C# DateTime显示时间格式的使用

    代码DateTime.ToString() Patterns All the patterns: 0 MM/dd/yyyy 08/22/2006 1 dddd, dd MMMM yyyy Tuesda ...

  10. vc调用BCB的dll 参数传递 报错

    可能原因: 调用方式约定不一致. 函数调用约定如下: 1. __cdecl:C 和 C++ 程序的缺省调用规范. 2. __stdcall:标准调用约定(即WINAPI调用约定),也就是pascal调 ...