上节我们看到自编码网络额隐含层可以用于原始数据的降维(其实也可以升维,不过把隐含层的单元设置的比输入维度还要多),换而言之就是特征学习,那么学习到的这些特征就可以用于分类了,本节主要试验下这些特征用于分类的效果。
先以最简单的三层自编码网络为例,先训练自编码网络,在得到编码权值矩阵后,在后接SVM分类器,抽象出来就是如下两个步骤:
这里我们不断调整隐含层单元个数K,并观察最终的分类准确率。
Ok第一步是自编码学习,部分代码如下:
%--------------添加当前文件夹-------------
%% addpath .\DeepLearnToolbox-master\.
currentFolder = pwd;
addpath(genpath(currentFolder))
%% 选择样本
load mnist_uint8;
%% 规定自编码权值
choose_num_train = 20000;
train = double(train_x(1:choose_num_train,:))/255;
auto_net = [784 100];
sae = deep_autocoderW(train,auto_net);
首先设置好工具箱所有路径,加载数据,选择用于自编码的样本个数,确定网络结构,然后进行自编码学习,关于deep_autocoderW函数如下:
function sae = deep_autocoderW(train_x,auto_net)
%% 规定每一层参数--需要修改的参数
sae = saesetup(auto_net);
for i = 1:(numel(auto_net)-1)
sae.ae{i}.activation_function = 'sigm';
sae.ae{i}.learningRate = 1;
sae.ae{i}.inputZeroMaskedFraction = 0.5;
sae.ae{i}.nonSparsityPenalty = 0.05;
end
%% 训练自编码
opts.numepochs = 1;
opts.batchsize = 100;
sae = saetrain(sae, train_x, opts);
在这个函数里,我们要设置一些网络的参数,尤其是稀疏表示的参数设置、激活函数的设置,等等,然互直接调用自编码的训练函数,就可以得到训练好的网络。
训练好了我们只是把自编码网络训练完了,那么我们接下来就是要找到输入经过隐含层的输出是什么?比如这里784维输入经过隐含层会输出K=100维的数据(也就是降维数据,也就是特征提取数据)。很简单就是将784维数据依次乘以编码网络的权值参数即可。接着上面的代码往下提取这100维特征数据:
%% 重新选择分类需要的训练数据与测试数据
num_train = 5000;
train_x = double(train_x(1:num_train,:))/255;
train_y = double(train_y(1:num_train,:));
num_test= 5000;
test_x = double(test_x(1:choose_num_test,:))/255;
test_y = double(test_y(1:choose_num_test,:));
%% 根据自编码网络提取特征
data_train_feature = deep_feature_data(sae,train_x);
data_test_feature = deep_feature_data(sae,test_x);
data_train = data_train_feature{
1};
data_test = data_test_feature{
1<