#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/C++ GMM算法详解及实现源码
GMM(Gaussian Mixture Model)是一种基于高斯分布的概率模型,用于对数据进行聚类和分类的算法。GMM算法将数据集看作是由多个高斯分布组成的混合模型,每个高斯分布代表一个聚类或分类。GMM算法通过最大似然估计来估计模型参数,即找到最适合数据的高斯分布的均值和协方差矩阵。
高斯混合模型(GMM),c++实现
高斯混合模型,c++实现
C++实现的高斯混合模型:GMM从入门到优化
本文还有配套的精品资源,点击获取 简介:高斯混合模型(GMM)是统计建模、机器学习和信号处理中广泛使用的概率模型,可以有效地处理数据建模和分类问题。在C++编程环境中,GMM能够通过其核心概念如均值、方差、混合系数和概率密度函数来进行数据的聚类、密度估计和异常检测等任务。GMM训练主要依靠EM算法进行迭代优化,而C++中可以通过OpenCV和Eigen等库方便地实现这一模型...
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
GMM高斯混合模型代码c++版
高斯混合模型(Gaussian Mixed Model)指的是多个高斯分布函数的线性组合,理论上GMM可以拟合出任意类型的分布,通常用于解决同一集合下的数据包含多个不同的分布的情况(或者是同一类分布但参数不一样,或者是不同类型的分布,比如正态分布和伯努利分布)。该代码用vs2012打开即可运行。
GMM:C ++实现GMM(高斯混合模型)
GMM C ++实现GMM(高斯混合模型) 中文详细信息: :
高斯混合模型的C++实现
高斯混合模型的C实现 原理 过程 代码实现高斯混合模型的C++实现原理GMM将数据的分布通过多个高斯模型进行拟合。GMM是一种聚类算法,每个component就是一个聚类中心。高斯混合模型可以得到每个数据属于每个模型的概率,是一种软聚类算法。这是来自《统计学习方法》中的定义:过程高斯混合模型使用EM算法估计模型参数。 1. 初始化模型的个数和每个高斯模型的参数,设定迭代结束条件(迭代次数,误差阈值
C++实现GMM源码
C++实现GMM分类模型的源码,高斯参数自己可以调整
Eigen: C++开源矩阵计算工具——Eigen的简单用法
Eigen非常方便矩阵操作,当然它的功能不止如此,由于本人只用到了它的矩阵相关操作,所以这里只给出了它的一些矩阵相关的简单用法,以方便快速入门。矩阵操作在算法研究过程中,非常重要,例如在图像处理中二维高斯拟合求取光斑中心时使用Eigen提供的矩阵算法,差不多十来行代码即可实现,具体可见:http://b...
基于混合高斯模型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适...
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
中国高质量夜间灯光数据
中国高质量夜间灯光数据是CnOpenData与吉林高分遥感应用研究院有限公司合作的数据库 ,基于多源夜间灯光卫星遥感影像,经过科学手段对数据进行降噪、修正、分析统计,以年度、月度为更新频率,以省市县三级行政区划作为统计单元,制作高质量夜间灯光数据。
Python邮件自动化实战:基于imaplib和email库的高效邮件管理方案
本文详细介绍了如何使用Python的imaplib和email库实现高效邮件自动化管理。通过实战案例展示自动收取、解析邮件、下载附件等核心功能,帮助开发者快速构建企业级邮件处理系统,大幅提升工作效率。特别适合需要处理大量邮件的金融、数据分析等场景。
二维 均值方差高斯分布图 python_图像分割实战 - K均值算法(K-Means)和高斯混合模型(GMM)
1. K均值算法(K-Means)是一种无监督的聚类学习算法,它尝试找到样本数据的自然类别,分类K是由用户自己定义的,它在不需要任何其它先验知识的情况下,依据算法的迭代规则,把样本划分为K类,通过不断跌代和移动质心来完成分类。是一种硬分类的方法:即以距离为依据,离哪个点距离越近,它就应该标记为哪个编号,计算两个点之间的距离,有可能是向量(x,y)或(x,y,z)。不断的迭代,中心点不断的变换,使得...
LDPC码介绍:基础&编码&译码
本博客介绍了LDPC码的基本原理,其中包括校验矩阵的构造、Tanner 图和编译码的基础知识。
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" <<.
用STM32的SPI模式2搞定SSI绝对值编码器通信(附完整代码与避坑点)
本文详细解析了如何使用STM32的SPI模式2实现SSI绝对值编码器通信,包括硬件设计、SPI配置、数据处理算法及稳定性优化技巧。通过完整的代码示例和避坑指南,帮助工程师解决时序匹配、数据解析等常见问题,提升工业自动化系统中的编码器通信可靠性。
STM32F103C8T6全桥逆变电路PWM波生成(基于HAL库)
全桥逆变电路需要两组开关管相互协同工作,故需要两路PWM控制信号,为了防止电源短路,需要保证同一桥臂的上下两个开关管不会同时导通,故两路PWM在相位上需要相差180°;为了保证高频变压器不会磁饱和,使正负半周PWM占空比相同。但是传统的互补输出达不到调节占空比调节输出电压的效果。......
二维高斯曲面拟合法求取光斑中心及算法的C++实现
(1)二维高斯去曲面拟合推导 一个二维高斯方程可以写成如下形式: 其中,G为高斯分布的幅值,,为x,y方向上的标准差,对式(1)两边取对数,并展开平方项,整理后为: 假如参与拟合的数据点有N个,则将这个N个数据点写成矩阵的形式为:A = B C, 其中: A为N*1的向量,其元素为: B为N*5的矩阵: C为一个由高斯参数组成的向量:
AI驱动芯片设计的端到端验证:AI应用架构师的全流程指南
想象你要建造一座1000层的超级摩天大楼,每个房间都有独特的功能,管道、电路、电梯系统交织如迷宫。传统的检查方式是派1000个工程师逐层逐房手动检查,耗时十年且仍可能遗漏火灾隐患。这就是今天芯片设计面临的困境:7nm芯片含百亿晶体管,相当于百亿个"房间",传统验证方法(人工编写测试用例、随机仿真)已难以应对。本文的目的,是为AI应用架构师提供一份"AI驱动芯片验证导航图",范围涵盖从验证需求分析到芯片签核的全流程,包括AI模型如何融入传统验证工具链、数据如何驱动验证效率提升、以及端到端闭环系统的构建方法。
C++实现GMM算法(附带源码)
高斯混合模型(GMM, Gaussian Mixture Model) 是一种概率模型,用于表示一个具有多个高斯分布成分的整体数据分布。它是一种非常常用的聚类和密度估计方法,在许多应用场景中,如图像处理、语音识别、异常检测等领域都有广泛的应用。
电子电器架构 --- OEM企标中规定ECU启动时间的目的
电子电器架构 --- OEM企标中规定ECU启动时间的目的
基于YOLOv11的手术器械计数系统:从数据集构建到Web应用部署
m2cai16-tool数据集:包含15种腹腔镜手术器械的标注图像Cholec80数据集:包含80个胆囊切除手术视频,标注了7种器械SurgicalTools数据集:包含超过10,000张手术器械图像,涵盖21类常见器械手术剪(Scissors)止血钳(Hemostat)持针器(Needle Holder)手术刀(Scalpel)镊子(Forceps)拉钩(Retractor)吸引器(Suction)
7752



被折叠的 条评论
为什么被折叠?



