DeepLearning: denoising autoencoder
本文参考hogo在youtube上的视频:https://www.youtube.com/watch?v=t2NQ_c5BFOc&index=49&list=PL6Xpj9I5qXYEcOhn7TqghAJ6NAPrNmUBH
一、理论基础
在训练autoencoder模型时,为了防止过拟合,我们经常采用denoising策略,即在输入中加入噪声,让模型去重构加噪声前的数据,这样的模型泛化能力强,并且对比较鲁棒,抗噪能力强。
加噪方法:
1、以概率v将输入置为0
2、加高斯噪声
输入为x,根据概率加噪后得到
,重构误差表示:x与
,即:

黑色曲线表示原输入的流行,红点表示的样本是加了噪声后的结果,即输入以一定的概率偏离原分布,那么denoising 模型就是要抗这种干扰,拟合出黑色曲线。

在下图上,曲线上的数字2是原输入,偏离曲线的2是加了噪声后的输入,那么denoising autoencoder模型就是要重构出曲线上的2而非加了噪声的2.

二、实验部分
本实验使用deepLearn Toolbox中的sae,关于deepLearnToolbox见博文http://www.cnblogs.com/dupuleng/articles/4340293.html
结果:左图是原始的autoencoder,右图是denoising autoencoder
错误率分别为: 0.394000 0.252000
为加速训练,作者使用的数据规模只有2000,因此错误率比较大,但可以看出denoising的泛化能力更强,将错误率降低了14个百分点。

视频中hogo提供的例子更能看出加噪的作用,我们可以看出加噪后的模型学习出的边缘特征更加明显,但到底要以什么比例加噪?这需要以具体问题具体对待。



实验主要代码:
%% //导入数据 load mnist_uint8; train_num = 2000; train_x = double(train_x)/255; train_x = train_x(1:train_num,:); test_x = double(test_x)/255; test_x = test_x(1:train_num,:); train_y = double(train_y); train_y = train_y(1:train_num,:); test_y = double(test_y); test_y = test_y(1:train_num , : ); %% //实验一:采用denoising autoencoder进行预训练 rand('state',0) sae = saesetup([784 100 100]); % //其实这里nn中的W已经被随机初始化过 sae.ae{1}.activation_function = 'sigm'; sae.ae{1}.learningRate = 1; sae.ae{1}.inputZeroMaskedFraction = 0.; opts.numepochs = 10; opts.batchsize = 100; sae = saetrain(sae, train_x, opts);% //无监督学习,不需要传入标签值,学习好的权重放在sae中, % //并且train_x是最后一个隐含层的输出。 visualize(sae.ae{1}.W{1}(:,2:end)') % Use the SDAE to initialize a FFNN nn = nnsetup([784 100 100 10]); nn.activation_function = 'sigm'; nn.learningRate = 1; %add pretrained weights nn.W{1} = sae.ae{1}.W{1}; % //将sae训练好了的权值赋给nn网络作为初始值,覆盖了前面的随机初始化 % Train the FFNN opts.numepochs = 10; opts.batchsize = 100; nn = nntrain(nn, train_x, train_y, opts); [er, bad] = nntest(nn, test_x, test_y); str = sprintf('testing error rate is: %f',er); disp(str) %% //实验二:采用denoising autoencoder进行预训练 maskFraction = 0.5 %rng(0); rand('state',0) sae = saesetup([784 100 100]); % //其实这里nn中的W已经被随机初始化过 sae.ae{1}.activation_function = 'sigm'; sae.ae{1}.learningRate = 1; sae.ae{1}.inputZeroMaskedFraction = 0.5; opts.numepochs = 10; opts.batchsize = 100; sae = saetrain(sae, train_x, opts);% //无监督学习,不需要传入标签值,学习好的权重放在sae中, % //并且train_x是最后一个隐含层的输出。由于是分层预训练 % //的,所以每次训练其实只考虑了一个隐含层,隐含层的输入有 % //相应的denoise操作 figure,visualize(sae.ae{1}.W{1}(:,2:end)') % Use the SDAE to initialize a FFNN nn = nnsetup([784 100 100 10]); nn.activation_function = 'sigm'; nn.learningRate = 1; %add pretrained weights nn.W{1} = sae.ae{1}.W{1}; % //将sae训练好了的权值赋给nn网络作为初始值,覆盖了前面的随机初始化 % Train the FFNN opts.numepochs = 10; opts.batchsize = 100; nn = nntrain(nn, train_x, train_y, opts); [er, bad] = nntest(nn, test_x, test_y); str = sprintf('maskFraction = 0.5, testing error rate is: %f',er); disp(str)
参考文献:
https://www.youtube.com/watch?v=t2NQ_c5BFOc&index=49&list=PL6Xpj9I5qXYEcOhn7TqghAJ6NAPrNmUBH
http://www.cnblogs.com/dupuleng/articles/4340293.html

浙公网安备 33010602011771号