65.9K
CodeProject 正在变化。 阅读更多。
Home

高斯多元分布 - 第 1 部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2014 年 8 月 18 日

CPOL

2分钟阅读

viewsIcon

10628

多元高斯分布 - 第 1 部分

引言

在本文中,我们将探讨多元高斯分布。

  • 多元高斯分布由均值向量 µ 和协方差矩阵 Σ 参数化。
    fx(x1, …, xk) = 1 / √(2π)k |Σ| exp(−1/2 (x − μ)T Σ−1 (x − μ)) ,
    其中
    μ 是一个 Nx1 的均值向量
    Σ 是一个 NxN 的协方差矩阵
    |Σ| 是 Σ 的行列式
  • 多元高斯分布也被用作向量 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mrow class="MJX-TeXAtom-ORD"> <mi>X 的概率密度函数。
  • 一种朴素的实现方法是直接按照公式进行计算以获得结果。
  • 高斯分布的定义
  • 由于我将使用大量的 OpenCV 转换例程,这些例程是为 OpenCV cv::Mat 数据结构定义的,转换为 Eigen::MatrixXf 数据结构。
  • 在加载协方差矩阵时,也会计算行列式、逆矩阵等,这些将在后续的概率计算中用到。
    void setMean(Mat &v)
    {
        Map<Eigen::Matrix<float,Dynamic,Dynamic,Eigen::RowMajor> > 
        mappedMat((float *)v.data(),1,v.size()) ;
        _mu=mappedMat;
    }
    
    void setSigma(cv::Mat &v)
    {
        Map<Eigen::Matrix<float,Dynamic,Dynamic,Eigen::RowMajor> > 
        mappedMat((float *)v.data,v.rows,v.cols) ;
        _Sigma=mappedMat;
        _dim=v.rows;
        _det=_Sigma.determinant();
        _scale=1.f/(pow(2*PI*_dim*_det,0.5));
        _invsigma=_Sigma.inverse();
    }
    
    MatrixXf setData(cv::Mat &v)
    {
        Map<Eigen::Matrix<float,Dynamic,Dynamic,Eigen::RowMajor> > 
        mappedMat((float *)v.data,1,v.cols) ;
        MatrixXf  ref=mappedMat;
        return ref;
    }
  • 概率计算只是简单地写出公式。
       void validate(float &res)
       {
    if(res<0)
               res=0;
           if(res>1)
               res=1;
           if(isnan(res))
               res=0;
        }
        
       float Prob(Mat &x)
       {
           MatrixXf tmp=setData(x);
           float res=0;
           MatrixXf tmp1=(tmp-_mu);
           MatrixXf tmp2=tmp1*_invsigma*tmp1.transpose();
           res=scale*tmp2(0,0);        
    validate(res);   
           return res;
       }
  • 协方差矩阵是正半定且对称的。
  • 对称正定矩阵 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mi mathvariant="bold">Σ 的 Cholesky 分解将其分解为下三角矩阵 L 及其转置的乘积。
  • 因此,乘积 <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"> <mtable columnalign="right center left" columnspacing="0 thickmathspace" displaystyle="true" rowspacing="3pt"> <mtr> <mtd> <mtd> <mi mathvariant="bold">Σ=LLT
    Σ−1=(LLT)−1=L−TL−1
    yTΣ−1y
    yTΣ−1y
    yTL−TL−1y
    (L−1y)T(L−1y)<mtr><mtd><mrow><mo>
  • 因此,我们只需要计算 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mrow> <mo>(L−1y)<mo> 并取其转置。
  • 因此,我们可以对协方差矩阵执行 Cholesky 分解来找到 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mrow class="MJX-TeXAtom-ORD"> <mi mathvariant="bold">L。
  • 然后,我们取 <math xmlns="http://www.w3.org/1998/Math/MathML"> <mrow class="MJX-TeXAtom-ORD"> <mi mathvariant="bold">L 的逆。
       float Prob(Mat &x)
       {
           MatrixXf tmp=setData(x);
    
           float res=0;
           MatrixXf tmp1=(tmp-_mu).transpose();
           tmp1=_LI*tmp1;
           MatrixXf tmp2=tmp1.transpose()*tmp1;
           res=tmp2(0,0);
           validate(res);   
           return res;
       }

源代码

代码可以在 git 仓库 https://github.com/pi19404/OpenVisionImgML/gaussian.hppImgML.gaussian.cpp 文件中找到。

本文档的 PDF 版本可以在下面找到

© . All rights reserved.