本文主要圍繞學習流形這個概念來講,而不是流形學習。流形學習僅僅是利用流形局部性質(鄰域)來學習流形的一個領域,而學習流形則是更加寬泛的一種思想理念。下面首先簡單介紹一下我對流形這一概念的認識,然后講一下機器學習中學習流形的動機,最后結合不同方法來講如何學習流形。
一、什么是流形
我接觸流形這一概念已經半年多了,從最開始的仰望到慢慢攀爬,現在已經逐漸麻木了。要全面地去弄清楚流形是個什么東西是極其困難的,因為它是數學幾何里的抽象概念,特別是在維度特別高的情況下,要想象出它的樣子根本不可能,而且它還有很多的復雜性質。但是,如果它僅用來機器學習的話,我們只要知道它的簡單定義和一些基礎性質就行了。
1、簡單定義
首先,我們要知道流形是一個空間,而不是一個類似於正方體這樣的簡單幾何物體。這一點很重要,我們可以拿歐式空間去和流形對比,兩者都是空間,但前者是直線、平面等概念的推廣,而后者是歐式空間中曲線、曲面等概念的推廣。那么兩者有什么關系呢?因為直線、平面等概念可以看成對應維度的曲線、曲面等的特例,所以歐式空間相應地可以看成流形的一個特例,叫線性流形。
一般大家研究流形是為了解決非線性問題,所說的流形也都默認是非線性流形。但本文為了從學習流形這個大的理念來討論,所以下面將流形細分為線性流形(歐式空間)和非線性流形。
再說一說非線性流形,我們可以粗暴地去理解,將非線性流形看成歐式空間被扭曲的結果,而用來描述歐式空間的直角坐標系中的軸也相應地被掰彎了。舉一個二維的例子,展平的一塊抹布,可以看成二維歐式空間,當抹布被扭一扭后,它就變成了一個非線性流形。
2、局部性質
流形的局部是具有歐式空間性質的。就像曲線無限放大后,局部是直線一樣,流形無限小的局部也可以看成歐式空間,因此流形局部具有歐式空間性質。地球表面就是一個稍微復雜的例子,從遠處看,地球表面近似一個球面,但從地球上的我們來看,地球表面是一個平面。從這個性質出發,一般的流形可以通過把許多平直的片折彎並粘連而成,而這些片則被稱為坐標卡(坐標圖)。


3、測地線距離
測地線距離是用來度量流形中的距離的。當所在的空間是歐式空間(線性流形)時,測地線距離也就是我們常用的歐式距離;但當空間是非線性流形時,測地線距離不再是歐式距離。還是地球表面的那個例子,假如限定在表面(一個非線性流形)去衡量南北極的距離,我們是不可能直接拉一根直線穿過地心去測量的,只能貼着表面去找最短距離,找出來的這個距離就叫測地線距離。
簡單來說,歐式距離不能滿足非線性流形的約束,所以有了測地線距離。就像地球表面上南北極的歐式距離不滿足球面約束,越出了球面這個空間。
4、切平面
流形的一個重要特征是流形可看作切平面的集合。d 維流形上的一點 x 的切平面由能張成流形上允許變動的局部方向的 d 維基向量給出,而這些局部方向決定了我們能如何微小地變動點 x 而保持於流形上。這里提到的切平面其實是我們用自編碼器學習非線性流形所依賴的一個很重要的性質。
5、固有維數、嵌入維數、流形維數
- 固有維數:數據的固有性質,也是參數空間(能完整包含數據的維數最少的歐式空間)的維數。
- 嵌入維數:數據集能夠完全嵌入且不損失信息的歐式空間的維數。(嵌入指一個數據結構經映射包含到另一個結構中)
- 流形維數:流形本身的維數,其大小等於自由度(用來完整描述數據所需的最少特征或變量)的個數。
關於這三者的關系,我們需要明確一下:嵌入維數 \( \geq \) 固有維數 \( \geq \) 流形維數。
具體解釋一下,嵌入維數是取決於數據的嵌入空間的,而固有維數則是嵌入空間維數最小的時候的維數,也就是說固有維數是嵌入維數的下界。而對於流形維數,大部分人都認為固有維數等於流形維數,這其實是不嚴謹的。因為當流形具有環狀結構時,流形維數是要小於固有維數的。還是舉地球表面的例子,表面作為一個二維流形,其流形維數是 2 ,但是其固有維數卻是 3 ,我們可以想象具有環狀結構的地球表面是不能在不損失結構的情況下嵌入到二維歐式空間的。當然流形不具有環狀結構時,本征維數還是等於流形維數的,總結來說,固有維數是流形維數的上界。
二、為什么要學習流形
這個問題其實摘要里已經簡單說明了,因為流形分布定律,即高維數據往往位於一個低維流形上或附近,所以流形是數據最本質的空間信息。而我們機器學習目的就是為了從經驗中去學習進而提高在任務上的性能,經驗的形式往往又是以數據形式存在的,所以我們只要提取出數據的本質信息,就能更高效地去學習。
在當今數據爆炸的時代,維度災難時常出現。以往在低維度適用的算法都效果很差或者計算代價過高。如果我們能學習到數據位於的那個低維流形,那么我們就可以在這個流形或其嵌入的參數空間里去運用原先的低維學習算法了。當下比較火的深度學習在高維數據中的表現優異,其很大程度上都是可以用流形來解釋的。大家有興趣的可以去看一下深度學習的幾何觀點。
總的來說,我們去學習流形可以減少計算機的內存負擔和計算復雜度,並且可以使學習效果提升,特別是圖像識別,手寫體識別等。
三、怎么樣學習流形
學習流形的算法一般有兩種學習方式:
- 直接學習訓練樣本在流形上的嵌入,也就是計算出訓練樣本在參數空間的坐標表示。流形學習這個鄰域就是基於這種學習的。
- 學習高維空間到參數空間的映射,典型代表是自編碼器。
1、流形學習
流形學習作為機器學習的一個子領域,就是利用流形的局部性質來進行學習的,很明顯的特征是流形學習算法都用到了最近鄰圖的概念。作為了一個比較年輕的鄰域,流形學習也曾引起轟動,但是由於在實際非實驗數據上的運用存在問題,以及深度學習的崛起,這個領域逐漸被冷淡。
流形學習算法主要分兩類,一類是改造原來適用於歐式空間的算法,最典型的就是 Isomap 算法--先估計測地線距離來代替歐式距離,再應用 MDS 算法,可以看成對 MDS 的改進。第二類就是利用流形性質重新設計算法,代表的算法就是 LLE --針對保持鄰域結構不變來構建目標函數。
這里我簡單說一下流形學習這個領域學習的思想:
- 先用k近鄰法構建*最近鄰圖**;
- 再提取流形的特征(測地線距離、領域結構等);
- 最后在保持這些性質的基礎上去將數據映射到參數空間。
換個角度來說,可以簡單理解成:首先學習數據所在的低維流形,然后將這個流形映射到參數空間。
介紹流形學習的博客有很多,我這里就不再多贅述了。有興趣的可以去看看下面兩個博客:
2、其他方法
學習線性流形
前面提到的流形學習雖然也能學習線性流形,但是其效果卻沒有線性方法好,計算復雜度也偏高。其實要學習線性流形,也就是學習歐式空間,最簡單的線性因子模型就可以了。
線性因子模型是最簡單的生成模型,一般用來描述數據的生成過程:
其中 x 是觀察數據,W 是權重矩陣,b 是偏移量,noise 是對角化的且服從正態分布的噪聲。可以從語言上來解釋這個公式:我們觀察到的數據向量 x 是通過獨立的潛在因子 h 的線性組合再加上一定噪聲獲得的。
就拿線性因子模型里最簡單的PCA來說,簡單介紹一下它如何學習線性流形。
下圖中有一個半薄餅狀的概率分布區域,它是概率PCA的模型描述的生成數據概率分布的上半部分(下半部分對稱),整個薄餅可以看成潛在因子所在的歐式空間(超平面)線性變換后加上噪聲的多維正態分布形成的。圖中為了可視化,把潛在因子所在空間看成三維的超平面(一般超平面是四維及以上的,我這里這么說是為了統一好理解),噪聲是三維多維正太分布。而穿過薄餅的平面則是高維空間的線性流形(超平面),圖中是三維超平面。

PCA是概率PCA生成模型中去除噪聲的退化,其概率分布區域可以看成薄餅壓扁,變成一個超平面。那么PCA則可以將薄餅壓扁后通過訓練數據來調整權重和偏移量參數,然后將模型描述的超平面與流形這個超平面貼合(其實叫對准更加恰當)。貼合后,我們就可以得到高維空間到參數空間的映射了。
學習非線性流形
自編碼器可以依據兩種動力去學習非線性流形:一種動力是對自身的重構誤差要小,即解碼器能恢復輸入;第二種是通過約束(正則項)去學習對流形切平面上輸入不敏感的函數。兩種結合成一個目標函數,這樣自編碼器就可以學習非線性流形了。
能學習自編碼器的有兩種:
- 去噪自編碼器:通過約束重構函數的梯度在數據點周圍很小可以捕獲流形的切平面結構。
- 收縮自編碼器:與去噪自編碼器目標相同,只不過手段是通過約束編碼器學習到的函數在數據點周圍梯度很小。
關於其他方法來學習流形這部分講的比較簡單抽象,其深入的理解將會在后續文章中涉及。