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

简介:

单高斯分布模型SGM

高斯密度函数估计是一种参数化模型。有单高斯模型(Single Gaussian Model, SGM)和高斯混合模型(Gaussian mixture model,GMM)两类。类似于聚类,根据高斯概率密度函数(PDF,见公式1)参数的不同,每一个高斯模型可以看作一种类别,输入一个样本x,即可通过PDF计算其值,然后通过一个阈值来判断该样本是否属于高斯模型。很明显,SGM适合于仅有两类别问题的划分,而GMM由于具有多个模型,划分更为精细,适用于多类别的划分,可以应用于复杂对象建模。

多维变量X服从高斯分布时,它的概率密度函数PDF为:

x是维度为d的列向量,u是模型期望,Σ是模型方差。在实际应用中u通常用样本均值来代替,Σ通常用样本方差来代替。很容易判断一个样x本是否属于类别C。因为每个类别都有自己的u和Σ,把x代入(1)式,当概率大于一定阈值时我们就认为x属于C类。

从几何上讲,单高斯分布模型在二维空间应该近似于椭圆,在三维空间上近似于椭球。遗憾的是在很多分类问题中,属于同一类别的样本点并不满足“椭圆”分布的特性。这就引入了高斯混合模型。

高斯混合模型GMM

高斯混合模型是单一高斯机率密度函数的延伸,由于 GMM 能够平滑地近似任意形状的密度分布,因此近年来常被用在语音、图像识别等方面,得到不错的效果。

GMM认为数据是从几个SGM中生成出来的,即

K需要事先确定好,就像K-means中的K一样。πk是权值因子。其中的任意一个高斯分布N(x;ukk)叫作这个模型的一个component。这里有个问题,为什么我们要假设数据是由若干个高斯分布组合而成的,而不假设是其他分布呢?实际上不管是什么分布,只K取得足够大,这个XX Mixture Model就会变得足够复杂,就可以用来逼近任意连续的概率密度分布,只是因为高斯函数具有良好的计算性能,所GMM被广泛地应用。

GMM是一种聚类算法,每个component就是一个聚类中心。即在只有样本点,不知道样本分类(含有隐含变量)的情况下,计算出模型参数(π,u和Σ),这可以用EM算法来求解。再用训练好的模型去差别样本所属的分类,方法是:step1随机选择K个component中的一个(被选中的概率是πk);step2把样本代入刚选好的component,判断是否属于这个类别,如果不属于则回到step1。

样本分类已知情况下的GMM

当每个样本所属分类已知时,GMM的参数非常好确定,直接利用Maximum Likelihood。设样本容量为N,属于K个分类的样本数量分别是N1,N2,...,Nk,属于第k个分类的样本集合是L(k)。

样本分类未知情况下的GMM

有N个数据点,服从某种分布Pr(x;θ),我们想找到一组参数θ,使得生成这些数据点的概率最大,这个概率就是

称为似然函数(Lilelihood Function)。通常单个点的概率很小,连乘之后数据会更小,容易造成浮点数下溢,所以一般取其对数,变成

称为log-likelihood function。

GMM的log-likelihood function就是:

这里每个样本xi所属的类别zk是不知道的。Z是隐含变量。

我们就是要找到最佳的模型参数,使得(6)式所示的期望最大,“期望最大化算法”名字由此而来。

EM估计GMM参数

1)初始值:

方案1:协方差矩阵Σk设为单位矩阵,每个模型比例的先验概率πk=1/N,均值uk设为随机数。

方案2:由k均值(k-means)聚类算法对样本进行聚类,利用各类的均值作为uk,并计算Σk,πk取各类样本占样本总数的比例。

2)EM算法:

E-Step E就是Expectation的意思,就是假设模型参数已知的情况下求隐含变量Z分别取z1,z2,...的期望,亦即Z分别取z1,z2,...的概率。在GMM中就是求数据点由各个 component生成的概率。

注意到我们在Z的后验概率前面乘以了一个权值因子αk,它表示在训练集中数据点属于类别zk的频率,在GMM中它就是πk

M-Step M就是Maximization的意思,就是用最大似然的方法求出模型参数。现在我们认为上一步求出的r(i,k)就是“数据点xi由component k生成的概率”。根据公式(3),(4),(5)可以推出均值、协方差和权值的更新公式为:

3)收敛条件:

不断地迭代E和M步骤,重复更新上面的三个值,直到参数的变化不显著。

GMM的C++实现

C++代码下载:GMM.rar

GitHub代码:https://github.com/luxiaoxun/KMeans-GMM-HMM

代码来自网络,做了简单的测试。


    本文转自阿凡卢博客园博客,原文链接:http://www.cnblogs.com/luxiaoxun/archive/2013/05/10/3071672.html,如需转载请自行联系原作者

相关文章
|
缓存 并行计算 C++
实践教程|旋转目标检测模型-TensorRT 部署(C++)
实践教程|旋转目标检测模型-TensorRT 部署(C++)
492 0
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
189 2
|
算法 C++
【动态规划】斐波那契数列模型(C++)
【动态规划】斐波那契数列模型(C++)
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
C++构建 GAN 模型:生成器与判别器平衡训练的关键秘籍
生成对抗网络(GAN)是AI领域的明星,尤其在C++中构建时,平衡生成器与判别器的训练尤为关键。本文探讨了GAN的基本架构、训练原理及平衡训练的重要性,提出了包括合理初始化、精心设计损失函数、动态调整学习率、引入正则化技术和监测训练过程在内的五大策略,旨在确保GAN模型在C++环境下的高效、稳定训练,以生成高质量的结果,推动AI技术的发展。
349 10
|
存储 数据格式 运维
开发与运维C++问题之更改数据模型为通用数据结构如何解决
开发与运维C++问题之更改数据模型为通用数据结构如何解决
108 1
|
编译器 程序员 调度
协程问题之C++20 的协程实现是基于哪种协程模型的
协程问题之C++20 的协程实现是基于哪种协程模型的
169 1
|
Linux C++
c++高级篇(三) ——Linux下IO多路复用之poll模型
c++高级篇(三) ——Linux下IO多路复用之poll模型
190 1
|
缓存 监控 网络协议
c++高级篇(二) ——Linux下IO多路复用之select模型
c++高级篇(二) ——Linux下IO多路复用之select模型
276 1
|
机器学习/深度学习 PyTorch 算法框架/工具
C++多态崩溃问题之在PyTorch中,如何定义一个简单的线性回归模型
C++多态崩溃问题之在PyTorch中,如何定义一个简单的线性回归模型
|
存储 编译器 C语言
【c++】类对象模型
【c++】类对象模型
【c++】类对象模型