K均值演算法基於CUDA環境的實現

洛欣發表於2010-05-24

聚類分析的目的是將若干特徵相似的特徵模式劃分到一個集合,每個集合的特徵模式之間按照某種度量來衡量相似程度,使得同一個集合內的資料物件具有較高的相似度,而不同集合中的資料物件間的相似度儘可能小,資料物件間特性差異的大小通常是藉助於某一距離空間中的距離概念來表示的。在現有的聚類演算法中, K-均值演算法以其簡單和高效佔有重要地位,因而大量應用於資料探勘中。

 

其計算流程如下:

1.       如果是第一次迴圈,隨機選擇K個元素作為質心;否則使用K個分類的平均值作為質心。

2.       計算n個資料離各個分類的距離,將當前資料作為離其最近的分類的元素

3.       計算各分類的的均值和方差

4.       如果當前各個分類方差,如果前後步最大方差差別滿足容忍限度,演算法完成,退出;否則,返回1,進行下一次迴圈。

 

首先,我們對這個問題進行分析,進行演算法GPU化的第一步不是拿起鍵盤就敲,而是分析當前演算法是否滿足GPU計算的要求,從演算法步驟可以看出,該演算法是資料並行,雖然各資料之間有些互動,但是都能夠解決。此外資料探勘領域的演算法幾乎都要求是大資料量的,因此,初步可得出此演算法可以GPU化。

其次,在我們得出演算法可以GPU化結論後,下一步應當是具體的設計了,設計首先應當是演算法和資料結構設計。從演算法可以看出,主要運算有求平均值、方差,都可以使用歸約解決。其後就是資料結構設計了。由於涉及到資料是分類的元素這個問題,其有兩種實現方式,一種是為每一分類分配一陣列,儲存該分類的元素;另一種是為每個元素設立一個域,來表示元素屬於那個分類。CUDA要求資料組織是有序的,因此表面上看前一種方案比較好,但是由於我們無法提前知道屬於每一分類的元素數目,因此陣列只能開得比較大,當然我們可以實現類似STL中的向量,但是這又帶來其它開銷。一般來說GPU的裝置儲存器容量不多,而資料量往往又比較大,再考慮到實現的難度,因此我們採用後一種方案。此時資料結構設計如下:

//T stand for attribute type,size stand for attribute number;

template data{

T x[size];//attribute

}

struct dataSet{

         unsigned int num;//data size

         data *attributes;// size == num

         unsigned int *belongTo;//specify data belong to which class;size == num

演算法要求計算距離,但是並無必要,我們計算距離的平方就行了,這樣節省一次求方根的計算量。程式碼如下:

__host__ __device__ int distance2(data one, data two, unsigned int size = 3){

         Int dis2 = 0;//must be more explicit

         int dis;

#pragma unroll 3

for(int I = 0; I < size; i++){

                   dis = one.x[i] – two.x[i];

                   dis2 += dis*dis;

}

 

return dis2;

}

我們存放分類的平均值,在計算每個資料屬於那個分類時,理論上是有分支的,但是可以消除。分類之後就要計算各分類的平均值,可在每個block中分配共享儲存器,以儲存各個分類和及各分類元素數量,此時要用到共享儲存器的原子函式,因此元素屬性型別只能採用整形,此時最多可處理2000個分類,但是如果是2.0的裝置,可處理的分類數會多,也可以處理浮點型屬性,一方面是因為共享儲存器量多了且支援浮點原子函式,另一方面此時可將分類元素數量宣告為ushort而沒有儲存體衝突。然後再另起一個kernel 就可得到各分類的平均值。然後要做的就是求各分類的方差了。此時可將分類平均值存放於共享儲存器中,然後遍歷各元素,並將求得的分類方差和存放在共享儲存器中,再另起一核心,該核心只有一個塊,用於歸約上一核心得到的部分方差和。至此整個演算法基本完成。

         如果要在計算能力2.0以下的裝置上做K-均值演算法,並使用浮點屬性值的話,可以使用我在分析的時候的前一方案,此時最好實現CUDA環境的向量資料結構。由於要使用全域性儲存器的原子函式,由此可見其速度將不會很好。

         intel至強5450 CPU上,GTX 295顯示卡上,一萬個三維的資訊,計算部分加速比在40以上。由於是個人玩樂的專案,因此並沒有為了速度而進行極致的優化。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22785983/viewspace-663548/,如需轉載,請註明出處,否則將追究法律責任。

相關文章