这学期有一门课程《数学建模案例分析》,讲到了两种经典的非线性降维(Nonlinear Dimensionality Reduction)方法:lle和isomap。问题是别人做过的,算法实现也基本都是现成的,我只是拿来"玩一玩"。实验有很多环节,最有趣的一个环节, 是给你698张人脸的图像(64×64灰度),通过isomap降维方法将每张脸当做一个点映到二维平面上,使得横坐标恰好反映人脸左右看的程度,纵坐标反映人脸上下看的程度。
如果你也对这个实验感兴趣,就往下读吧,很简单的~
实验环境:Matlab6.5
实验步骤
步骤一:准备数据集和工具包
下载
人脸数据集:http://waldron.stanford.edu/~isomap/face_data.mat.Z
并解压缩
下载
isomap算法实现:http://waldron.stanford.edu/~isomap/code/
的所有代码
步骤二:
准备图片标记的人脸序号集:一共有698张人脸,都画在平面上太拥挤了,所以选了30个人脸(存入posesSelect.mat的ks向量),选取的准则是:30个人脸的姿态尽量不同,也就是希望画在平面上尽量分散。事实上,face_data.mat数据集中,poses是一个2行698列的矩阵,第j列就是第j张人脸的客观姿态。
绘制客观姿态分布图:
load face_data
load posesSelect
showFacesOnR2(images,poses,ks)
http://lh6.ggpht.com/_iMG9M3S-9Xo/SWXkfHPcWNI/AAAAAAAACBs/otRKwIQ6DMc/s800/image002.gif
步骤三:降维
用Isomap算法将4096维的人脸数据images降维到2维,并绘制在平面上
load face_data
load posesSelect
D=L2_distance(images,images,1);
options.dims = [2];
[Y, R, E] = IsomapII(D, 'k', 7, options);
showFacesOnR2(images,Y.coords{1},ks);
http://lh4.ggpht.com/_iMG9M3S-9Xo/SWXkfu3IIOI/AAAAAAAACB0/nbFaLN3X1HM/s800/image004.gif
D是一个距离矩阵,i行j列值表示人脸i和人脸j的距离,这里把一个人脸图像数据当做一个向量,使用2范数定义距离。
IsomapII是高性能算法,先把D用k=7近邻打成稀疏矩阵,然后用基于斐波那契堆的Dijkstra算法计算最短路,Dijkstra算法用C实现使用并且编译成了.dll文件为了提高效率。计算结果对我们有用的是Y.coords{1},它保存了降维后的结果,是2行698列的矩阵。
观察计算结果发现,以中间那个正的人脸为中心,他左边的都在向左看,而且越是靠左的转动越明显。同理,他右面的都在向右看、上面的都在向下看、下面的在向上看。与客观姿态分布基本吻合。
实验细节:
showFacesOnR2.m
%把头像和姿态坐标画在平面上
function showFacesOnR2(images,poses,ks);
%normalize into 1:1
poses(1,:)=poses(1,:)/range(poses(1,:));
poses(2,:)=poses(2,:)/range(poses(2,:));
%draw all points
scatter(poses(1,:),poses(2,:),12,'o','filled');
xlabel('left-right pose');
ylabel('up-down pose');
hold on
%draw selected points
scatter(poses(1,ks),poses(2,ks),24,'ro');
hold on
%draw images on selected points
scale = 0.001;
x=zeros(64,64);
for p=1:size(ks,2)
k=ks(p);
for i=1:64
x(:,i)=images((i-1)*64+1:i*64,k);
end
xc=poses(1,k);
yc=poses(2,k);
imshow(xc:scale:xc+64*scale,yc:-scale:yc-64*scale,x);
hold on
end
return
转自 http://i.cn.yahoo.com/wusongsong65536/blog/p_4/
Isomap(Isometric Feature Mapping)和CDA(Curvilinear Distance Analysis)是两种重要而效果显著的非线性维数约简方法,它们都能一定程度上找到高维流形的低维嵌入。这两者之间既有相同之处有各有特点,以下说说我对这两种方法的一些看法,当然,这些看法是在阅读了文献Curvilinear Distance Analysis versus Isomap (2002). John Aldo Lee 后产生的。
Isomap由麻省理工计算机科学与人工智能实验室的Josh Tenenbaum教授于2000在Science杂志上提出(A global geometric framwork for nonlinear dimensionality reduction. (2000) J.B.Tenenbaum)。Isomap的主要目标是对于给定的高维流形,欲找到其对应的低维嵌入,使得高维流形上数据点间的近邻结构在低维嵌入中得以保持。Isomap以MDS(Multidimensional Scaling)为计算工具,创新之处在于计算高维流形上数据点间距离时,不是用传统的欧式距离,而是采用微分几何中的测地线距离(或称为曲线距离),并且找到了一种用实际输入数据估计其测地线距离的算法(即图论中的最小路径逼近测地线距离)。Isomap的优点在于:1 求解过程依赖于线性代数的特征值和特征向量问题,保证了结果的稳健性和全局最优性;2 能通过剩余方差判定隐含的低维嵌入的本质维数;3 Isomap方法计算过程中只需要确定唯一的一个参数(近邻参数k或邻域半径e)。
CDA由天主教鲁汶大学(法语-Université Catholique de Louvain 简称 UCL)应用学院时为博士研究生的John Aldo Lee于2000提出(A Robust Nonlinear Projection Method.(2000) John Aldo Lee)。CDA的主要目标同样是寻找高维流形的低维本质嵌入,但要求低维嵌入应保持高维流形数据点间的距离特性。CDA由CCA(Curvilinear Component Analysis)发展而来,创新点也是引入测地线距离代替欧式距离来度量输入数据间的距离,但CDA寻求低维嵌入的方式更偏重于神经计算方面,因为低维嵌入是通过最优化一个目标为距离误差的无约束最优化问题来获得的。更重要的是,CDA使用VQ(Vector Quantization)作为数据预处理,在获得训练数据的低维嵌入后,通过使用差值运算来获得整个输入数据集的低维表示。这使得CDA表现出更强的流形展开能力和Isomap所没有的泛化能力。
综上,可以得出以下结论:
1.Isomap和CDA都利用了输入数据的测地线距离度量,都能在一定程度上对高维流形进行展开,获得其低维嵌入,达到非线性降维的目的。
2.Isomap参数设定简单、能保证得到全局最优、可以计算出低维嵌入的维数且计算速度较快;但Isomap方法对内部曲率较大的流形展开能力较差,同时如何对训练数据以外的数据进行维数约简一直是Isomap急待解决的问题。
3.CDA方法有优良的流形展开能力,能适应较多类型的流形结构,通过VQ和差值运算使得CDA不仅具有泛化能力,而且CDA所获得的非线性映射具有可逆性,从而保证了CDA具有评价非线性维数压缩质量的机制;但是,CDA的性能表现强烈地依赖于几个参数的设定,且神经计算的求解方式不可避免地会遭遇局部极值的欺骗和收敛性(包括收敛速度)的困扰,另外,VQ和差值运算会增加额外的计算量,使得用CDA进行维数约简时运行速度缓慢,这种计算缓慢性在重复运行CDA以获得正确的低维嵌入维数时更为明显。
以后的方向:
将CDA应用在人脸识别上会表现出什么效果,是否有某些特性未为人知;
研究CDA能够泛化的内在机制,能否将其引入Isomap使得Isomap也具有泛化能力;
研究保持距离度量和保持近邻关系在非线性维数压缩中的效果比较和内在联系,尝试能否找到一种框架将这两种方式统一起来或是结合这两种方式的优点提出一种综合性的方法。