TSNE-原理與實現

TSNE-數據可視化降維

項目地址:https://github.com/wchstrife/Information-Visualization-and-Visual-Analytics.git

一、運行

python tsne.py

二、算法原理

2.1 SNE原理

SNE即stochastic neighbor embedding,其基本思想爲在高維空間相似的數據點,映射到低維空間距離也是相似的。SNE把這種距離關係轉換爲一種條件概率來表示相似性。

假設高維空間中有 xix_i, xjx_j 兩個點,pjip_{j|i} 表示中心爲 xix_i 時,xjx_j是其近鄰點的概率:xjx_j 越靠近 xix_i其值越大,反之概率就越小。pjip_{j|i}採用高斯分佈,公式如下:

pji=exp(xixj2/2σi2)kiexp(xixk2/2σi2) p_{j|i} = \frac{exp(-||x_i - x_j||^2 / 2 \sigma^2_i)}{\sum_{k \neq i}exp(-||x_i - x_k||^2 / 2 \sigma^2_i)}

對於不同的中心xix_i,其對應的高斯分佈的方差σ\sigma也不同,需要對每個點進行計算。

同樣對於高維空間的點xix_i, xjx_j映射爲低維空間對應的點爲yiy_i, yjy_j,其概率分佈函數qjiq_{j|i}如下。在這裏爲了方便計算,假設所有點的σ\sigma都爲12\frac{1}{\sqrt{2}}

qji=exp(yiyj2)kiexp(yiyk2) q_{j|i} = \frac{exp(-||y_i - y_j||^2) }{\sum_{k \neq i}exp(-||y_i - y_k||^2 )}

爲了讓高維空間的點映射到低維空間後,儘可能保持一樣的分佈,即原來離得近的點還離得近,離得遠的點還離得遠,所以要保證兩個分佈儘可能相似,這裏用的衡量的方法就是採用KL(Kullback-Leibler Divergence)距離。

C=iKL(PiQi)=ijpjilogpjiqji C = \sum_i KL(P_i || Q_i) = \sum_i\sum_j p_{j|i} log\frac{p_{j|i}}{q_{j|i}}

現在問題轉化了如何讓上面的代價函數C最小。經典方法就是梯度下降法

δCδyi=2j(pjiqji+pijqij)(yiyj) \frac{\delta C}{\delta y_i} = 2\sum_j(p_{j|i} - q_{j|i} + p_{i|j} - q_{i|j})(y_i-y_j)

在進行梯度更新時,要注意Cost Function並不是一個凸函數,所以會存在很多的局部最優解,爲了防止陷於局部最優解,還需要加上一個“動量”,可以衝出局部最優解。

Yt=Yt1+ηδCδyi+α(t)(Yt1Yt2) Y^{t} = Y^{t-1} + \eta\frac{\delta C}{\delta y_i} + \alpha(t)(Y^{t-1} - Y^{t-2})

其中YtY^{t}表示t次迭代的結果,η\eta是學習率,α(t)\alpha(t)表示第t次迭代時的動量。

此時還剩下一個問題沒有解決:如何爲不同的xix_i選擇合適的σ\sigma。這裏提出叫做困惑度(perplexity)的概念,來表示xix_i附近的有效近鄰點的個數,通常取5-50之間。

Perp(Pi)=2H(Pi) Perp(P_i) = 2^{H(P_i)}

H(Pi)=jpjilog2pji H(P_i)= - \sum_j {p_{j|i}}log_2{p_{j|i}}

給定困惑度之後,使用二分搜索尋找一個最合適的σ\sigma

但是需要注意一點時,KL距離具有不對稱性

  1. pjip_{j|i}越大,qjiq_{j|i}越小時,此時的Cost越高。即高維空間的點越接近,映射到低維空間時反而越遠,此時的懲罰是很大的,這是正確的情況。
  2. pjip_{j|i}越小,qjiq_{j|i}越大時,此時的Cost越小。即高維空間的點距離遠時,映射到低維空間的點接近時,此時的懲罰卻很小,這時跟我們想要的結果正好相反。

因此SNE傾向於保留局部特徵,即讓高維離得近的點儘可能在低維時聚在一起,但是不考慮不同類間的間隔,直觀理解爲:整個降維後的圖像會比較“擁擠”。

2.2 t-SNE原理

t-SNE是在SNE的基礎上進行了以下兩點改進:

  • 使用對稱SNE,簡化梯度公式
  • 低維空間使用t分佈取代高斯分佈

我們先看改進1,將非對稱的SNE改爲對稱的SNE。

在之前的條件分佈概率中,是不對稱的,例如高維空間中pijp_{i|j}是不等於pjip_{j|i}的,這與我們的直覺不符合,因爲無論是xix_i還是xjx_j誰作爲中心點,其出現在對方附近的概率應該是相等的,所以我們應該設計一個聯合概率分佈,使得pij=pjip_{ij} = p_{ji}.

於是在高維、低維空間中,我們重新定義一下概率分佈,注意除號下面部分與之前的區別:

pij=exp(xixj2)klexp(xkxl2) p_{ij} = \frac{exp(-||x_i - x_j||^2) }{\sum_{k \neq l}exp(-||x_k - x_l||^2 )}

qij=exp(yiyj2)klexp(ykyl2) q_{ij} = \frac{exp(-||y_i - y_j||^2) }{\sum_{k \neq l}exp(-||y_k - y_l||^2 )}

對於高維空間中的點,爲了避免異常值的影響,採取以下方法定義高維空間的聯合分佈:

pij=pij+pij2n p_{ij} = \frac{p_{i|j} + p_{i|j}}{2n}

此時KL距離組成的損失函數如下:

C=KL(PQ)=ijpijlogPijqij C = KL(P||Q) = \sum_i \sum_j p_{ij}log\frac{P_{ij}}{q_{ij}}

梯度爲:

δCδyi=4j(pijqij)(yiyj) \frac{\delta C}{\delta y_i} = 4\sum_j(p_{ij} - q_{ij})(y_i-y_j)

下面繼續看t-SNE的第二個改進:低維空間用t分佈替換高斯分佈。這樣做的好處是在低維的情況下,將同類的數據的距離減少,不同類間的距離拉大,這樣可視化的效果會更好。

所以低維空間上的分佈函數如下:

qij=(1+yiyj2)1kl(1+ykyl2)1 q_{ij} = \frac{(1+||y_i-y_j||^2)^{-1}}{\sum_{k \neq l}(1+||y_k-y_l||^2)^{-1}}

此時梯度如下:

δCδyi=4j(pjiqji)(yiyj)(1+yiyj2)1 \frac{\delta C}{\delta y_i} = 4\sum_j(p_{ji} - q_{ji})(y_i-y_j)(1+|y_i -y_j||^2)^{-1}

三、算法實現

輸入的數據爲MNIST數據集中,抽取的2500條數據,每一條數據是784維,所以輸入的規模爲2500*784。

爲了降低TSNE執行的複雜度,在進行TSNE之前,先通過PCA對數據進行降維,減少參數量,簡化TSNE計算,否則實際的執行時間過長。

算法僞代碼如下:

input data set X = {x1, x2, ..., xn}
input perplexity Perp
input iterations T, learning rate n, momentum a(t)

begin
    compute p_{j|i} with perplexity Perp
    compute P_{ij}
    initial y(0) = {y1, y2, ..., yn}

    for t = 1 to T 
        compute q_{ij}
        compute gradient
        update y(t)
    end
end

四、實驗結果

在這裏插入圖片描述

五、參考文獻

  1. Van der Maaten L, Hinton G. Visualizing data using t-SNE[J]. Journal of Machine Learning Research, 2008, 9(2579-2605): 85.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章