gpt4 book ai didi

c++ - 为什么 Armadillo 无法学习高斯混合模型并提示 'no existing means' 尽管随机子集播种?

转载 作者:行者123 更新时间:2023-11-28 02:20:54 24 4
gpt4 key购买 nike

问题总结:

我有一个 [5 x 72580] 矩阵。我正在尝试使用以 random_subset 作为初始播种模式的 gmm_diag.learn() 方法将高斯混合模型 (GMM) 拟合到此数据。为什么 Armadillo 会显示“gmm_diag::learn(): no existing means”而无法学习模型?


问题详情:

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

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

int totFeatureVectors = CountPointClusterElements(TRAINING_CLUSTER_LIST_INDEX);
printf("\n%d elements added to list\n",totFeatureVectors);

mat F = mat(NUM_POINT_BASED_FEATURES, totFeatureVectors, fill::zeros);

此处 TRAINING_CLUSTER_LIST_INDEX 和 NUM_POINT_BASED_FEATURES 是一对可配置的项目级常量;对于我的程序 NUM_POINT_BASED_FEATURES = 5 和 totFeatureVectors = 72580。因此变量 F 是一个 [5 x 72580] double 值的维矩阵。初始化后,我将链表中的特征值读取到 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,"%lf\t",F(r,c));
}
fprintf(fp,"\n");
}
}
fclose(fp);

到目前为止,还不错。但是在此之后,当我声明一个 gmm_diag 变量并尝试使用其 learn() 方法使 GMM 适合 F 时,程序显示警告“gmm_diag::learn(): no existing means”并退出,因此无法学习GMM(这里的 VARIANCE_FLOORING_FACTOR = 0.001)

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() 方法,据我所知,只有当初始播种模式为 keep_existing 时才会显示此错误(警告)消息。我提到的源文件位于/usr/include/armadillo_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 list\n",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,"%lf\t",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++应用程序

任何帮助将不胜感激!提前致谢~席德

最佳答案

您需要先尝试最简单的情况,以缩小错误的位置。你的代码当然不简单,而且它也不可重现(除了你没有人拥有所有的功能)。

以下简单代码有效,这表明该错误存在于您代码中的其他地方。

我怀疑您的代码正在某处覆盖内存,导致数据和/或代码损坏。该错误可能是指针不正确或指针使用不正确。

#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 ...
...

关于c++ - 为什么 Armadillo 无法学习高斯混合模型并提示 'no existing means' 尽管随机子集播种?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32524041/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com