1.理论知识:UFLDL教程、Deep learning:十六(deep networks)
2.实验环境:win7, matlab2015b,16G内存,2T硬盘
3.实验内容:Exercise: Implement deep networks for digit classification。利用深度网络完成MNIST手写数字数据库中手写数字的识别。即:用6万个已标注数据(即:6万张28*28的图像块(patches)),作为训练数据集,然后把它输入到栈式自编码器中,它的第一层自编码器提取出训练数据集的一阶特征,接着把这个一阶特征输入到第二层自编码器中提取出二阶特征,然后把把这个二阶特征输入到softmax分类器,再用原始数据的标签和二阶特征来训练softmax分类器,最后利用BP算法对整个网络的权重值进行微调以更好地学习数据,再用1万个已标注数据(即:1万张28*28的图像块(patches))作为测试数据集,用前面训练好的softmax分类器对测试数据集进行分类,并计算分类的正确率。本节整个网络结构如下:
注意:本节实验与Deep Learning六:Softmax Regression_Exercise(斯坦福大学深度学习教程UFLDL)和Deep Learning七:Self-Taught Learning_Exercise(斯坦福大学深度学习教程UFLDL)的区别如下:
Deep Learning六:Softmax Regression_Exercise(斯坦福大学深度学习教程UFLDL)用原始数据本身作训练集直接输入softmax分类器分类,Deep Learning七:Self-Taught Learning_Exercise(斯坦福大学深度学习教程UFLDL)是从原始数据中提取特征作训练集,再把其特征输入softmax分类器分类,而本节实验是从原始数据中提取特征作训练集,再把其特征输入softmax分类器分类,最后再用大量已标注数据对整个网络的权重值进行微调,从而得到更好的分类结果。所以,最后结果能看出,本节实验方法得到的准确率97.590%高于Deep Learning六:Softmax Regression_Exercise(斯坦福大学深度学习教程UFLDL)中得到的准确率92.640%。对于Deep Learning七:Self-Taught Learning_Exercise(斯坦福大学深度学习教程UFLDL),因为它的训练样本不一样,故其准确率结果不能直接比较。但是,本节实验对进行微调前后的准确率作了对比,见本节实验结果。
在什么时候应用微调?通常仅在有大量已标注训练数据的情况下使用。在这样的情况下,微调能显著提升分类器性能。然而,如果有大量未标注数据集(用于非监督特征学习/预训练),却只有相对较少的已标注训练集,微调的作用非常有限,这时可用Deep Learning七:Self-Taught Learning_Exercise(斯坦福大学深度学习教程UFLDL)中介绍的方法。
[params, netconfig] = stack2params(stack)
是将stack层次的网络参数(可能是多个参数)转换成一个向量params,这样有利用使用各种优化算法来进行优化操作。Netconfig中保存的是该网络的相关信息,其中netconfig.inputsize表示的是网络的输入层节点的个数。netconfig.layersizes中的元素分别表示每一个隐含层对应节点的个数。
[ cost, grad ] = stackedAECost(theta, inputSize, hiddenSize, numClasses, netconfig,lambda, data, labels)
该函数内部实现整个网络损失函数和损失函数对每个参数偏导的计算。其中损失函数是个实数值,当然就只有1个了,其计算方法是根据sofmax分类器来计算的,只需知道标签值和softmax输出层的值即可。而损失函数对所有参数的偏导却有很多个,因此每个参数处应该就有一个偏导值,这些参数不仅包括了多个隐含层的,而且还包括了softmax那个网络层的。其中softmax那部分的偏导是根据其公式直接获得,而深度网络层那部分这通过BP算法方向推理得到(即先计算每一层的误差值,然后利用该误差值计算参数w和b)。
stack = params2stack(params, netconfig)
和上面的函数功能相反,是吧一个向量参数按照深度网络的结构依次展开。
[pred] = stackedAEPredict(theta, inputSize, hiddenSize, numClasses, netconfig, data)
这个函数其实就是对输入的data数据进行预测,看该data对应的输出类别是多少。其中theta为整个网络的参数(包括了分类器部分的网络),numClasses为所需分类的类别,netconfig为网络的结构参数。
[h, array] = display_network(A, opt_normalize, opt_graycolor, cols, opt_colmajor)
该函数是用来显示矩阵A的,此时要求A中的每一列为一个权值,并且A是完全平方数。函数运行后会将A中每一列显示为一个小的patch图像,具体的有多少个patch和patch之间该怎么摆设是程序内部自动决定的。
struct:
s = sturct;表示创建一个结构数组s。
nargout:
表示函数输出参数的个数。
save:
比如函数save(‘saves/step2.mat‘, ‘sae1OptTheta‘);则要求当前目录下有saves这个目录,否则该语句会调用失败的。
栈式自编码神经网络是一个由多层稀疏自编码器组成的神经网络,其前一层自编码器的输出作为其后一层自编码器的输入。
1. 解决了Deep Learning六:Softmax Regression_Exercise(斯坦福大学深度学习教程UFLDL)中提出的一个问题:
在softmaxExercise.m中有如下一句代码:
images = loadMNISTImages(‘train-images.idx3-ubyte‘);
labels = loadMNISTLabels(‘train-labels.idx1-ubyte‘);
labels(labels==0) = 10; % 把标签0变为标签10,故labels的值是[1,10],而原来是[0,9] ?为什么非要这样?
为什么非要把原来的标签0变为标签10呢?搞不懂!
这个问题在本节实验中的stackedAEExercise.m中也有:
trainLabels(trainLabels == 0) = 10; % 一直没搞懂,为什么非要把标签0变为10?
原因:为了方便后面预测分类结果时,能直接通过max函数返回的是大值的列号就是所预测的分类结果。如本节实验中stackedAEPredict.m中的这句话:
[prob pred] = max(softmaxTheta*a{depth+1});
其中pred就是保存的所要预测的结果。
1.如果我们后面的分类器不是用的softmax分类器,而是用的其它的,比如svm等,这个时候前面特征提取的网络参数已经预训练好了,用该参数是可以初始化前面的网络,但是此时该怎么微调呢?
2.从代码中,可以看出整个网络的代价函数实际上就是softmax分类器的代价函数,这是怎么推导来的?
3.第二个隐含层的特征怎么显示出来?
1.初始化参数,加载MNIST手写数字数据库。
2.利用原始数据训练第一个自编码器,得到它的权重参数值sae1OptTheta,通过sae1OptTheta可得到原始数据的一阶特征sae1Features。
3.利用一阶特征sae1Features训练第二个自编码器,得到它的权重参数值sae2OptTheta,通过sae2OptTheta可得到原始数据的二阶特征sae2Features。
4.利用二阶特征sae2Features和原始数据的标签来训练softmax分类器,得到softmax分类器的权重参数saeSoftmaxOptTheta。
5.利用前面得到的所有权重参数sae1OptTheta、sae2OptTheta、saeSoftmaxOptTheta,得到微调前整个网络的权重参数stackedAETheta,然后在利用原始数据及其标签的基础上通过BP算法对stackedAETheta进行微调,得到微调后的整个网络的权重参数stackedAEOptTheta。
6.通过微调前整个网络的权重参数stackedAETheta和微调后的整个网络的权重参数stackedAEOptTheta,分别对测试数据进行分类,得到两者的分类准确率。
Before Finetuning Test Accuracy: 92.140%
After Finetuning Test Accuracy: 97.590%
第一层特征显示如下:
参考资料:
Deep learning:二十四(stacked autoencoder练习)
http://blog.csdn.net/freeliao/article/details/19618855
http://www.tuicool.com/articles/MnANFn
……
原文:http://www.cnblogs.com/dmzhuo/p/4945037.html