1. 程式人生 > >流形學習 manifold learning--自學小結(2)之 Isomap

流形學習 manifold learning--自學小結(2)之 Isomap

http://isomap.stanford.edu/     應有盡有

另外,中文blog:
http://www.cvchina.info/2010/05/31/manifold-learning/#more-1038

 Isomap 論文裡的一個結果:

這裡的圖片來自同一張人臉(好吧,其實是人臉模型),每張圖片是 64×64 的灰度圖,如果把點陣圖按照列(或行)拼起來,就可以得到一個 4096 維的向量,這樣一來,每一張圖片就可以看成是 4096 維歐氏空間中的一個點。很顯然,並不是 4096 維空間中任意一個點都可以對應於一張人臉圖片的,這就類似於球面的情形,我們可以假定所有可以是人臉的 4096 維向量實際上分佈在一個 d 維 (d < 4096) 的子空間中。而特定到 

Isomap 的人臉這個例子,實際上我們知道所有的 698 張圖片是拍自同一個人臉(模型),不過是在不同的 pose 和光照下拍攝的,如果把 pose (上下和左右)當作兩個自由度,而光照當作一個自由度,那麼這些圖片實際只有三個自由度,換句話說,存在一個類似於球面一樣的引數方程(當然,解析式是沒法寫出來的),給定一組引數(也就是上下、左右的 pose 和光照這三個值),就可以生成出對應的 4096 維的座標來。換句話說,這是一個嵌入在 4096 維歐氏空間中的一個 3 維流形。

實際上,上面的那張圖就是 Isomap 將這個資料集從 4096維對映到 3 維空間中,並顯示了其中 2 維的結果,圖中的小點就是每個人臉在這個二維空間中對應的座標位置,其中一些標紅圈的點被選出來,並在旁邊畫上了該點對應的原始圖片,可以很直觀地看出這兩個維度正好對應了 pose 的兩個自由度平滑變化的結果。

就我目前所知,把流形引入到機器學習領域來主要有兩種用途:一是將原來在歐氏空間中適用的演算法加以改造,使得它工作在流形上,直接或間接地對流形的結構和性質加以利用;二是直接分析流形的結構,並試圖將其對映到一個歐氏空間中,再在得到的結果上運用以前適用於歐氏空間的演算法來進行學習。

這裡 Isomap 正巧是一個非常典型的例子,因為它實際上是通過“改造一種原本適用於歐氏空間的演算法”,達到了“將流形對映到一個歐氏空間”的目的。 :)

Isomap 所改造的這個方法叫做 Multidimensional Scaling (MDS) ,MDS 是一種降維方法,它的目的就是使得降維之後的點兩兩之間的距離儘量不變(也就是和在原是空間中對應的兩個點之間的距離要差不多)。只是 MDS 是針對歐氏空間設計的,對於距離的計算也是使用歐氏距離來完成的。如果資料分佈在一個流形上的話,歐氏距離就不適用了。

讓我們再回到地球——這個在三維空間中的二維流形,假設我們要在三維空間中計算北極點和南極點的距離,這很容易,就是兩點相連的線段的長度,可是,如果要在這個流形上算距離就不能這樣子算了,我們總不能從北極打個洞鑽到南極去吧?要沿著地球表面走才行,當然,如果我隨便沿著什麼路線走一遍,然後數出總共走了多少步作為距離,這是不成的,因為這樣一來如果我沿著不同的路線走,豈不是會得到不同的距離值?總而言之,我們現在需要一個新的定義在地球表面(流形)上的距離度量,理論上來說,任意滿足測度的 4 個條件的函式都可以被定義為距離,不過,為了和歐氏空間對應起來,這裡選擇一個直線距離的推廣定義。

還記得初中學的“兩點之間,線段最短”嗎?現在,我們反過來說,把線段的概念推廣一下,變成“兩點之間最短的曲線是線段”,於是流形上的距離定義也就等同於歐氏空間了:流形上兩個點之間的距離就是連線兩個點的“線段”的長度。雖然只是置換了一個概念,但是現在兩者統一起來了,不過,在流形上的線段大概就不一定是“直”的了(於是直線也變成不一定是“直”的了),通常又稱作是“測地線”。對於球面這個簡單的流形來說,任意一條線段必定是在一個“大圓”上的,於是球面上的直線其實都是一些大圓,也造成了球面這個流形上沒有平行線等一系列尷尬的局面(任意兩條直線均相交),如果你看過一些數學科普八卦類的書,應該會回憶起不少東西啦!

回到 Isomap ,它主要做了一件事情,就是把 MDS 中原始空間中距離的計算從歐氏距離換為了流形上的測地距離。當然,如果流形的結構事先不知道的話,這個距離是沒法算的,於是 Isomap 通過講資料點連線起來構成一個鄰接 Graph 來離散地近似原來的流形,而測地距離也相應地通過 Graph 上的最短路徑來近似了。如下圖所示:

這個東西叫做 Swiss Roll ,姑且把它看作一塊捲起來的布好了。圖中兩個標黑圈的點,如果通過外圍歐氏空間中的歐氏距離來計算的話,會是捱得很近的點,可是在流形上它們實際上是距離很遠的點:紅色的線是 Isomap 求出來的流形上的距離。可以想像,如果是原始的 MDS 的話,降維之後肯定會是很暴力地直接把它投影到二維空間中,完全無視流形結構,而 Isomap 則可以成功地將流形“展開”之後再做投影。





實驗:

ISOMAP人臉識別

兩種經典的非線性降維(Nonlinear Dimensionality Reduction)方法:lle和isomap。問題是別人做過的,演算法實現也基本都是現成的,我只是拿來"玩一玩"。實驗有很多環節,最有趣的一個環節,是給你698張人臉的影象(64×64灰度),通過isomap降維方法將每張臉當做一個點映到二維平面上,使得橫座標恰好反映人臉左右看的程度,縱座標反映人臉上下看的程度。

如果你也對這個實驗感興趣,就往下讀吧,很簡單的~

實驗環境:Matlab6.5

實驗步驟

步驟一:準備資料集和工具包

下載

並解壓縮

下載

的所有程式碼

步驟二:

準備圖片標記的人臉序號集:一共有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://hi.baidu.com/bess_tang/item/f3f0d216cde2520d8fbde438