(二) 三维点云课程---GMM

2024-01-09 13:20
文章标签 三维 课程 点云 gmm

本文主要是介绍(二) 三维点云课程---GMM,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


由于KMeans缺乏不确定性的指标,GMM算法可以解决这个问题,现在就GMM算法的原理进行解释

1.前言

单变量高斯分布
N ( x ∣ μ , σ 2 ) = 1 ( 2 π σ 2 ) 1 / 2 exp ⁡ { − 1 2 σ 2 ( x − μ ) 2 } \mathcal{N}\left(x \mid \mu, \sigma^{2}\right)=\frac{1}{\left(2 \pi \sigma^{2}\right)^{1 / 2}} \exp \left\{-\frac{1}{2 \sigma^{2}}(x-\mu)^{2}\right\} N(xμ,σ2)=(2πσ2)1/21exp{2σ21(xμ)2}
在这里插入图片描述

多变量的高斯分布,D是维数
N ( x ∣ μ , Σ ) = 1 ( 2 π ) D / 2 1 ∣ Σ ∣ 1 / 2 exp ⁡ { − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) } \mathcal{N}(\mathbf{x} \mid \boldsymbol{\mu}, \boldsymbol{\Sigma})=\frac{1}{(2 \pi)^{D / 2}} \frac{1}{|\boldsymbol{\Sigma}|^{1 / 2}} \exp \left\{-\frac{1}{2}(\mathbf{x}-\boldsymbol{\mu})^{\mathrm{T}} \boldsymbol{\Sigma}^{-1}(\mathbf{x}-\boldsymbol{\mu})\right\} N(xμ,Σ)=(2π)D/21Σ1/21exp{21(xμ)TΣ1(xμ)}
在这里插入图片描述


2.GMM原理

2.1E步推导

对于一个混合高斯模型,可以写成多个单个高斯模型通过不同的权重进行叠加,其中 π k \pi_k πk表示权重
p ( x ) = ∑ k = 1 K π k N ( x ∣ μ k , Σ k ) p(x)=\sum_{k=1}^{K} \pi_{k} \mathcal{N}\left(x \mid \mu_{k}, \Sigma_{k}\right) p(x)=k=1KπkN(xμk,Σk)
现在引入一个K维二进制变量z,表达形式如下
z k ∈ { 0 , 1 } , Σ k z k = 1 z_k\in \{0,1\},\Sigma_{k} z_{k}=1 zk{0,1},Σkzk=1
p ( z k = 1 ) p(z_k=1) p(zk=1)是高斯分布 N ( x ∣ μ k , Σ k ) \mathcal{N}\left(x \mid \mu_{k}, \Sigma_{k}\right) N(xμk,Σk)先验概率,表达如下
p ( z k = 1 ) = π k p(z_k=1)=\pi_k p(zk=1)=πk
先验的直观理解就是,不告诉我一个数据点在什么位置,只知道高斯模型的概率。以上式子有 0 ≤ π k ≤ 1 , ∑ k = 1 K π k = 1 0 \leq \pi_{k} \leq 1, \sum_{k=1}^{K} \pi_{k}=1 0πk1,k=1Kπk=1的约束,联合起来, p ( z ) p(z) p(z)的表达如下
p ( z ) = ∏ k = 1 K π k z k p(z)=\prod_{k=1}^{K} \pi_{k}^{z_{k}} p(z)=k=1Kπkzk
其中 z = [ z 1 , . . . , z k , . . . , z K ] z=[z_1,...,z_k,...,z_K] z=[z1,...,zk,...,zK]。那么 p ( x ∣ z k = 1 ) p(x|z_k=1) p(xzk=1)就坍塌成一个高斯分布了。
p ( x ∣ z k = 1 ) = N ( x ∣ μ k , Σ k ) p\left(x \mid z_{k}=1\right)=\mathcal{N}\left(x \mid \mu_{k}, \Sigma_{k}\right) p(xzk=1)=N(xμk,Σk)
所以 p ( x ∣ z ) p(x|z) p(xz)表示如下
p ( x ∣ z ) = ∏ k = 1 K N ( x ∣ μ k , Σ k ) z k p(x \mid z)=\prod_{k=1}^{K} \mathcal{N}\left(x \mid \mu_{k}, \Sigma_{k}\right)^{z_{k}} p(xz)=k=1KN(xμk,Σk)zk
根据概率中的联合密度和边缘概率的关系 p ( x ) = ∑ z p ( x , z ) p(x)=\sum_{z} p(x, z) p(x)=zp(x,z),可以得到
p ( x ) = ∑ z p ( x , z ) = ∑ z p ( z ) p ( x ∣ z ) = ∑ z ∏ k = 1 K π k z k ∏ k = 1 K N ( x ∣ μ k , Σ k ) z k = ∑ k = 1 K π k N ( x ∣ μ k , Σ k ) p(x)=\sum_{z} p(x, z)=\sum_{z}p(z)p(x|z)=\sum_{z}\prod_{k=1}^{K} \pi_{k}^{z_{k}}\prod_{k=1}^{K} \mathcal{N}\left(x \mid \mu_{k}, \Sigma_{k}\right)^{z_{k}}=\sum_{k=1}^{K} \pi_{k} \mathcal{N}\left(x \mid \mu_{k}, \Sigma_{k}\right) p(x)=zp(x,z)=zp(z)p(xz)=zk=1Kπkzkk=1KN(xμk,Σk)zk=k=1KπkN(xμk,Σk)
根据贝叶斯概率分布公式可以得到
p ( z ∣ x ) = p ( z , x ) p ( x ) = p ( z ) p ( x ∣ z ) ∑ j = 1 K p ( x ∣ z j ) p ( z j ) p(\mathbf{z} \mid \mathbf{x})=\frac{p(\mathbf{z},\mathbf{x})}{p(\mathbf{x})}=\frac{p(\mathbf{z}) p(\mathbf{x} \mid \mathbf{z})}{\sum_{j=1}^{K} p\left(\mathbf{x} \mid z_{j}\right) p\left(z_{j}\right)} p(zx)=p(x)p(z,x)=j=1Kp(xzj)p(zj)p(z)p(xz)
γ ( z k ) = p ( z k = 1 ) \gamma(z_k)=p(z_k=1) γ(zk)=p(zk=1),那么
γ ( z k ) ≡ p ( z k = 1 ∣ x ) = p ( z k = 1 ) p ( x ∣ z k = 1 ) ∑ j = 1 K p ( z j = 1 ) p ( x ∣ z j = 1 ) = π k N ( x n ∣ μ k , Σ k ) ∑ j = 1 K π j N ( x n ∣ μ j , Σ j ) \begin{aligned} \gamma\left(z_{k}\right) \equiv p\left(z_{k}=1 \mid \mathbf{x}\right) &=\frac{p\left(z_{k}=1\right) p\left(\mathbf{x} \mid z_{k}=1\right)}{\sum_{j=1}^{K} p\left(z_{j}=1\right) p\left(\mathbf{x} \mid z_{j}=1\right)} \\ &=\frac{\pi_{k} \mathcal{N}\left(\mathbf{x}_{n} \mid \mu_{k}, \Sigma_{k}\right)}{\sum_{j=1}^{K} \pi_{j} \mathcal{N}\left(\mathbf{x}_{n} \mid \mu_{j}, \Sigma_{j}\right)} \end{aligned} γ(zk)p(zk=1x)=j=1Kp(zj=1)p(xzj=1)p(zk=1)p(xzk=1)=j=1KπjN(xnμj,Σj)πkN(xnμk,Σk)

物理意义

γ n k = p ( z n k = 1 ∣ x n ) \gamma_{nk}=p(z_{nk}=1 | x_n) γnk=p(znk=1xn):一个点属于哪个类的可能性


2.2.M步推导

上式当我们知道 { π k , μ k , Σ k } \{\pi_k,\mu_k,\Sigma_k\} {πk,μk,Σk} x x x,我们可以得到 γ ( z k ) \gamma(z_k) γ(zk)。但是实际是我只知道数据点 x 1 , . . . , x N {x_1,...,x_N} x1,...,xN和聚类的个数,让我们来估计 { π k , μ k , Σ k } , γ ( z k ) \{\pi_k,\mu_k,\Sigma_k\},\gamma(z_k) {πk,μk,Σk},γ(zk),此时我们需要最大似然估计
p ( x ) = ∑ k = 1 K π k N ( x ∣ μ k , Σ k ) ln ⁡ p ( X ∣ π , μ , Σ ) = ∑ n = 1 N ln ⁡ { ∑ k = 1 K π k N ( x n ∣ μ k , Σ k ) } \begin{aligned} p(\mathbf{x}) &=\sum_{k=1}^{K} \pi_{k} \mathcal{N}\left(\mathbf{x} \mid \mu_{k}, \Sigma_{k}\right) \\ \ln p(\mathbf{X} \mid \pi, \mu, \Sigma) &=\sum_{n=1}^{N} \ln \left\{\sum_{k=1}^{K} \pi_{k} \mathcal{N}\left(\mathbf{x}_{\mathbf{n}} \mid \mu_{k}, \Sigma_{k}\right)\right\} \end{aligned} p(x)lnp(Xπ,μ,Σ)=k=1KπkN(xμk,Σk)=n=1Nln{k=1KπkN(xnμk,Σk)}
其中 X = [ x 1 , . . . , x N ] X=[x_1,...,x_N] X=[x1,...,xN],因此最大似然表达如下
π , μ , Σ = arg ⁡ max ⁡ π , μ , Σ ln ⁡ p ( X ∣ π , μ , Σ ) = arg ⁡ max ⁡ π , μ , Σ ∑ n = 1 N ln ⁡ { ∑ k = 1 K π k N ( x n ∣ μ k , Σ k ) } \pi, \mu, \boldsymbol{\Sigma}=\underset{\pi, \mu, \boldsymbol{\Sigma}}{\arg \max } \ln p(\mathbf{X} \mid \pi, \mu, \boldsymbol{\Sigma})=\underset{\pi, \mu, \boldsymbol{\Sigma}}{\arg \max } \sum_{n=1}^{N} \ln \left\{\sum_{k=1}^{K} \pi_{k} \mathcal{N}\left(\mathbf{x}_{n} \mid \mu_{k}, \boldsymbol{\Sigma}_{k}\right)\right\} π,μ,Σ=π,μ,Σargmaxlnp(Xπ,μ,Σ)=π,μ,Σargmaxn=1Nln{k=1KπkN(xnμk,Σk)}
对于求解多个变量的最优问题,大多数是固定其中多个变量,只求解一个,进行迭代求解即可。


2.2.1固定 π k , Σ k \pi_k,\Sigma_k πk,Σk,求解 μ k \mu_k μk

对上式进行求导可知,省略求导过程
0 = − ∑ n = 1 N π k N ( x n ∣ μ k , Σ k ) ∑ j π j N ( x n ∣ μ j , Σ j ) Σ K ( x n − μ k ) ⇔ 0 = − ∑ n = 1 N γ ( z n k ) Σ K ( x n − μ k ) 0 = - \sum\limits_{n = 1}^N {\frac{{{\pi _k}{\mathcal N}\left( {{x_n}\mid {\mu _k},{\Sigma _k}} \right)}}{{\sum\nolimits_j {{\pi _j}{\mathcal N}\left( {{x_n}\mid {\mu _j},{\Sigma _j}} \right)} }}} {\Sigma _K}({x_n} - {\mu _k})\\ \Leftrightarrow 0 = - \sum\limits_{n = 1}^N {\gamma ({z_{nk}})} {\Sigma _K}({x_n} - {\mu _k}) 0=n=1NjπjN(xnμj,Σj)πkN(xnμk,Σk)ΣK(xnμk)0=n=1Nγ(znk)ΣK(xnμk)
化简得
μ k = ∑ n = 1 N γ ( z n k ) x n N k , N k = ∑ n = 1 N γ ( z n k ) {\mu _k} = \frac{{\sum\limits_{n = 1}^N {\gamma ({z_{nk}})} {x_n}}}{{{N_k}}},{N_k} = \sum\limits_{n = 1}^N {\gamma ({z_{nk}})} μk=Nkn=1Nγ(znk)xn,Nk=n=1Nγ(znk)
物理意义
N k N_k Nk:分配给聚类K的有效点数,即有多个点属于k这个类

μ k \mu_k μk:所有点在k这个类上的加权平均,这个不同于KMeans简单的进行求平均,在这里引入了权重的概念


2.2.2固定 π k , μ k \pi_k,\mu_k πk,μk,求解 Σ k \Sigma_k Σk

求导过程省略
Σ k = 1 N k ∑ n = 1 N γ ( z n k ) ( x n − μ k ) ( x n − μ k ) T , N k = ∑ n = 1 N γ ( z n k ) {\Sigma _k} = \frac{1}{{{N_k}}}\sum\limits_{n = 1}^N {\gamma ({z_{nk}})({x_n} - {\mu _k})} {({x_n} - {\mu _k})^T},{N_k} = \sum\limits_{n = 1}^N {\gamma ({z_{nk}})} Σk=Nk1n=1Nγ(znk)(xnμk)(xnμk)TNk=n=1Nγ(znk)
物理意义

Σ k \Sigma_k Σk:是以 μ k \mu_k μk为中心的所有点方差的加权平均值,权重为后验概率 γ ( z n k ) \gamma(z_{nk}) γ(znk)


2.2.3固定 μ k , Σ k \mu_k,\Sigma_k μk,Σk,求解 π k \pi_k πk

解这个问题时,存在一个限制条件$\sum\nolimits_{k = 1}^K {{\pi _k} = 1} $。关于有限制条件的求导,使用拉格朗日求导法
ln ⁡ p ( X ∣ π , μ , Σ ) + λ ( ∑ k = 1 K π k − 1 ) \ln p(\mathbf{X} \mid \pi, \mu, \Sigma) +\lambda(\sum \limits_{k=1}^K \pi_k-1) lnp(Xπ,μ,Σ)+λ(k=1Kπk1)
对上式进行关于 μ k \mu_k μk的求导
∑ n = 1 N N ( x n ∣ μ k , Σ k ) ∑ j π j N ( x n ∣ μ j , Σ j ) + λ = 0 \sum\limits_{n = 1}^N {\frac{{{\mathcal N}\left( {{x_n}\mid {\mu _k},{\Sigma _k}} \right)}}{{\sum\nolimits_j {{\pi _j}{\mathcal N}\left( {{x_n}\mid {\mu _j},{\Sigma _j}} \right)} }}}+\lambda=0 n=1NjπjN(xnμj,Σj)N(xnμk,Σk)+λ=0
首先求解 λ \lambda λ,等式两边同时乘以 ∑ k = 1 K π k \sum \limits_{k=1}^K \pi_k k=1Kπk,化简得

∑ k = 1 K π k ∑ n = 1 N N ( x n ∣ μ k , Σ k ) ∑ j π j N ( x n ∣ μ j , Σ j ) + ∑ k = 1 K π k λ = 0 \sum \limits_{k=1}^K \pi_k {\sum\limits_{n = 1}^N {\frac{{{\mathcal N}\left( {{x_n}\mid {\mu _k},{\Sigma _k}} \right)}}{{\sum\nolimits_j {{\pi _j}{\mathcal N}\left( {{x_n}\mid {\mu _j},{\Sigma _j}} \right)} }}} }+\sum \limits_{k=1}^K \pi_k\lambda=0 k=1Kπkn=1NjπjN(xnμj,Σj)N(xnμk,Σk)+k=1Kπkλ=0
∑ k = 1 K ∑ n = 1 N π k N ( x n ∣ μ k , Σ k ) ∑ j π j N ( x n ∣ μ j , Σ j ) + ∑ k = 1 K π k λ = 0 \sum \limits_{k=1}^K {\frac{{\sum\limits_{n = 1}^N {\pi_k}{\mathcal N}\left( {{x_n}\mid {\mu _k},{\Sigma _k}} \right)}}{{\sum\nolimits_j {{\pi _j}{\mathcal N}\left( {{x_n}\mid {\mu _j},{\Sigma _j}} \right)} }}}+\sum \limits_{k=1}^K \pi_k\lambda =0 k=1KjπjN(xnμj,Σj)n=1NπkN(xnμk,Σk)+k=1Kπkλ=0
( ∑ n = 1 N 1 ) + λ = 0 λ = − N (\sum \limits_{n=1}^N 1)+\lambda=0\\ \lambda=-N (n=1N1)+λ=0λ=N
再次将 λ \lambda λ代入,进而求解 π k \pi_k πk
∑ n = 1 N N ( x n ∣ μ k , Σ k ) ∑ j π j N ( x n ∣ μ j , Σ j ) + λ = 0 1 π k ∑ n = 1 N π k N ( x n ∣ μ k , Σ k ) ∑ j π j N ( x n ∣ μ j , Σ j ) − N = 0 1 π k ∑ n = 1 N γ n k − N = 0 π k = N k N \sum\limits_{n = 1}^N {\frac{{{\mathcal N}\left( {{x_n}\mid {\mu _k},{\Sigma _k}} \right)}}{{\sum\nolimits_j {{\pi _j}{\mathcal N}\left( {{x_n}\mid {\mu _j},{\Sigma _j}} \right)} }}}+\lambda=0 \\ \frac{1}{\pi_k} \sum\limits_{n = 1}^N {\frac{{{\pi_k}{\mathcal N}\left( {{x_n}\mid {\mu _k},{\Sigma _k}} \right)}}{{\sum\nolimits_j {{\pi _j}{\mathcal N}\left( {{x_n}\mid {\mu _j},{\Sigma _j}} \right)} }}}-N=0\\ \frac {1}{\pi_k} \sum \limits_{n=1}^N\gamma_{nk}-N=0\\ \pi_k=\frac {N_k}{N} n=1NjπjN(xnμj,Σj)N(xnμk,Σk)+λ=0πk1n=1NjπjN(xnμj,Σj)πkN(xnμk,Σk)N=0πk1n=1NγnkN=0πk=NNk
物理意义

π k \pi_k πk:表示的是实际上有多少个点属于我这个类$\div $所有点的数量


3.GMM总结

  • 初始化每一个高斯模型的权重 π k \pi_k πk,均值 μ k \mu_k μk和方差 Σ k \Sigma_k Σk

    # π(alpha),初始化权重值,即初始时,平分权重
    alpha = np.ones(self.n_clusters) / self.n_clusters# μ(mu),随机初始化期望值
    mu = np.array([[.403, .237], [.714, .346], [.532, .472]])# ∑(sigma),这是一个k*data.shape[1]*data.shape[1]三维矩阵,目的是一次性的将方差储存起来,其中初值为对角矩阵,
    # 这里以3*2*2,∑为[[[0.1,0],[0,0.1]],[[0.1,0],[0,0.1]],[[0.1,0],[0,0.1]]],第一块(sigma[0])为k=0对应的方差,同理第二块,第三块也是这样
    sigma = np.full((self.n_clusters, n_features, n_features), np.diag(np.full(n_features, 0.1)))
    

    其中 self.n_clusters表示为聚类的个数,n_features表示数据的列数,这里是2,数据是以N*2表示的


  • E步:通过权重,均值,方差估计后验概率 γ n k = p ( z n k = 1 ∣ x n ) \gamma_{nk}=p(z_{nk}=1 | x_n) γnk=p(znk=1xn),表示一个点属于哪个类的可能性

    gamma = self.computeGamma(data, mu, sigma, alpha, self.multiGaussian)   #维数N*k
    

    计算 γ ( z n k ) \gamma(z_{nk}) γ(znk),调用computeGamma函数和multiGaussian函数,函数如下


    def computeGamma(self, X, mu, sigma, alpha, multiGaussian):n_samples = X.shape[0]n_clusters = len(alpha)gamma = np.zeros((n_samples, n_clusters))p = np.zeros(n_clusters)g = np.zeros(n_clusters)for i in range(n_samples):for j in range(n_clusters):p[j] = multiGaussian(X[i], mu[j], sigma[j])   #对应公式中的 N(xn|μj,∑j)g[j] = alpha[j] * p[j]                    #对应公式中的πj*N(xn|μj,∑j)for k in range(n_clusters):if np.sum(g)!=0:gamma[i, k] = g[k] / np.sum(g)            #对应公式的γnk的求解return gamma
    

    其中 p [ j ] p[j] p[j]对应 N ( x ∣ μ k , Σ k ) \mathcal{N}\left(x \mid \mu_{k}, \Sigma_{k}\right) N(xμk,Σk), g [ j ] g[j] g[j]对应 π k N ( x ∣ μ k , Σ k ) \pi_{k} \mathcal{N}\left(x \mid \mu_{k}, \Sigma_{k}\right) πkN(xμk,Σk)

     def multiGaussian(self, x, mu, sigma):return 1 / ((2 * np.pi) * pow(np.linalg.det(sigma), 0.5)) * np.exp(-0.5 * (x - mu).dot(np.linalg.pinv(sigma)).dot((x - mu).T))
    

    对应于前言的多元高斯分布函数


  • M步:计算最新的权重,均值,和方差
    { μ k = ∑ n = 1 N γ ( z n k ) x n N k Σ k = 1 N k ∑ n = 1 N γ ( z n k ) ( x n − μ k ) ( x n − μ k ) T π k = N k N N k = ∑ n = 1 N γ ( z n k ) N = ∑ n = 1 N 1 \left\{ \begin{array}{l} {\mu _k} = \frac{{\sum\limits_{n = 1}^N {\gamma ({z_{nk}})} {x_n}}}{{{N_k}}}\\ {\Sigma _k} = \frac{1}{{{N_k}}}\sum\limits_{n = 1}^N {\gamma ({z_{nk}})({x_n} - {\mu _k})} {({x_n} - {\mu _k})^T}\\ {\pi _k} = \frac{{{N_k}}}{N}\\ {N_k} = \sum\limits_{n = 1}^N {\gamma ({z_{nk}})} \\ N = \sum\limits_{n = 1}^N 1 \end{array} \right. μk=Nkn=1Nγ(znk)xnΣk=Nk1n=1Nγ(znk)(xnμk)(xnμk)Tπk=NNkNk=n=1Nγ(znk)N=n=1N1
    计算权重

    alpha = np.sum(gamma, axis=0) / n_samples
    

    对应公式 π k = N k N {\pi _k} = \frac{{{N_k}}}{N} πk=NNk

    计算均值

    #更新均值 μ(mu)
    gamma_xn=data * gamma[:, i].reshape((n_samples, 1))  #维数N*k
    mu_molecule=np.sum(gamma_xn, axis=0)    #维数(k,)
    mu_denominator=np.sum(gamma, axis=0)[i]
    mu[i]=mu_molecule/mu_denominator
    

    其中gamma_xn表示 γ ( z n k ) x n \gamma ({z_{nk}}){x_n} γ(znk)xn,mu_molecule表示 ∑ n = 1 N γ ( z n k ) x n \sum \limits_{n=1}^N \gamma(z_{nk})x_n n=1Nγ(znk)xn,mu_denominator表示 N k N_k Nk

    计算协方差矩阵

    sigma[i] = 0
    for j in range(n_samples):#更新方差∑(sigma)xn_muk=data[j].reshape((1, n_features))-mu[i]    #维数 1*ksigma[i]+=(xn_muk).T.dot(xn_muk)*gamma[j,i]  #维数 k*k
    sigma[i] = sigma[i] / (np.sum(gamma, axis=0)[i])
    

    其中xn_muk表示为 x n − μ k x_n-\mu_k xnμk。注意这里和公式不一样,是 ( x n − μ k ) T ( x n − μ k ) (x_n-\mu_k)^T(x_n-\mu_k) (xnμk)T(xnμk)这样才可以表示为协方差矩阵,维数为2*2。


  • 评估log函数的,如果收敛,则停止,否则返回到E步

效果如下,不同于KMeans的是,数据点有个渐变的过程,并不是非0即1

在这里插入图片描述


4.GMM完整代码

import numpy as np
from numpy import *
import pylab
import random, mathimport matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
from scipy.stats import multivariate_normalplt.style.use('seaborn')class GMM(object):def __init__(self, n_clusters, max_iter=50):self.n_clusters = n_clusters         #聚类个数self.ITER = max_iter                 #最大迭代次数self.mu = 0                          #初始化均值self.sigma = 0                       #初始化协方差矩阵self.alpha = 0                       #初始化权重#计算多元高斯分布函数,注意这里是(x-mu)*sigma^(-1)*(x-mu)^T公式没有错,因为这里算出来的是一个数,并且不能直接运用在三维中,缺了个系数def multiGaussian(self, x, mu, sigma):return 1 / ((2 * np.pi) * pow(np.linalg.det(sigma), 0.5)) * np.exp(-0.5 * (x - mu).dot(np.linalg.pinv(sigma)).dot((x - mu).T))#计算后验概率γnk,维数为data.shape[0]*k,这里以k=2为例,第一列放的是所有属于k=0类的概率,第二列放的是所有属于k=1类的概率def computeGamma(self, X, mu, sigma, alpha, multiGaussian):n_samples = X.shape[0]n_clusters = len(alpha)gamma = np.zeros((n_samples, n_clusters))p = np.zeros(n_clusters)g = np.zeros(n_clusters)for i in range(n_samples):for j in range(n_clusters):p[j] = multiGaussian(X[i], mu[j], sigma[j])   #对应公式中的 N(xn|μj,∑j)g[j] = alpha[j] * p[j]                        #对应公式中的πj*N(xn|μj,∑j)for k in range(n_clusters):if np.sum(g)!=0:gamma[i, k] = g[k] / np.sum(g)            #对应公式的γnk的求解return gamma#GMM的核心代码def fit(self, data):n_samples = data.shape[0]n_features = data.shape[1]'''mu=data[np.random.choice(range(n_samples),self.n_clusters)]'''#初始化初值# π(alpha),初始化权重值,即初始时,平分权重alpha = np.ones(self.n_clusters) / self.n_clusters# μ(mu),随机初始化期望值mu = np.array([[.403, .237], [.714, .346], [.532, .472]])# ∑(sigma),这是一个k*data.shape[1]*data.shape[1]三维矩阵,目的是一次性的将方差储存起来,其中初值为对角矩阵,# 这里以3*2*2,∑为[[[0.1,0],[0,0.1]],[[0.1,0],[0,0.1]],[[0.1,0],[0,0.1]]],第一块(sigma[0])为k=0对应的方差,同理第二块,第三块也是这样sigma = np.full((self.n_clusters, n_features, n_features), np.diag(np.full(n_features, 0.1)))for i in range(self.ITER):#E步,更新后验概率γnk,维数N*kgamma = self.computeGamma(data, mu, sigma, alpha, self.multiGaussian)   #M步,更新三大参数:权重,均值,方差#计算权重π(alpha),维数1*kalpha = np.sum(gamma, axis=0) / n_samplesfor i in range(self.n_clusters):#计算均值 μ(mu)gamma_xn=data * gamma[:, i].reshape((n_samples, 1))  #维数N*kmu_molecule=np.sum(gamma_xn, axis=0)    #维数(k,)mu_denominator=np.sum(gamma, axis=0)[i]mu[i]=mu_molecule/mu_denominatorsigma[i] = 0for j in range(n_samples):#计算协方差矩阵∑(sigma)xn_muk=data[j].reshape((1, n_features))    #维数 1*k#维数 k*ksigma[i]+=(xn_muk-mu[i]).T.dot(xn_muk-mu[i])*gamma[j,i] sigma[i] = sigma[i] / (np.sum(gamma, axis=0)[i])self.mu = mu             #更新权重π(alpha)self.sigma = sigma       #更新均值μ(mu)self.alpha = alpha       #更新协方差矩阵∑(sigma)#GMM算法中的最终预测点的分类函数def predict(self, data):pred = self.computeGamma(data, self.mu, self.sigma, self.alpha, self.multiGaussian)cluster_results = np.argmax(pred, axis=1)return cluster_results##初始化画布为4行2列
fig, ax = plt.subplots(4, 2)
## 可视化函数
## 输入:x 原始数的路径
#        i 画布的行
#        j 画布的列
#        n_clusters 聚类的个数,认为指定
def show_result(x,i,j,n_clusters):ax[i][j].scatter(x[:, 0], x[:, 1], s=20, c="b", marker='o')ax[i][j].set_xlabel('x')ax[i][j].set_ylabel('y')gmm = GMM(n_clusters)gmm.fit(x)cat = gmm.predict(x)list_max = max(cat)if list_max == 1:for idx, value in enumerate(cat):if value == 0:ax[i][j+1].scatter(x[idx, 0], x[idx, 1], s=20, c="r", marker='*')elif value == 1:ax[i][j+1].scatter(x[idx, 0], x[idx, 1], s=20, c="g", marker='+')elif list_max == 2:for idx, value in enumerate(cat):if value == 0:ax[i][j+1].scatter(x[idx, 0], x[idx, 1], s=20, c="r", marker='*')elif value == 1:ax[i][j+1].scatter(x[idx, 0], x[idx, 1], s=20, c="g", marker='+')elif value == 2:ax[i][j+1].scatter(x[idx, 0], x[idx, 1], s=20, c="y", marker='^')ax[i][j+1].set_xlabel('x')ax[i][j+1].set_ylabel('y')## 读取数据的函数
def read_txt(path):filename = path  # txt文件和当前脚本在同一目录下,所以不用写具体路径pos = []Efield = []with open(filename, 'r') as file_to_read:while True:lines = file_to_read.readline()  # 整行读取数据if not lines:breakpassp_tmp, E_tmp = [float(i) for i in lines.split(",")]  # 将整行数据分割处理,如果分割符是空格,括号里就不用传入参数,如果是逗号, 则传入‘,'字符。pos.append(p_tmp)  # 添加新读取的数据Efield.append(E_tmp)passpos = np.array(pos)  # 将数据从list类型转换为array类型。Efield = np.array(Efield)x=np.vstack(pos)y=np.vstack(Efield)X=np.concatenate((x,y),axis=1)return Xif __name__ == '__main__':x_circle = read_txt("circle.txt")show_result(x_circle, 0, 0, 2)x_moons = read_txt("moons.txt")show_result(x_moons, 1, 0, 2)x_blobs = read_txt("varied.txt")show_result(x_blobs, 2, 0, 3)x_aniso = read_txt("aniso.txt")show_result(x_aniso, 3, 0, 3)plt.show()

仿真结果如下
在这里插入图片描述
数据集下载参见之前的KMeans文章


5.GMM的一些缺点

最大似然公式存在奇异性的问题:假设GMM的协方差矩阵为 Σ k = σ k 2 I \Sigma_k=\sigma^2_{k}I Σk=σk2I, I I I为单位向量,有一个数据点 x n = μ j x_n=\mu_j xn=μj,那么高斯分布为
N ( x ∣ x n , σ j 2 I ) = 1 ( 2 π ) 1 / 2 1 σ j \mathcal{N}\left(x \mid x_n, \sigma_{j}^2I\right)=\frac{1}{(2\pi)^{1/2}} \frac{1}{\sigma_j} N(xxn,σj2I)=(2π)1/21σj1
那么如果 σ j \sigma_j σj非常小,高斯分布函数就非常大,系统可能会崩溃,例如如果一个点就是一个高斯分布,那么 σ = 0 \sigma=0 σ=0,N->0, ∏ p ( x i ) \prod p(x_i) p(xi)->0。因此,在GMM最大似然公式中,我们将高斯点放在单个点上,这会导致很大的问题。

解决方法:

1.采用MAP的方法,初始考虑 μ k , Σ k \mu_k,\Sigma_k μk,Σk,假如高斯分布的方差不能太小,就不会掉到奇点问题,但比较复杂

2.如果出现某个高斯点的方差很小,随机初始化另外的一个值。

其次GMM存在和KMeans同样的通病,需要人工给定聚类数。

这篇关于(二) 三维点云课程---GMM的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/587245

相关文章

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

hdu4826(三维DP)

这是一个百度之星的资格赛第四题 题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=500 题意:从左上角的点到右上角的点,每个点只能走一遍,走的方向有三个:向上,向下,向右,求最大值。 咋一看像搜索题,先暴搜,TLE,然后剪枝,还是TLE.然后我就改方法,用DP来做,这题和普通dp相比,多个个向上

2、PF-Net点云补全

2、PF-Net 点云补全 PF-Net论文链接:PF-Net PF-Net (Point Fractal Network for 3D Point Cloud Completion)是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像

Vector3 三维向量

Vector3 三维向量 Struct Representation of 3D vectors and points. 表示3D的向量和点。 This structure is used throughout Unity to pass 3D positions and directions around. It also contains functions for doin

《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》P98

更改为 差分的数学表达式从泰勒级数展开式可得: 后悔没听廖老师的。 禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》 禹晶、肖创柏、廖庆敏《数字图像处理》资源二维码

【LVI-SAM】激光雷达点云处理特征提取LIO-SAM 之FeatureExtraction实现细节

激光雷达点云处理特征提取LIO-SAM 之FeatureExtraction实现细节 1. 特征提取实现过程总结1.0 特征提取过程小结1.1 类 `FeatureExtraction` 的整体结构与作用1.2 详细特征提取的过程1. 平滑度计算(`calculateSmoothness()`)2. 标记遮挡点(`markOccludedPoints()`)3. 特征提取(`extractF

数据集 3DPW-开源户外三维人体建模-姿态估计-人体关键点-人体mesh建模 >> DataBall

3DPW 3DPW-开源户外三维人体建模数据集-姿态估计-人体关键点-人体mesh建模 开源户外三维人体数据集 @inproceedings{vonMarcard2018, title = {Recovering Accurate 3D Human Pose in The Wild Using IMUs and a Moving Camera}, author = {von Marc

Rhinoceros 8 for Mac/Win:重塑三维建模边界的革新之作

Rhinoceros 8(简称Rhino 8),作为一款由Robert McNeel & Assoc公司开发的顶尖三维建模软件,无论是对于Mac还是Windows用户而言,都是一款不可多得的高效工具。Rhino 8以其强大的功能、广泛的应用领域以及卓越的性能,在建筑设计、工业设计、产品设计、三维动画制作、科学研究及机械设计等多个领域展现出了非凡的实力。 强大的建模能力 Rhino 8支持多种建

数据集 Ubody人体smplx三维建模mesh-姿态估计 >> DataBall

Ubody开源人体三维源数据集-smplx-三维建模-姿态估计 UBody:一个连接全身网格恢复和真实生活场景的上半身数据集,旨在拟合全身网格恢复任务与现实场景之间的差距。 UBody包含来自多人的现实场景的1051k张高质量图像,这些图像拥有2D全身关键点、3D SMPLX模型。 UBody由国际数字经济学院(IDEA)提供。 (UBody was used for mesh r

三维布尔运算对不规范几何数据的兼容处理

1.前言 上一篇文章谈过八叉树布尔运算,对于规范几何数据的情况是没有问题的。 在实际情况中,由于几何数据来源不一,处理和生成方式不一,我们无法保证进行布尔运算的几何数据都是规范的,对于不规范情况有时候也有需求,这就需要兼容不规范数据情况,当然这种兼容不是一味的让步,而是对于存在有限的不规范数据的兼容处理。 2.原始数据示例 下图是一个大坝模型和之上要对其进行布尔运算的立方体。 大坝模型由