为什么犰狳没有学会高斯混合模型,尽管播种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?
问题摘要:
我有一个[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进行源代码级别的调试,看看它在什么时候会从你身上发生变化呢?
- "error: no matching function for call to"构造函数错误
- 调用专用模板时出错"no matching function for call to [...]"
- c++20[[no.unique_address]]中的新功能是什么
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- "no matching function for call to 'Vector::Vector'"错误
- Android NDK clang 编译器错误在 Windows 上显示'No such file or directory'
- 处理"no operator found"
- 我在 ifstream input_file(文件名)行中收到错误"no matching function to call";
- 如何解决"no Qt platform plugin could be initialized"问题?
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- 为什么当我在 std::string 中打开文件名的 fstream 时出现"no matching function"错误?
- 已解决 - C++ 的崇高文本中的"fatal error: opencv: no such file or directory"
- do while 循环中的 if 语句以 yes 或 no 结尾
- 从 TVector2 类派生复杂类:"No matching function for call to Complex::Complex()"
- 错误消息:使用"string* +="后"no match for 'operator+='"
- Eulers 项目问题 no 345 听不懂几行代码
- "No-Const Pointer to Const "调用功能
- 如何在 c++ 中将 s1 和 s2 与 no if 语句进行比较
- "No such file or directory" C++标头问题
- 在 Eclipse: "error: no match for 'operator='" 中获取错误消息