C++高斯混合型GMM实现

C++实现GMM算法(附完整源码) 阅读详情
#ifndef MYGMM_H
#define MYGMM_H
#include <iostream>
#include <Eigen/Dense>
#include <math.h>
#include <vector>
#define EPS 0.00000001

using namespace std;
using namespace Eigen;

Eigen::MatrixXf getCov(Eigen::MatrixXf input)
{
    // 按列求均值
    Eigen::MatrixXf meanVec = input.colwise().mean();
    Eigen::RowVectorXf meanVecRow(Eigen::RowVectorXf::Map(meanVec.data(), input.cols()));
    Eigen::MatrixXf zeroMeanMat = input;
    zeroMeanMat.rowwise() -= meanVecRow;
    if (input.rows() == 1)
        return (zeroMeanMat.adjoint() * zeroMeanMat) / double(input.rows());
    else
        return (zeroMeanMat.adjoint() * zeroMeanMat) / double(input.rows() - 1);
}

float GMM(Eigen::RowVectorXf u, Eigen::MatrixXf sigma, Eigen::RowVectorXf x)
{
    float tmp = -0.5 * (x - u) * sigma.inverse() * (x - u).transpose();
    return exp(tmp) / pow(2.0 * 3.1416, sigma.rows() / 2.0) / pow(sigma.determinant(), 0.5);
}

class MyGMM
{
public:
    void Init(vector<vector<float>> input)
    {
        Eigen::MatrixXf tmp(input.size(), input[0].size());
        input_ = tmp;
        rows_ = input_.rows();
        cols_ = input_.cols();
        for (int i = 0; i < rows_; ++i)
        {
            for (int j = 0; j < cols_; ++j)
            {
                input_(i, j) = input[i][j];
            }
        }
        K_ = 3;
        a_.resize(K_);
        float kk = 0;
        for (int i = 0; i < K_ - 1; ++i)
        {
            a_[i] = 1.0 / K_;
            kk += a_[i];
        }
        a_[K_ - 1] = 1 - kk;
        Eigen::MatrixXf u(K_, cols_);
        sigma_.resize(K_);
        for (int i = 0; i < K_; ++i)
        {
            u.row(i) = input_.row(rows_ * i / K_);
            sigma_[i] = getCov(input_);
        }
        u_ = u;
        belong_.resize(rows_);
        iter_ = 0;
        last_ = 0;
    }

    int EM()
    {
        while (1)
        {
            vector<int> N(K_, 0);
            Eigen::RowVectorXf gamma = RowVectorXf::Zero(rows_);
            // Expectation
            for (int i = 0; i < rows_; ++i)
            {
                float sum = 0;
                for (int j = 0; j < K_; ++j)
                {
                    if (a_[j] < EPS)
                        continue;
                    float tmp = a_[j] * GMM(u_.row(j), sigma_[j], input_.row(i));
                    sum += tmp;
                    if (tmp > gamma[i])
                    {
                        gamma[i] = tmp;
                        belong_[i] = j;
                    }
                }
                gamma[i] /= sum;
                N[belong_[i]]++;
            }
            // 
            for (int j = 0; j < K_; ++j)
            {
                if (N[j] == 0)
                {
                    return 0;
                } else if(N[j] == 1) {
                    return 1;
                }
            }
            // reset
            u_ = MatrixXf::Zero(K_, cols_);
            for (int j = 0; j < K_; ++j)
            {
                sigma_[j] = MatrixXf::Zero(cols_, cols_);
            }
            // Maximization
            for (int i = 0; i < rows_; ++i)
            {
                u_.row(belong_[i]) += gamma[i] * input_.row(i);
            }
            for (int j = 0; j < K_; ++j)
            {
                u_.row(j) /= N[j];
            }
            for (int i = 0; i < rows_; ++i)
            {
                sigma_[belong_[i]] += gamma[i] * (input_.row(i) - u_.row(belong_[i])).transpose() * (input_.row(i) - u_.row(belong_[i]));
            }
            for (int j = 0; j < K_; ++j)
            {
                sigma_[j] /= N[j];
                if (sigma_[j].determinant() == 0)
                {
                    return 2;
                }
                a_[j] = N[j] * 1.0 / rows_;
            }
            // Judge
            float judge = 0;
            for (int i = 0; i < rows_; ++i)
            {
                int tmp = belong_[i];
                float gg = GMM(u_.row(tmp), sigma_[tmp], input_.row(i));
                judge = judge + log(a_[tmp]) + log(gg);
            }
            ++iter_;
            // cout << judge << endl;
            if (iter_ > 6 && fabs(last_ - judge) < 0.00001)
                return 9;
            last_ = judge;
        }
    }

    Eigen::MatrixXf input_;
    int rows_;
    int cols_;
    int K_;
    vector<float> a_;
    Eigen::MatrixXf u_;
    vector<MatrixXf> sigma_;
    vector<int> belong_;
    int iter_;
    float last_;
};
#endif
使用C++实现高斯混合模型(Gaussian Mixture Model,GMM)算法 通过上述代码,我们定义了一个GMM类,其中包含了高斯分布的数量、高斯分布的向量以及训练和预测方法。在预测方法中,我们根据给定的输入值,选择具有最大概率的高斯分布作为预测结果。在GMM类中,我们需要定义高斯分布的数量(numComponents)以及一个保存高斯分布的向量(components)。我们定义了一个高斯分布的类和一个GMM类,并实现了GMM算法的训练和预测方法。通过上述测试程序,我们可以看到,在给定一个包含两个高斯分布的数据集后,我们可以使用GMM类进行训练,并预测新的数据点所属的高斯分布。 阅读详情

相关推荐

C/C++ GMM算法详解及实现源码

GMM(Gaussian Mixture Model)是一种基于高斯分布的概率模型,用于对数据进行聚类和分类的算法。GMM算法将数据集看作是由多个高斯分布组成的混合模型,每个高斯分布代表一个聚类或分类。GMM算法通过最大似然估计来估计模型参数,即找到最适合数据的高斯分布的均值和协方差矩阵。

希望我的博客,能帮上你解决学习中工作中所遇到的问题 7752

高斯混合模型(GMM),c++实现

高斯混合模型,c++实现

qq_25921073的博客 1170

C++实现的高斯混合模型:GMM从入门到优化

本文还有配套的精品资源,点击获取 简介:高斯混合模型(GMM)是统计建模、机器学习和信号处理中广泛使用的概率模型,可以有效地处理数据建模和分类问题。在C++编程环境中,GMM能够通过其核心概念如均值、方差、混合系数和概率密度函数来进行数据的聚类、密度估计和异常检测等任务。GMM训练主要依靠EM算法进行迭代优化,而C++中可以通过OpenCV和Eigen等库方便地实现这一模型...

weixin_36328210的博客 1663

GMM的C++实现

//GMM.h #pragma once #include #include "opencv2/opencv.hpp" using namespace cv; using namespace std; //定义gmm模型用到的变量 #define GMM_MAX_COMPONT 6 //每个GMM最多的高斯模型个数 #define GMM_LEARN_A

kkkkkkkkq的博客 2028

GMM高斯混合模型代码c++版

高斯混合模型(Gaussian Mixed Model)指的是多个高斯分布函数的线性组合,理论上GMM可以拟合出任意类型的分布,通常用于解决同一集合下的数据包含多个不同的分布的情况(或者是同一类分布但参数不一样,或者是不同类型的分布,比如正态分布和伯努利分布)。该代码用vs2012打开即可运行。

GMM:C ++实现GMM(高斯混合模型)

GMM C ++实现GMM(高斯混合模型) 中文详细信息: :

高斯混合模型的C++实现

高斯混合模型的C实现 原理 过程 代码实现高斯混合模型的C++实现原理GMM将数据的分布通过多个高斯模型进行拟合。GMM是一种聚类算法,每个component就是一个聚类中心。高斯混合模型可以得到每个数据属于每个模型的概率,是一种软聚类算法。这是来自《统计学习方法》中的定义:过程高斯混合模型使用EM算法估计模型参数。 1. 初始化模型的个数和每个高斯模型的参数,设定迭代结束条件(迭代次数,误差阈值

新安浅滩的博客 2862

C++实现GMM源码

C++实现GMM分类模型的源码,高斯参数自己可以调整

Eigen: C++开源矩阵计算工具——Eigen的简单用法

Eigen非常方便矩阵操作,当然它的功能不止如此,由于本人只用到了它的矩阵相关操作,所以这里只给出了它的一些矩阵相关的简单用法,以方便快速入门。矩阵操作在算法研究过程中,非常重要,例如在图像处理中二维高斯拟合求取光斑中心时使用Eigen提供的矩阵算法,差不多十来行代码即可实现,具体可见:http://b...

Crystal_YS的博客 1157

基于混合高斯模型GMM图像分割C++

C++代码 GMM全代码打包。实测可用,欢迎下载!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

GMM C++代码

高斯混合模型的C++代码,包含详细注释,可直接运行。mian函数中的"data.txt"是数据,可设置数据的维度和数目

高斯混合模型GMM的C++实现

单高斯分布模型SGM 高斯密度函数估计是一种参数化模型。有单高斯模型(Single Gaussian Model, SGM)和高斯混合模型(Gaussian mixture model,GMM)两类。类似于聚类,根据高斯概率密度函数(PDF,见公式1)参数的不同,每一个高斯模型可以看作一种类别,输入一个样本x,即可通过PDF计算其值,然后通过一个阈值来判断该样本是否属于高斯模型。很明显,SGM适...

weixin_34240657的博客 439

GMM.rar_EM聚类_em算法 分类_gmm分类_tieq2g_高斯混合(GMM)

此算法实现高斯混合,可以对初始聚类算法选择c均值和EM,可以实现密度估计和分类。

GMM混合高斯模型的C++代码(一)

高斯混合模型 C++实现 转载请标明出处:http://www.cppblog.com/Terrile/archive/2011/01/19/120051.html 头文件:------------------------------------------  1 #ifndef _GMM_H  2 #define _GMM_H  3 #include  4 #include  

andyfu57的专栏 4259

中国高质量夜间灯光数据

中国高质量夜间灯光数据是CnOpenData与吉林高分遥感应用研究院有限公司合作的数据库 ,基于多源夜间灯光卫星遥感影像,经过科学手段对数据进行降噪、修正、分析统计,以年度、月度为更新频率,以省市县三级行政区划作为统计单元,制作高质量夜间灯光数据。

Sunny9qx的博客 3311

Python邮件自动化实战:基于imaplib和email库的高效邮件管理方案

本文详细介绍了如何使用Python的imaplib和email库实现高效邮件自动化管理。通过实战案例展示自动收取、解析邮件、下载附件等核心功能,帮助开发者快速构建企业级邮件处理系统,大幅提升工作效率。特别适合需要处理大量邮件的金融、数据分析等场景。

weixin_30500105的博客 619

二维 均值方差高斯分布图 python_图像分割实战 - K均值算法(K-Means)和高斯混合模型(GMM)

1. K均值算法(K-Means)是一种无监督的聚类学习算法,它尝试找到样本数据的自然类别,分类K是由用户自己定义的,它在不需要任何其它先验知识的情况下,依据算法的迭代规则,把样本划分为K类,通过不断跌代和移动质心来完成分类。是一种硬分类的方法:即以距离为依据,离哪个点距离越近,它就应该标记为哪个编号,计算两个点之间的距离,有可能是向量(x,y)或(x,y,z)。不断的迭代,中心点不断的变换,使得...

weixin_39956036的博客 1543

LDPC码介绍:基础&编码&译码

本博客介绍了LDPC码的基本原理,其中包括校验矩阵的构造、Tanner 图和编译码的基础知识。

渺小的颗星的博客 4309

C++Eigen简单使用

头文件 使用时包含头文件,大多数功能均可使用 #include<Eigen/Dense> 矩阵创造 Eigen::Matrix<double, 3, 3> A; //或者 Matrix3d B; 矩阵填充 A<<1,2,3,4,5,6,7,8,9; 矩阵运算 cout << "A转置矩阵:\n" << A.transpose() << endl; cout << "A伴随矩阵:\n" <&lt.

风雪夜不眠人的博客 1253

用STM32的SPI模式2搞定SSI绝对值编码器通信(附完整代码与避坑点)

本文详细解析了如何使用STM32的SPI模式2实现SSI绝对值编码器通信,包括硬件设计、SPI配置、数据处理算法及稳定性优化技巧。通过完整的代码示例和避坑指南,帮助工程师解决时序匹配、数据解析等常见问题,提升工业自动化系统中的编码器通信可靠性。

weixin_27252001的博客 265

STM32F103C8T6全桥逆变电路PWM波生成(基于HAL库)

全桥逆变电路需要两组开关管相互协同工作,故需要两路PWM控制信号,为了防止电源短路,需要保证同一桥臂的上下两个开关管不会同时导通,故两路PWM在相位上需要相差180°;为了保证高频变压器不会磁饱和,使正负半周PWM占空比相同。但是传统的互补输出达不到调节占空比调节输出电压的效果。......

weixin_45042735的博客 6025

二维高斯曲面拟合法求取光斑中心及算法的C++实现

(1)二维高斯去曲面拟合推导 一个二维高斯方程可以写成如下形式: 其中,G为高斯分布的幅值,,为x,y方向上的标准差,对式(1)两边取对数,并展开平方项,整理后为: 假如参与拟合的数据点有N个,则将这个N个数据点写成矩阵的形式为:A = B C, 其中: A为N*1的向量,其元素为: B为N*5的矩阵: C为一个由高斯参数组成的向量:

逍遥子曰: 2万+

AI驱动芯片设计的端到端验证:AI应用架构师的全流程指南

想象你要建造一座1000层的超级摩天大楼,每个房间都有独特的功能,管道、电路、电梯系统交织如迷宫。传统的检查方式是派1000个工程师逐层逐房手动检查,耗时十年且仍可能遗漏火灾隐患。这就是今天芯片设计面临的困境:7nm芯片含百亿晶体管,相当于百亿个"房间",传统验证方法(人工编写测试用例、随机仿真)已难以应对。本文的目的,是为AI应用架构师提供一份"AI驱动芯片验证导航图",范围涵盖从验证需求分析到芯片签核的全流程,包括AI模型如何融入传统验证工具链、数据如何驱动验证效率提升、以及端到端闭环系统的构建方法。

2501_92132293的博客 1241

C++实现GMM算法(附带源码)

高斯混合模型(GMM, Gaussian Mixture Model) 是一种概率模型,用于表示一个具有多个高斯分布成分的整体数据分布。它是一种非常常用的聚类和密度估计方法,在许多应用场景中,如图像处理、语音识别、异常检测等领域都有广泛的应用。

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 971

电子电器架构 --- OEM企标中规定ECU启动时间的目的

电子电器架构 --- OEM企标中规定ECU启动时间的目的

Soly_kun的博客 223

基于YOLOv11的手术器械计数系统:从数据集构建到Web应用部署

m2cai16-tool数据集:包含15种腹腔镜手术器械的标注图像Cholec80数据集:包含80个胆囊切除手术视频,标注了7种器械SurgicalTools数据集:包含超过10,000张手术器械图像,涵盖21类常见器械手术剪(Scissors)止血钳(Hemostat)持针器(Needle Holder)手术刀(Scalpel)镊子(Forceps)拉钩(Retractor)吸引器(Suction)

YOLO 396
上一篇: message_filters做成员变量时,声明和初始化的方法
下一篇: python重命名目录下所有文件
刀么克瑟拉莫
博客等级 码龄14年 68粉丝 268原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刀么克瑟拉莫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值