MATLAB并行实现Kmeans聚类算法
程序员文章站
2022-05-20 22:30:21
...
使用MATLAB语言实现Kmeans聚类算法,并用并行工具箱进行加速运算。
function [cluster,label] = calculateDistforGpu(data,centeroids,max_iter)
[m,n]=size(data);
fprintf('m=%d,n=%d\n',m,n);
% 获得类别个数
k = length(centeroids);
fprintf('聚类中心个数:%d\n', k);
% 类别标记
%--------------------gpu---------------------%
label = gpuArray(zeros(m,1));
% 得到每个聚类实例
cluster=cell(k,1);
centeroids_copy = centeroids;
for iteration=1:max_iter
% 将与每个聚类中心最近的实例归为一类
fprintf('迭代:%d\n',iteration);
for i = 1:m
d = zeros(k,1);
for j = 1:k
d(j)=sum((data(i,:)-centeroids_copy(j,:)).^2) ;
end
% 判断每个实例与哪个聚类中心最近,将此实例归为聚类中心所代表的类
indexes = find(d==min(d));
% 更新类别标记
len = length(indexes);
if len==1
label(i)=indexes;
index = indexes;
else
index = randperm(len,1);
label(i)=indexes(index);
end
% 为每个类别添加实例
cluster{index}=vertcat(cluster{index}, data(i,:));
end
% 更新聚类中心
newcenteroids = updateCenteroid(cluster,n);
% 如果新的聚类中心和上一次的聚类中心相同
% 则停止迭代
if sum(sum(newcenteroids==centeroids_copy))
fprintf('终止迭代次数是:%d\n',iteration);
break;
else
% 替换聚类中心
centeroids_copy = newcenteroids;
%-----------------gpu---------------%
label=gpuArray(zeros(m,1));
cluster=cell(k,1);
end
end
% 更新聚类中心
function newcenteroids = updateCenteroid(cluster,dim)
k=length(cluster);
newcenteroids=zeros(k,dim);
parfor i=1:k
% mean默认按照每一列求均值
newcenteroids(i,:)=mean(cluster{i});
end
% 调用kmeans
pic = imread('E:\pythonfile_withpycharm\cluster.jpg');
pic = imresize(pic,0.5);
[m,n,z]=size(pic);
row_data = double(reshape(pic,m*n,z));
%---------------------gpu--------------------------%
% 产生一组随机索引
rand_index= randperm(m*n,10);
kcenteroids = row_data(rand_index,:);
max_iter =20;
tic
[clusters, target] = calculateDistforGpu(row_data, kcenteroids, max_iter);
fprintf('kmeans run time:%f\n',toc);
delete(gcp);
% 显示聚类后的图片
img = zeros(m*n,z);
colormap=[0,255,0;255,0,0;0,0,255;200,200,100;180,255,100;
20,187,240;100,100,150;140,150,160;177,190,0;200,0,200];
for i=1:m*n
img(i,:)=colormap(target(i),:);
end
img = reshape(img,m,n,z);
res = im2uint8(mat2gray(img));
imshow(res);
原图像为:
聚类之后结果显示: