为什么犰狳没有学会高斯混合模型,尽管播种random_subset却抱怨'no existing means'?

Why does Armadillo fail to learn a Gaussian Mixture Model and complain about 'no existing means' despite random_subset seeding?

本文关键字:subset no means random existing 学会 高斯 混合 模型 为什么      更新时间:2023-10-16

问题摘要:

我有一个[5 x 72580]矩阵。我正试图使用GMM_diag.learn((方法将高斯混合模型(GMM(拟合到这些数据中,其中random_subset作为初始种子模式。为什么Armadillo显示"gmm_diag::learn((:无现有手段"而无法学习模型


问题详细信息:

我正在研究一种机器学习算法,其目的是从笔迹中识别作家。我正在使用监督学习来用GMM训练我们的模型。

所有的训练数据都是从XML文件中读取的。计算完特征后,它们的值将存储在链接列表中。在此之后,列表中的元素数量将被计数,并用于在运行时初始化Armadillo mat(rix(变量,如下所示:

int totFeatureVectors = CountPointClusterElements(TRAINING_CLUSTER_LIST_INDEX);
printf("n%d elements added to listn",totFeatureVectors);
mat F = mat(NUM_POINT_BASED_FEATURES, totFeatureVectors, fill::zeros);

这里,TRAINIG_CLUSTER_LIST_INDEX和NUM_POINT_BASED_FATURES是一对可配置的项目级常量;对于我的程序NUM_POINT_BBASED_FEATURE=5和totFeatureVectors=72580。因此,变量F是一个[5 x 72580]维的双值矩阵。初始化后,我将链表中的特征值读取到F中,如下所示:

int rowInd=0, colInd=0;
PointClusterElement *iterator = allClusterPointsList;
while(iterator!=NULL)
{
    F(rowInd,colInd)=iterator->pointSample.speed;
    rowInd += 1;
    F(rowInd,colInd)=iterator->pointSample.dirn.cosComponent;
    rowInd += 1;
    F(rowInd,colInd)=iterator->pointSample.dirn.sinComponent;
    rowInd += 1;
    F(rowInd,colInd)=iterator->pointSample.curv.cosComponent;
    rowInd += 1;
    F(rowInd,colInd)=iterator->pointSample.curv.sinComponent;
    rowInd += 1;
    if(rowInd==NUM_POINT_BASED_FEATURES)
    {
        rowInd=0;
        colInd += 1;
    }
    iterator=iterator->nextClusterElement;
}

将特征值分配给F中的位置是以列为主的方式进行的,即F的每一列表示分配后的特征向量。我甚至将F的值写入一个文本文件,以验证所有的特征值都已正确设置,是的,它正在发生,没有任何问题

FILE *fp = fopen(PROGRAM_DATA_OUTPUT_PATH,"w");
if(fp!=NULL)
{
    int r,c;
    for(c=0; c<totFeatureVectors; c++)
    {
        for(r=0; r<NUM_POINT_BASED_FEATURES; r++)
        {
            fprintf(fp,"%lft",F(r,c));
        }
        fprintf(fp,"n");
    }
}
fclose(fp);

到目前为止,一切都很好。但在此之后,当我声明一个gmm_diag变量并尝试使用其learn((方法将gmm拟合为F时,程序显示警告"gmm_diag::learn(

gmm_diag writerModel;
bool result = writerModel.learn(F, 20, maha_dist, random_subset, 100, 100, VARIANCE_FLOORING_FACTOR, true);
writerModel.dcovs.print("covariances:n");
writerModel.hefts.print("weights:n");
writerModel.means.print("means:n");
if(result==true)
{
    printf("nModel learnt");
}
else if(result==false)
{
    printf("nModel not learnt");
}

我在IDE上打开了learn((方法,据我所知,只有当初始种子模式保持存在时,才会显示此错误(警告(消息。我引用的源文件位于/usr/include/aarmadillo_bits/gmm_diag_meat.hpp

我的问题是,为什么即使我的种子是使用random_subset模式完成的,也会发生这种情况?我应该如何让我的模型学习?不确定我在这里错过了什么。。。提供的文档和代码示例位于http://arma.sourceforge.net/docs.html#gmm_diag没有太大帮助(这里的短程序即使没有初始化GMM的方法也能工作(。下方给出了代码

int main(int argc, char** argv) {
int totFeatureVectors = CountPointClusterElements(TRAINING_CLUSTER_LIST_INDEX);
printf("n%d elements added to listn",totFeatureVectors);
mat F = mat(NUM_POINT_BASED_FEATURES, totFeatureVectors, fill::zeros);
int rowInd=0, colInd=0;
PointClusterElement *iterator = allClusterPointsList;
while(iterator!=NULL)
{
    F(rowInd,colInd)=iterator->pointSample.speed;
    rowInd += 1;
    F(rowInd,colInd)=iterator->pointSample.dirn.cosComponent;
    rowInd += 1;
    F(rowInd,colInd)=iterator->pointSample.dirn.sinComponent;
    rowInd += 1;
    F(rowInd,colInd)=iterator->pointSample.curv.cosComponent;
    rowInd += 1;
    F(rowInd,colInd)=iterator->pointSample.curv.sinComponent;
    rowInd += 1;
    if(rowInd==NUM_POINT_BASED_FEATURES)
    {
        rowInd=0;
        colInd += 1;
    }
    iterator=iterator->nextClusterElement;
}
FILE *fp = fopen(PROGRAM_DATA_OUTPUT_PATH,"w");
if(fp!=NULL)
{
    int r,c;
    for(c=0; c<totFeatureVectors; c++)
    {
        for(r=0; r<NUM_POINT_BASED_FEATURES; r++)
        {
            fprintf(fp,"%lft",F(r,c));
        }
        fprintf(fp,"n");
    }
}
fclose(fp);
gmm_diag writerModel;
bool result = writerModel.learn(F, 20, maha_dist, random_subset, 100, 100, VARIANCE_FLOORING_FACTOR, true);
writerModel.dcovs.print("covariances:n");
writerModel.hefts.print("weights:n");
writerModel.means.print("means:n");
if(result==true)
{
    printf("nModel learnt");
}
else if(result==false)
{
    printf("nModel not learnt");
}
getchar();
return 0;}

技术细节:

该程序使用Netbeans 8.0.2 IDE在Ubuntu 14.04操作系统上运行。该项目是一个C/C++应用程序

任何帮助都将不胜感激!提前感谢~Sid

您需要先尝试最简单的情况,以缩小bug的位置。你的代码当然不简单,也不可复制(除了你,没有人拥有所有的功能(。

下面的简单代码是有效的,这表明bug在代码中的其他地方。

我怀疑您的代码正在某个地方覆盖内存,从而导致数据和/或代码损坏。该错误可能是一个不正确的指针,或者使用不正确的指示器。

#include <fstream>
#include <armadillo>
using namespace std;
using namespace arma;
int main(int argc, char** argv) {
  mat F(5,72580, fill::randu);
  gmm_diag model;
  bool result = model.learn(F, 20, maha_dist, random_subset, 100, 100, 0.001, true);
  model.hefts.print("hefts:");
  model.means.print("means:");
  model.dcovs.print("dcovs:");
  return 0;
  }

以上代码输出:

gmm_diag::learn(): generating initial means
gmm_diag::learn(): k-means: iteration:    1   delta: 0.343504
gmm_diag::learn(): k-means: iteration:    2   delta: 0.0528804
...
gmm_diag::learn(): k-means: iteration:  100   delta: 3.02294e-06
gmm_diag::learn(): generating initial covariances
gmm_diag::learn(): EM: iteration:    1   avg_log_p: -0.624274
gmm_diag::learn(): EM: iteration:    2   avg_log_p: -0.586567
...
gmm_diag::learn(): EM: iteration:  100   avg_log_p: -0.472182
hefts:
   0.0915   0.0335   0.0308   ...
means:
   0.4677   0.1230   0.8582   ...
   ...
dcovs:
   0.0474   0.0059   0.0080   ...
   ...

只有当seed_mode等于keep_existing并且均值矩阵为空时,才能在Armadillo代码中获取该分支。为什么不简单地使用IDE进行源代码级别的调试,看看它在什么时候会从你身上发生变化呢?