Training of GMM

   太多公式,只能发图,全英版提高逼格~













以下是GMM训练的matlab代码,为了加快收敛的速度,在训练之前加入了K-means聚类算法,初步估计聚类的means,weights,variences;


function TrainGMM()
    clear;
    Sample=getGMMSample(10000);
    %利用K_Means方法现对样本进行聚类,减少GMM的计算次数,加快GMM的训练速度
    [weights0,means0,conv0]=K_Means(Sample,3);%利用K-means方法加快收敛
    [weights,means,conv]=estimateGMM(Sample,3,weights0,means0,conv0);


function Sample=getGMMSample(SampleNum)
%符合混合高斯分布的数据生成函数
    weight1=0.2;
    miu1=30; %第一个分布的参数 
    sigma1=10;%第一个分布的参数 标准差
    weight2=0.5;
    miu2=100;%第二个分布的参数 
    sigma2=25;%第二个分布的参数 标准差
    weight3=0.3;
    miu3=190;%第二个分布的参数 
    sigma3=20;%第二个分布的参数 标准差
    x=0:1:255; 
    y1=normcdf(x,miu1,sigma1); 
    y2=normcdf(x,miu2,sigma2); 
    y3=normcdf(x,miu3,sigma3);
    y=weight1*y1+weight2*y2+weight3*y3; 
    u=0.002+0.996*rand(1,SampleNum);
    Sample=round(interp1(y,x,u,'linear'));
    
    
function [weights,means,conv]=estimateGMM(Sample,numOfGaussiant,weights0,means0,conv0)
    numOfSample=size(Sample,2);
    weights=weights0;
    means=means0;
    conv=conv0;
    qiutThread=1e-5;
    %calculate the P(q|X,weights,means,conv)
    while(1)
        GaussianOutput=zeros(numOfGaussiant,numOfSample);
        for i=1:1:numOfGaussiant
            %在现有假设的高斯模型下,对当前样本的概率进行计算   
            % weight(i)*N(xj|(i)th compose of the old model ) j=[0:1:numOfSample];
            singleGaussiant=normpdf(Sample,means(i),conv(i));
            GaussianOutput(i,:)=weights(i).*singleGaussiant;
        end
        %E-step calculate the expatation
        %计算P(xi|old model)
        oldGMMForOutput=sum(GaussianOutput,1);
        eachComposeContributeToOutput=zeros(numOfGaussiant,numOfSample);
        for i=1:1:numOfGaussiant
            %计算P(q|xj,old model) 
            %  =weight(i)*P(xj|(i)th compose of the old model)/P(xj|old model)
            eachComposeContributeToOutput(i,:)=GaussianOutput(i,:)./oldGMMForOutput;
        end
        %M-step maxmize the estimation
        %计算sum(P(q|xi,old model))
        Nq=sum(eachComposeContributeToOutput,2)';   
        %计算xi*P(q|xi,old model)
        tempmartixForMeans=zeros(numOfGaussiant,1);
        for j=1:1:numOfGaussiant
            tempmartixForMeans(j,:)=eachComposeContributeToOutput(j,:)*Sample';% eachComposeContributeToOutput(j,:)是行向量 Sample' 是列向量
        end
        %update means;
        means=(tempmartixForMeans')./Nq
        
        tempmartixForConvs=zeros(numOfGaussiant,1);
        for j=1:1:numOfGaussiant
            tempmartixForConvs(j,:)=eachComposeContributeToOutput(j,:)*((Sample-means(j)).^2)';
        end
        %update conv
        conv=sqrt((tempmartixForConvs')./Nq) %方差开方变标准差
        %update weight
        weights=Nq./numOfSample
        pause(1);
        %画图
        drawDistribution(Sample,weights,means,conv);
        %退出条件:产生序列的似然概率变化达到阈值
        loglikehoodOldModel=sum(log(ModelOutputProbility(Sample,numOfGaussiant,weights0,means0,conv0)));
        loglikehoodNewModel=sum(log(ModelOutputProbility(Sample,numOfGaussiant,weights,means,conv)));
        if abs(loglikehoodOldModel-loglikehoodNewModel)<qiutThread
            break;
        else
            weights0=weights;
            means0=means;
            conv0=conv;
        end
    end
    
function [weights,means,convs]=K_Means(Sample,numOfCluser)
    sampleNum=size(Sample,2);
    means=round(255*rand(1,3));%随机得到分类中心
    means0=means;
    threadHold=1e-5;%停止阈值
    while(1)
        %计算每个样本到达分类中心的距离
        distanceSampleMeans=zeros(numOfCluser,sampleNum);
        for i=1:1:numOfCluser
            distanceSampleMeans(i,:)=Sample-means(i);%计算距离:此处计算的是一维的欧氏距离。
        end
        absDistanceSampleMeans=abs(distanceSampleMeans);%取绝对值,方便下一步将点归类
        %将点分配到距离它最近的类中
        cluserMartrix=zeros(numOfCluser,sampleNum);
        for i=1:1:sampleNum
            [minValue,minimumLocation]=min(absDistanceSampleMeans(:,i));%计算最近距离的位置
            cluserMartrix(minimumLocation,i)=1;
        end
        pointAsignToCluser=sum(cluserMartrix,2);%计算分配到每个类的点的个数
        %计算重新分配后的点聚类群的均值
        cluserCenter=zeros(1,numOfCluser);
        for i=1:1:numOfCluser
            cluserCenter(1,i)=(Sample*cluserMartrix(i,:)')./pointAsignToCluser(i);
        end
        means=cluserCenter;%更新均值
        weights=pointAsignToCluser'./sampleNum;%更新权重
        if min(abs(means-means0))<threadHold %求means最小变化值是否已经小于阈值
            %重新计算分类:
            cluserMartrix=zeros(numOfCluser,sampleNum);
            for i=1:1:numOfCluser
                distanceSampleMeans(i,:)=Sample-means(i);
            end
            absDistanceSampleMeans=abs(distanceSampleMeans);
            cluserMartrix=zeros(numOfCluser,sampleNum);
            for i=1:1:sampleNum
                [minValue,minimumLocation]=min(absDistanceSampleMeans(:,i));
                cluserMartrix(minimumLocation,i)=1;
            end
            %###################################
            convs=zeros(1,numOfCluser);
            for i=1:1:numOfCluser
                bufferSample=((Sample-means(i)).^2)*cluserMartrix(i,:)';
                convs(1,i)=sqrt(bufferSample/sum(cluserMartrix(i,:)));%标准差
            end
            %画混合高斯模型图:利用K-means方法估计的权重,均值和标准差
            X=[0:1:255];
            Y=weights(1)*normpdf(X,means(1),convs(1))+weights(2)*normpdf(X,means(2),convs(2))+weights(3)*normpdf(X,means(3),convs(3));
            subplot(3,1,1);
            plot(X,Y);
            %
            break;
        else 
            means0=means;
        end
    end

 
function ProbilityVector=ModelOutputProbility(Sample,numOfGaussiant,weights,means,conv)
    %P(xi|weights,means,conv)
    GaussianOutput=zeros(numOfGaussiant,size(Sample,2));
    for i=1:1:numOfGaussiant
        %在高斯模型下,对当前样本的概率进行计算   
        % weight(i)*N(xj|(i)th compose of the old model ) j=[0:1:numOfSample];
        GaussianOutput(i,:)=weights(i)*normpdf(Sample,means(i),conv(i));
    end
    %E-step calculate the expatation
    %计算P(xi|old model)
    ProbilityVector=sum(GaussianOutput,1);
    
    
function  drawDistribution(Sample,weights,means,conv)
    %画图
    %数据分布
    xx=1:1:255;
    yy=hist(Sample,xx);
    subplot(3,1,2)
    bar(xx,yy);
    %混合模型
    X=[0:1:255];
    Y=weights(1)*normpdf(X,means(1),conv(1))+weights(2)*normpdf(X,means(2),conv(2))+weights(3)*normpdf(X,means(3),conv(3));
    subplot(3,1,3);
    plot(X,Y);
  

算法运行效果截图:


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值