基于降噪自编码器-多层感知机(DAE-MLP)的手写数字分类预测MATLAB实战
今天给大家分享基于DAF-MLP的手写数字分类预测MATLAB实战 ,主要从算法原理和代码实战展开。
一、算法原理
1.1 降噪自编码器(Denoising Auto-Encoders, DAE)
在介绍降噪自编码器的原理之前,需要介绍一下自编码器的原理,这样才能方便我们理解降噪自编码器的原理。如图1所示为自编码器的网络结构,它包含有编码阶段和解码阶段。主要应用于数据去噪和数据降维。
图1 自编码器的网络结构
它的编码和解码过程可表达为
其中,W1、b1为编码的权重和偏置,W2、b2为编码的权重和偏置,
自编码器的目的是使输出与输入尽量相同,所以采用的损失函数可表达为:
当损失函数J的值越小,那么经自编码器重构的数据与原始数据就尽可能的相同。但在实际中,我们更关注的是自编码器的隐层表达,而不是实际输出。自编码器真正关心的是隐藏层的特征表达,一个好的表达能够捕获输入信号的稳定结构,以该目的为出发出现了降噪自动编码器。
降噪自动编码器的网络结构如图2所示。降噪自动编码器,首先对干净的输入信号加入噪声产生一个受损的信号。然后将受损信号送入传统的自动编码器中,使其重建回原来的无损信号。降噪自编码器的优点是:它通过人为的增加噪声使模型获得鲁棒性的特征表达。
图2 降噪自编码器的网络结构
1.2 多层感知机(Multilayer Perceptron,MLP)
多层感知机是由单层感知机推广而来,最主要的特点是有多个神经元层。一般将MLP的第一层称为输入层,中间的层为隐藏层,最后一层为输出层。如下图3所示。MLP并没有规定隐藏层的数量,因此可以根据实际处理需求选择合适的隐藏层层数,且对于隐藏层和输出层中每层神经元的个数也没有限制。 多层感知机采用反向传播BP算法训练得到模型的权重和偏置。关于MLP的公式推导这里不做详细的描述,大家可参考下面的文章:手把手教学 - MLP算法实现 - 知乎 (zhihu.com)
图3 多层感知机的网络结构
二、代码实战
%%以手写数字分类预测为例
clc
clear
% load MNIST
load 'mnist_14x14.mat';
% shuffle the training data
X_labels = X_labels + 1;
X_test_labels = X_test_labels + 1;
perm_idx = randperm (size(X,1));
n_all = size(X, 1);
n_train = ceil(n_all * 3 / 4);
n_valid = floor(n_all /4);
X_valid = X(perm_idx(n_train+1:end), :);
X_valid_labels = X_labels(perm_idx(n_train+1:end));
X = X(perm_idx(1:n_train), :);
X_labels = X_labels(perm_idx(1:n_train));
layers = [size(X,2), 500, 500, 10];
n_layers = length(layers);
blayers = [1, 1, 1, 1];
use_tanh = 0;
do_pretrain = 1;
if do_pretrain
Ds = cell(n_layers - 2, 1);
H = X;
H_valid = X_valid;
for l = 1:n_layers-2
% construct DAE and use default configurations
D = default_dae (layers(l), layers(l+1));
D.data.binary = blayers(l);
D.hidden.binary = blayers(l+1);
if use_tanh
if l > 1
D.visible.use_tanh = 1;
end
D.hidden.use_tanh = 1;
else
if D.data.binary
mH = mean(H, 1)';
D.vbias = min(max(log(mH./(1 - mH)), -4), 4);
else
D.vbias = mean(H, 1)';
end
end
D.learning.lrate = 1e-1;
D.learning.lrate0 = 5000;
D.learning.minibatch_sz = 128;
D.noise.drop = 0.2;
D.noise.level = 0;
%D.adagrad.use = 1;
%D.adagrad.epsilon = 1e-8;
D.adadelta.use = 1;
D.adadelta.epsilon = 1e-8;
D.adadelta.momentum = 0.99;
D.valid_min_epochs = 10;
if blayers(l+1)
D.cae.cost = 0.01;
%D.sparsity.target = 0.1;
%D.sparsity.cost = 0.01;
end
D.iteration.n_epochs = 500;
% save the intermediate data after every epoch
D.hook.per_epoch = {@save_intermediate, {sprintf('dae_mnist_%d.mat', l)}};
% print learining process
D.verbose = 0;
% display the progress
D.debug.do_display = 0;
% train RBM
fprintf(1, 'Training DAE (%d)\n', l);
tic;
D = dae (D, H, H_valid, 0.1);
fprintf(1, 'Training is done after %f seconds\n', toc);
H = dae_get_hidden(H, D);
H_valid = dae_get_hidden(H_valid, D);
Ds{l} = D;
end
end
M = default_mlp (layers);
M.output.binary = blayers(end);
M.hidden.use_tanh = use_tanh;
M.valid_min_epochs = 10;
M.dropout.use = 1;
M.hook.per_epoch = {@save_intermediate, {'mlp_mnist.mat'}};
M.learning.lrate = 1e-3;
M.learning.lrate0 = 5000;
M.learning.minibatch_sz = 128;
M.adadelta.use = 1;
M.adadelta.epsilon = 1e-8;
M.adadelta.momentum = 0.99;
M.noise.drop = 0;
M.noise.level = 0;
M.iteration.n_epochs = 100;
if do_pretrain
for l = 1:n_layers-2
M.biases{l+1} = Ds{l}.hbias;
M.W{l} = Ds{l}.W;
end
end
fprintf(1, 'Training MLP\n');
tic;
M = mlp (M, X, X_labels, X_valid, X_valid_labels, 0.1);
fprintf(1, 'Training is done after %f seconds\n', toc);
[pred] = mlp_classify (M, X_test);
n_correct = sum(X_test_labels == pred);
fprintf(2, 'Correctly classified test samples: %d/%d\n', n_correct, size(X_test, 1));
实现结果:
需要调整相关参数才能获得较好的效果,由于运行时间较长,这里不再进行调参后的效果展示,此代码是根据算法原理来写的可供入门DAE的同学学习
文章来源:matlab学习之家