linear Decoder (线性自动稀疏编码)

来源:互联网 发布:你可能需要与该网络isp 编辑:程序博客网 时间:2024/05/17 03:34

一、简介

 稀疏自编码包含3层神经元,分别是输入层,隐含层以及输出层。自编码网络中的神经元采用的是相同的激励函数(S型函数)。

 S型函数的输出范围是[0,1],当神经元采用S型函数时,其输出范围也在[0,1]内;由于输出范围在0和1之间,这就要求采用自码时,对输入数据进行限制或者放缩,使其范围也在0和1之间。一些数据集,比如mnist,能很方便的将输出放缩到0和1之间;但是很难满足对输入值的要求。比如,经过PCA白化处理后的数据就不满足0和1这个范围。

 在线性解码中,我们在某些神经元采用不同的激励函数;网络的隐含层依然使用S型函数,而其输出层采用恒等函数即a=f(z)=z,由于其具有线性性质,又称为线性激励函数。

一个 S 型或 tanh 隐含层以及线性输出层构成的自编码器,我们称为线性解码器。

其网络结构:

   

 因为输出a3,即x_^,是隐单元激励输出的线性函数,改变W_2,就可以使a3缩放到相应的范围。这可以使得我们用实际值输入来训练自编码器,避免预先缩放样本给定范围。

 这样的优点主要有2点:

1.模型更容易应用

2.模型对参数的变化也更为鲁棒性

二、试验练习

Step0数据:

 在彩色图像数据包stl10(一个包含十个彩色图像的数据),提取10W个小patches,进行学习训练。(试验提取完成,直接加载stlSampledPatches.mat)

Step1数据预处理:

 ZCAWhitening处理,先0均值化,之后求解相关系数矩阵,再对相关系数矩阵(协方差矩阵)进行svd分解,求转换矩阵u和特征值;在进行ZCAWhitening处理。处理后数据范围由[0,1]转换到[-5.1211 ,  5.8668]。

 

meanPatch = mean(patches, 2); 

               %注意这里减掉的是每一维属性的均值,为什么会和其它的不同呢? 按照斯坦福教程中说明的,由于自然图像具有一致的统计特性,故对于自然图像独立的进行处理即可;对于一些人工图像,或者明显的黑白背景图像需要这种维度统一的处理

patches = bsxfun(@minus,patches, meanPatch);

               %每一维都均值化,而不是对每个patches分别均值化

sigma = patches *patches' / numPatches;

[u, s, v] = svd(sigma);

ZCAWhite = u * diag(1 ./ sqrt(diag(s) + epsilon)) * u';%ZCAWhitening矩阵

patches = ZCAWhite * patches;

 详细参见:http://blog.csdn.net/whiteinblue/article/details/21447887

Step2:编写损失函数sparseAutoencoderLinearCost()

               这个部分和sparseAutoencoderCost()的损失函数结构上一致,只有两处小的变化。

               1)把网络的输出层激励函数换成了线性激励函数。即:

                       z3 = W2 * a2 + repmat(b2, [1, m]);  a3 = z3;

               2)输出层网络权重误差,求解简化

               由于最后一层为线性激励函数,在计算误差时,线性函数的导数值为1,所以最后误差为:

                       delta3= -(data - a3);

Step3:用l-bfgs算法优化

options = struct;

options.Method = 'lbfgs';

options.maxIter = 400;

options.display = 'on';

[optTheta, cost] = minFunc( @(p) sparseAutoencoderLinearCost(p, ...

                                  visibleSize,hiddenSize, ...

                                   lambda,sparsityParam, ...

                                   beta,patches), ...

                              theta,options);

Step4:可视化参数矩阵

W =reshape(optTheta(1:visibleSize * hiddenSize), hiddenSize, visibleSize);

displayColorNetwork( (W*ZCAWhite)');

%这里为什么要用(W*ZCAWhite)'呢?


 因为每个样本x输入网络,白化后转换为X_ZCA=ZCAWhite*x;其输出等价于W*ZCAWhite*x;所以W*ZCAWhite是原始数据x的权值矩阵,而W为白话后数据的权值矩阵。

 由于W*ZCAWhite的每一行才是一个隐含节点的变换值;而displayColorNetwork函数是把每一列显示一个小图像块的,所以需要对其转置。


实验结果,及其他分析详见tornadomeet博客linear decoder:http://www.cnblogs.com/tornadomeet/archive/2013/04/08/3007435.html

 

0 0