K均值演算法基於CUDA環境的實現
聚類分析的目的是將若干特徵相似的特徵模式劃分到一個集合,每個集合的特徵模式之間按照某種度量來衡量相似程度,使得同一個集合內的資料物件具有較高的相似度,而不同集合中的資料物件間的相似度儘可能小,資料物件間特性差異的大小通常是藉助於某一距離空間中的距離概念來表示的。在現有的聚類演算法中, 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 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 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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- iOS基於灰度的均值雜湊演算法實現影象匹配iOS演算法
- K均值演算法演算法
- K-鄰近均值演算法演算法
- 《機器學習實戰》kMeans演算法(K均值聚類演算法)機器學習演算法聚類
- cuda的 visual studio 環境配置
- 演算法雜貨鋪:k均值聚類(K-means)演算法聚類
- 第5章 基於K均值聚類的網路流量異常檢測聚類
- 一句話總結K均值演算法演算法
- 基於Docker搭建LNMP環境DockerLNMP
- 基於Docker的LNMP開發環境DockerLNMP開發環境
- 【K8S】基於Docker+K8S+GitLab/SVN+Jenkins+Harbor搭建持續整合交付環境(環境搭建篇)K8SDockerGitlabJenkins
- 基於環信實現線上聊天功能
- 基於BKDRhash實現Hash演算法演算法
- 常用整合開發環境(IDE)的CUDA配置開發環境IDE
- 機器學習經典聚類演算法 —— k-均值演算法(附python實現程式碼及資料集)機器學習聚類演算法Python
- 聚類之K均值聚類和EM演算法聚類演算法
- 基於 Laradock 環境 Project 的總結Project
- 搭建基於 Mac 的 Flutter 開發環境MacFlutter開發環境
- 部署基於Dragonwell的Java執行環境GoJava
- 搭建基於以太坊的私有鏈環境
- 基於Linux的 工作環境配置方法Linux
- 基於ECS快速搭建Docker環境Docker
- 演算法金 | 一文讀懂K均值(K-Means)聚類演算法演算法聚類
- 基於 webpack 的前後端分離開發環境實踐Web後端開發環境
- 搭建基於netfilter/iptables的防火牆實驗環境(轉)Filter防火牆
- linux下CUDA開發環境構建Linux開發環境
- CUDA開發環境高亮顯示設定開發環境
- 4090 windows cuda12.1 環境配置Windows
- golang實現二倍均值演算法和搶紅包Golang演算法
- K 均值演算法-如何讓資料自動分組演算法
- 如何構建基於 docker 的開發環境Docker開發環境
- 如何構建基於docker的開發環境Docker開發環境
- 基於IDEA的JavaWeb開發環境搭建IdeaJavaWeb開發環境
- PC基於Linux的叢集環境搭建?Linux
- 【轉載】基於 Docker 的 PHP 整合環境 dnmpDockerPHP
- 基於ubuntu如何搭建TensorFlow環境Ubuntu
- 基於Webpack搭建React開發環境WebReact開發環境
- 《機器學習實戰》二分-kMeans演算法(二分K均值聚類)機器學習演算法聚類