Machine learning 如何为一个巨大的亲和矩阵组合谱聚类的分裂运行

Machine learning 如何为一个巨大的亲和矩阵组合谱聚类的分裂运行,machine-learning,computer-vision,cluster-analysis,linear-algebra,image-segmentation,Machine Learning,Computer Vision,Cluster Analysis,Linear Algebra,Image Segmentation,引出问题 我有一个二维复值图像和一系列短值。我想聚类相似的像素/分割图像。有一个或多或少的静态图像,其中有一个叠加图像,其中有一些斑点,在短序列上有一个变化的值(主要是复数的角度)。在图像的标准中,它们也可以稍微辨别出来 我的第一次尝试是k-means,但实际上是根据平均值进行聚类的(平均值有区别,特别是与周围像素相比,但时间和角度信息更大)。我的第二次尝试是ICA,然后查看具有最大幅度的k分量,这确实成功地将图像中的某些区域识别为不同的,但没有识别出我感兴趣的像素组(视觉上不难识别它们,但它们

引出问题

我有一个二维复值图像和一系列短值。我想聚类相似的像素/分割图像。有一个或多或少的静态图像,其中有一个叠加图像,其中有一些斑点,在短序列上有一个变化的值(主要是复数的角度)。在图像的标准中,它们也可以稍微辨别出来

我的第一次尝试是k-means,但实际上是根据平均值进行聚类的(平均值有区别,特别是与周围像素相比,但时间和角度信息更大)。我的第二次尝试是ICA,然后查看具有最大幅度的k分量,这确实成功地将图像中的某些区域识别为不同的,但没有识别出我感兴趣的像素组(视觉上不难识别它们,但它们很小)

当前情况

所以,因为我的前两次尝试没有成功,我环顾了一下谷歌,这似乎是合适的。但是我在使用这个方法时遇到了一些严重的问题,主要是因为可用内存有限。然后我想,既然我有这么多像素,我可以应用光谱聚类来分离数据块

有人建议先对板块进行聚类,然后再进行组合,他接着说“最终你会遇到重组板块的问题,这个问题很容易解决”。当然,在解释中被指定为“容易”的比特从来都不容易。他链接到纸上,但这种方法不能处理平板中的所有数据。而是排除不接近主分量的向量

问题

我的问题分为两部分:

1。如何组合单独段的结果?特征向量不同,聚类数也不同。结果看起来像是在分离的平板上工作

2。不考虑单独平板中像素之间的距离/亲和力。我能做“板间板”吗?对于那些L和A不对称的板,不知道如何执行该方法。也许我可以在最后比较/合并所有特征向量

(3.是否有类似或更好的方法不需要这么多内存。计算时间也可以接受,很容易爆炸)

Matlab代码示例

生成的数据如下所示:

右图中的亮点就是我想要的。随着时间的推移,它们的变化也最大(并且在时间上是相关的)

然后设置群集:

%% perform spectral clustering in seperate slabs 
% method from http://ai.stanford.edu/~ang/papers/nips01-spectral.pdf
%get all pixel vectors in a single matrix
complexrows = reshape(permute(complexdata, [3,1,2]), [15, 921*921]);
%k means and eigs dont accept complex, so convert to real here?
complexrowsTranspose = [real(complexrows);imag(complexrows)]'; 

%lets say 10000 by 10000 matrices are still ok
npix = 10000;
nslabpix = floor(length(complexrowsTranspose)/npix);
nrestpix = rem(length(complexrowsTranspose), npix);
在适合内存的板中执行光谱聚类:

% spectral clustering 
keig = 50;%how many eigenvectors needed? more is better
affinity_sigma = 1;% i dont understand how to calculate this from the paper
tic
% start with last slab (dynamically preallocate)
for islabpix = (nslabpix+1):-1:1;
    %print progress
    islabpix/nslabpix
    toc
    if islabpix>nslabpix
        pixrange = (1:nrestpix) + ((islabpix-1)*npix);;
    else
        pixrange = (1:npix) + ((islabpix-1)*npix);
    end
    %calculate affinity between all voxels in slab
    Aff = exp( -squareform(pdist(complexrowsTranspose(pixrange,:))).^2/(2*affinity_sigma^2) ); % affinity matrix
    %calculate degree matrix for normalization
    Dsq = sparse(size(Aff,1),size(Aff,2)); %degree matrix
    for idiag=1:size(Aff,1)
        Dsq(idiag,idiag) = sum(Aff(idiag,:))^(1/2);
    end
    %normalize affinity matrix
    Lap = Dsq * Aff * Dsq; %normalize affinity matrix
    %calculate eigenvectors of affinity matrix
    [eigVectors(pixrange,1:keig), eigValues] = eigs(Lap, keig); %eigenvectors of normalized aff mat
    normEigVectors(pixrange,1:keig) = eigVectors(pixrange,1:keig)./repmat(sqrt(sum(abs(eigVectors(pixrange,1:keig)).^2,2)), [1 keig]); %normalize rows of eigen vectors, normr only works on real numbers
    % perform k means clustering on weights for eigenvectors
    [idx,C,sumd,D] = kmeans([real(normEigVectors(pixrange,1:keig)),imag(normEigVectors(pixrange,1:keig))], 5); %k means on normalized eigenvecotrs

    idxval(pixrange) = idx;
end
%reshape into image
idxim = reshape(idxval, [921, 921]);
figure; imshow(idxim,[])
toc
由此产生的聚类:

%% perform spectral clustering in seperate slabs 
% method from http://ai.stanford.edu/~ang/papers/nips01-spectral.pdf
%get all pixel vectors in a single matrix
complexrows = reshape(permute(complexdata, [3,1,2]), [15, 921*921]);
%k means and eigs dont accept complex, so convert to real here?
complexrowsTranspose = [real(complexrows);imag(complexrows)]'; 

%lets say 10000 by 10000 matrices are still ok
npix = 10000;
nslabpix = floor(length(complexrowsTranspose)/npix);
nrestpix = rem(length(complexrowsTranspose), npix);


结果看起来该方法在每个板中都有一定程度的效果;目标是对所有范数稍高、角度变化较大的斑点(tempim2中的高饱和度斑点)进行聚类,结果似乎可以识别。现在的问题主要是分离的板,没有交叉板簇。这花了我的电脑大约15分钟。对于这个例子,我减少了特征值的数量和图像的大小,因此它可以在可接受的时间内运行。我想这说明了我的问题的一部分。

我真的没有答案给你,但我认为以下几点应该可以帮助你找到答案:

  • 你声称有记忆问题。你确定你的亲和矩阵是稀疏的吗?在代码中似乎只有对角度矩阵是稀疏的。通常在像素/体素上运行光谱聚类时,会将亲和矩阵设计为非常稀疏(8连接或26连接)

  • 您将集群描述为“它们很小”。光谱聚类在不同的尺度上有着不同的分类。你确定你得到了令人满意的结果吗

  • 如何计算相邻体素之间的亲和力(相似性)?你也能测量差异吗?也就是说,对于某些体素,你能说它们不应该属于同一簇吗?如果是,您是否考虑过使用?该方法对不同的聚类尺度具有较强的鲁棒性,能够自动检测聚类数目

  • 您是否考虑过使用多尺度/方法来粗化您的数据,而不是将其残酷地分割成“板”

  • 你看过吗?如果我没有弄错的话,这种方法应该可以让你“学习”部分点上的光谱聚类,然后使用网络将聚类“外推”到新的点上


  • 升级:
    鉴于此,我要说的是,当涉及到非常大数据的光谱聚类时,将数据残酷地分割成“板块”,然后尝试将结果“缝合”在一起可能不是最好的粗略操作(我并不认为这是不可能的)。解决此问题的更好方法是显著稀疏亲和矩阵:仅计算每个点对其相邻点的成对亲和性,从而得到大部分稀疏的亲和矩阵。这样,一个人可以一次处理所有的点,而不需要“切片”和“缝合”

    关于谱聚类和相关聚类的区别:
    为什么即使在输入亲和矩阵如此稀疏的情况下,谱聚类也能聚类所有点?它如何判断点
    a
    和远处的点
    c
    应该属于同一个簇,即使它们之间没有计算亲缘关系?
    简单的答案是相似性:如果
    a
    类似于
    b
    并且
    b
    类似于
    c
    ,那么
    a
    c
    应该聚集在一起。
    陷阱在哪里?在谱聚类中,亲和矩阵中的所有条目都是
    tic
    complexrowsTranspose = [real(complexrows);imag(complexrows)]';
    indexnonzero = find(mean(tempdisk,3) > 0);
    idxval = zeros(size(complexrowsTranspose, 1),1);
    
    [irow jcol] = sparse_adj_matrix([size(meannorm,1), size(meannorm,2)], 4, 2);
    keep = ismember(irow, indexnonzero);
    irow(~keep) = [];
    jcol(~keep) = [];
    clear keep
    
    sigma = 1;
    Avect = exp(-sum((complexrowsTranspose(irow,:)-complexrowsTranspose(jcol,:)).^2,2)/(2*sigma^2));
    iAval = find([Avect>0].*[Avect<Inf]);
    Aff = sparse(irow(iAval),jcol(iAval),Avect(iAval),length(complexrowsTranspose),length(complexrowsTranspose));
    Dvector = sum(Aff,2).^(1/2);
    Dindex = find(Dvector);
    D = sparse(Dindex, Dindex, Dvector(Dindex),size(Aff,1),size(Aff,2));
    L = D * Aff * D;
    
    keig = 25;
    [Vect, Val] = eigs(L, keig);
    normVect = Vect./repmat(sqrt(sum(abs(Vect).^2,2)), [1 keig]);
    [kidx,kC,ksumd,kD] = kmeans(normVect, 5);
    
    kmeansim = reshape(kidx, [921, 921]);
    figure; imshow(kmeansim,[])
    toc
    
    complexrowsTranspose = complexrows';
    [icol irow] = sparse_adj_matrix([921, 921], 1, Inf);
    
    complexrowsTminmean = complexrowsTranspose -repmat(mean(complexrowsTranspose , 2), [1, 15]);
    complexrowsTstd = sqrt( std(real(complexrowsTranspose), [], 2).^2+std(imag(complexrowsT), [], 2).^2 );
    complexrowsTcorr = sum(real(complexrowsTminmean(icol).*complexrowsTminmean(irow)), 2)./complexrowsTstd(irow)./complexrowsTstd(icol)./(15-1);
    
    Asparse = sparse(irow, icol, 1-complexrowsTcorr, 921*921, 921*921);
    Asparse(isnan(Asparse)) = 0;
    
    K = AL_ICM(Asparse);