gpt4 book ai didi

c++ - 具有大特征向量 LibSVM 的段错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:16:19 26 4
gpt4 key购买 nike

我在 Android 应用程序 (NDK) 上运行 LibSVM。我已经在适用于所有特征向量大小的 Mac 应用程序上实现了类似的代码。当我给出一个包含 408 个特征的 vector 时,我在进行多类分类时没有任何问题。不过,任何 409 或更高的值(我最终将输入 16800)似乎都在这里失败:

0-16 23:28:41.084 30997-31028/? A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0xaf000000 in tid 31028 (GLThread 17147)
10-16 23:28:41.190 27393-27393/? I/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
10-16 23:28:41.191 27393-27393/? I/DEBUG: Build fingerprint: 'google/hammerhead/hammerhead:5.1.1/LMY48M/2167285:user/release-keys'
10-16 23:28:41.191 27393-27393/? I/DEBUG: Revision: '11'
10-16 23:28:41.191 27393-27393/? I/DEBUG: ABI: 'arm'
10-16 23:28:41.191 27393-27393/? I/DEBUG: pid: 30997, tid: 31028, name: GLThread 17147 >>> cc.openframeworks.androidEmptyExample <<<
10-16 23:28:41.191 27393-27393/? I/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xaf000000
10-16 23:28:41.202 27393-27393/? I/DEBUG: r0 aef3e000 r1 aef5ed10 r2 00000001 r3 af000000
10-16 23:28:41.202 27393-27393/? I/DEBUG: r4 aec29eb8 r5 00000001 r6 b4b2c608 r7 12d090c0
10-16 23:28:41.202 27393-27393/? I/DEBUG: r8 12d15660 r9 b4a39400 sl 00000000 fp af37d824
10-16 23:28:41.202 27393-27393/? I/DEBUG: ip b6e417dc sp af37d810 lr a301ff78 pc a301ff04 cpsr 000f0010
10-16 23:28:41.202 27393-27393/? I/DEBUG: #00 pc 00167f04 /data/app/cc.openframeworks.androidEmptyExample-1/lib/arm/libOFAndroidApp.so (Kernel::dot(svm_node const*, svm_node const*)+192)

这是我正在学习的相关代码:

ofxSvm mSvm;
void ofApp::update()
{ //Runs in loop
for(int i =0; i<8400; ++i)
{
HandDataVector.push_back((double)tempValue[i]);//tempValue is incoming data from a serial port (8400 doubles per packet)
}
//If I exclude this I get segfaults:
HandDataVector.resize(150);
if(learningToggleBoxTicked)
{
mSvm.addData(HandDataVector,label)
mSvm.train();
} else {
ofLogNotice("Classified As")<< mSvm.classify();
}
}

int ofApp::classify()
{
return mSvm.predict(HandDataVector);
}

这是我正在使用的 ofxSvm 库

    int ofxSvm::addData(int label, vector<double>& vec)
{
checkDimension(vec.size());

mData.insert(make_pair(label, vec));
mDimension = vec.size();


stringstream ss;
for (const auto v : vec) ss << v << " ";
ss << "EOS";
ofLogNotice(LOG_MODULE, "add data, label: " + ofToString(label) + " size: "+ofToString(vec.size())+" vec: " + ss.str());


return mData.size();
}
void ofxSvm::train()
{


svm_problem prob;

prob.l = mData.size();

prob.y = new double[prob.l];
{
data_type::iterator it = mData.begin();
int i = 0;
while (it != mData.end())
{
prob.y[i] = it->first;
++it; ++i;
}
}


if(mParam.gamma == 0)
{
mParam.gamma = 1.0 / mDimension;
}

int nodeLength = mDimension + 1;
svm_node* node = new svm_node[prob.l * nodeLength];
prob.x = new svm_node*[prob.l];
{
data_type::iterator it = mData.begin();
int i = 0;
while (it != mData.end())
{
prob.x[i] = node + i * nodeLength;
for (int j = 0; j < mDimension; ++j)
{
prob.x[i][j].index = j + 1;
prob.x[i][j].value = it->second[j];
}
prob.x[i][mDimension].index = -1; // delimiter
++it; ++i;
}
}

ofLogNotice(LOG_MODULE, "Start train...");

mModel = svm_train(&prob, &mParam);



ofLogNotice(LOG_MODULE, "Finished train!");

int x = mModel->nr_class;

ofLogNotice("TRAINED MODEL LABELS: " + ofToString(x));

delete[] node;
delete[] prob.x;
delete[] prob.y;
}

int ofxSvm::predict(vector<double>& testVec)
{
if (mModel == NULL)
{
ofLogNotice(LOG_MODULE, "null model, before do train or load model file");
return -5;
}
if (testVec.size() != mDimension)
{
ofLogNotice(LOG_MODULE, "different dimension");
return -6;
}


svm_node* node = new svm_node[mDimension + 1];
for (int i = 0; i < mDimension; ++i)
{
node[i].index = i + 1;
node[i].value = testVec[i];
ofLogNotice("node") << node[i].value <<"-" << i;

}
node[mDimension].index = -1;

int res = static_cast<int>(svm_predict(mModel, node));


stringstream ss;
for (const auto v : testVec) ss << v << " ";
ss << "EOS";
ofLogNotice(LOG_MODULE, "add data, label: size: "+ofToString(testVec.size())+" vec: " + ss.str());


ofLogNotice("ANSWER")<< res;


delete[] node;
return res;
}

这是发生错误的 LibSVM 库中的函数:

double Kernel::dot(const svm_node *px, const svm_node *py)
{
double sum = 0;
while(px->index != -1 && py->index != -1)
{
if(px->index == py->index)
{
sum += px->value * py->value;
++px;
++py;
}
else
{
if(px->index > py->index)
++py;
else
++px;
}
}
return sum;
}

编辑:这里是调用点函数的地方(svm_predict_values 中的 k_function)

double svm_predict_values(const svm_model *model, const svm_node *x, double* dec_values)
{
int i;
if(model->param.svm_type == ONE_CLASS ||
model->param.svm_type == EPSILON_SVR ||
model->param.svm_type == NU_SVR)
{
double *sv_coef = model->sv_coef[0];
double sum = 0;
for(i=0;i<model->l;i++)
sum += sv_coef[i] * Kernel::k_function(x,model->SV[i],model->param);
sum -= model->rho[0];
*dec_values = sum;

if(model->param.svm_type == ONE_CLASS)
return (sum>0)?1:-1;
else
return sum;
}
else
{
int nr_class = model->nr_class;
int l = model->l;

double *kvalue = Malloc(double,l);
for(i=0;i<l;i++)
kvalue[i] = Kernel::k_function(x,model->SV[i],model->param);

int *start = Malloc(int,nr_class);
start[0] = 0;
for(i=1;i<nr_class;i++)
start[i] = start[i-1]+model->nSV[i-1];

int *vote = Malloc(int,nr_class);
for(i=0;i<nr_class;i++)
vote[i] = 0;

int p=0;
for(i=0;i<nr_class;i++)
for(int j=i+1;j<nr_class;j++)
{
double sum = 0;
int si = start[i];
int sj = start[j];
int ci = model->nSV[i];
int cj = model->nSV[j];

int k;
double *coef1 = model->sv_coef[j-1];
double *coef2 = model->sv_coef[i];
for(k=0;k<ci;k++)
sum += coef1[si+k] * kvalue[si+k];
for(k=0;k<cj;k++)
sum += coef2[sj+k] * kvalue[sj+k];
sum -= model->rho[p];
dec_values[p] = sum;

if(dec_values[p] > 0)
++vote[i];
else
++vote[j];
p++;
}

int vote_max_idx = 0;
for(i=1;i<nr_class;i++)
if(vote[i] > vote[vote_max_idx])
vote_max_idx = i;

free(kvalue);
free(start);
free(vote);
return model->label[vote_max_idx];
}
}

double Kernel::k_function(const svm_node *x, const svm_node *y,
const svm_parameter& param)
{
switch(param.kernel_type)
{
case LINEAR:
return dot(x,y);
case POLY:
return powi(param.gamma*dot(x,y)+param.coef0,param.degree);
case RBF:
{
double sum = 0;
while(x->index != -1 && y->index !=-1)
{
if(x->index == y->index)
{
double d = x->value - y->value;
sum += d*d;
++x;
++y;
}
else
{
if(x->index > y->index)
{
sum += y->value * y->value;
++y;
}
else
{
sum += x->value * x->value;
++x;
}
}
}

while(x->index != -1)
{
sum += x->value * x->value;
++x;
}

while(y->index != -1)
{
sum += y->value * y->value;
++y;
}

return exp(-param.gamma*sum);
}
case SIGMOID:
return tanh(param.gamma*dot(x,y)+param.coef0);
case PRECOMPUTED: //x: test (validation), y: SV
return x[(int)(y->value)].value;
default:
return 0; // Unreachable
}
}

double kernel_linear(int i, int j) const
{
return dot(x[i],x[j]);
}

最佳答案

简介

我很难在 C++ 中找到有关 libSVM 的任何文档。所以我的回答主要基于您向我们展示的代码,没有真正的引用文档。

如果您可以发布指向您的文档的链接,那将非常有帮助:)

潜在问题

您展示了初始化 svm_node* 的代码在你的训练代码中:

prob.x[i][mDimension].index = -1;

您正在初始化一个 svm_problem实例。显然在你的 dot()您希望看到带有负索引的此类节点的函数,以标记 svm_node 的结尾列表。

但是当这样调用时你的代码失败了:

Kernel::k_function(x,model->SV[i],model->param);

在这里,model是一个 svm_model ,不是 svm_problem ,所以我猜这是在您训练模型后 libSVM 返回的。你确定svm_model遵循使用 node->index = -1 的约定标记节点列表的结尾?

所以也许标记节点不存在而你超出了范围。

为什么409条突然断了

您收到的信号是一个 SIGSEGV,它表示您试图访问未在您的进程中映射的页面中的一个字节。

越界访问项目时,通常不会收到 SIGSEGV,因为先前分配的项目位于内存页的中间,并且页中它后面有足够的字节。可能恰好第 409 项就在当前分配的页面之后,触发了信号。

关于c++ - 具有大特征向量 LibSVM 的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33182523/

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