在 Eclipse IDE 中在 C 上使用 LIBSVM 时出错
Posted
技术标签:
【中文标题】在 Eclipse IDE 中在 C 上使用 LIBSVM 时出错【英文标题】:Error using LIBSVM on C in Eclipse IDE 【发布时间】:2018-02-01 20:51:08 【问题描述】:我正在尝试使用 LIBSVM 在 Eclipse 上使用 C 执行二进制类机器学习(仅限 2 类)。在我开始使用我的训练数据之前,我尝试运行一个简单的 XOR 问题,看看我的 LIBSVM 是否可以预测正确的输出值(应该是 +1)。
但是,在我构建项目之后,我遇到了诸如 undefined reference to '_Heap_Begin'
、 undefined reference to '_Heap_Limit'
和 undefined reference to '__reset_hardware'
之类的错误。
我将svm.h
文件添加到“include”文件夹,将svm_train.c
和svm.cpp
文件添加到“src”文件夹,我已经在源文件中添加了#include 'svm.h'
,这是我从README
LIBSVM 中的文件。我按照 README 文件中的所有说明进行操作,其中指出 "You need to #include "svm.h" in your C/C++ source files and link your program with
svm.cpp'。"`
谁能解释我在这里做错了什么?谢谢!
svm.h:
#ifndef _LIBSVM_H
#define _LIBSVM_H
#define LIBSVM_VERSION 322
#ifdef __cplusplus
extern "C"
#endif
extern int libsvm_version;
struct svm_node
int index;
double value;
;
struct svm_problem
int l;
double *y;
struct svm_node **x;
;
enum C_SVC, NU_SVC, ONE_CLASS, EPSILON_SVR, NU_SVR ; /* svm_type */
enum LINEAR, POLY, RBF, SIGMOID, PRECOMPUTED ; /* kernel_type */
struct svm_parameter
int svm_type;
int kernel_type;
int degree; /* for poly */
double gamma; /* for poly/rbf/sigmoid */
double coef0; /* for poly/sigmoid */
/* these are for training only */
double cache_size; /* in MB */
double eps; /* stopping criteria */
double C; /* for C_SVC, EPSILON_SVR and NU_SVR */
int nr_weight; /* for C_SVC */
int *weight_label; /* for C_SVC */
double* weight; /* for C_SVC */
double nu; /* for NU_SVC, ONE_CLASS, and NU_SVR */
double p; /* for EPSILON_SVR */
int shrinking; /* use the shrinking heuristics */
int probability; /* do probability estimates */
;
//
// svm_model
//
struct svm_model
struct svm_parameter param; /* parameter */
int nr_class; /* number of classes, = 2 in regression/one class svm */
int l; /* total #SV */
struct svm_node **SV; /* SVs (SV[l]) */
double **sv_coef; /* coefficients for SVs in decision functions (sv_coef[k-1][l]) */
double *rho; /* constants in decision functions (rho[k*(k-1)/2]) */
double *probA; /* pariwise probability information */
double *probB;
int *sv_indices; /* sv_indices[0,...,nSV-1] are values in [1,...,num_traning_data] to indicate SVs in the training set */
/* for classification only */
int *label; /* label of each class (label[k]) */
int *nSV; /* number of SVs for each class (nSV[k]) */
/* nSV[0] + nSV[1] + ... + nSV[k-1] = l */
/* XXX */
int free_sv; /* 1 if svm_model is created by svm_load_model*/
/* 0 if svm_model is created by svm_train */
;
struct svm_model *svm_train(const struct svm_problem *prob, const struct svm_parameter *param);
void svm_cross_validation(const struct svm_problem *prob, const struct svm_parameter *param, int nr_fold, double *target);
int svm_save_model(const char *model_file_name, const struct svm_model *model);
struct svm_model *svm_load_model(const char *model_file_name);
int svm_get_svm_type(const struct svm_model *model);
int svm_get_nr_class(const struct svm_model *model);
void svm_get_labels(const struct svm_model *model, int *label);
void svm_get_sv_indices(const struct svm_model *model, int *sv_indices);
int svm_get_nr_sv(const struct svm_model *model);
double svm_get_svr_probability(const struct svm_model *model);
double svm_predict_values(const struct svm_model *model, const struct svm_node *x, double* dec_values);
double svm_predict(const struct svm_model *model, const struct svm_node *x);
double svm_predict_probability(const struct svm_model *model, const struct svm_node *x, double* prob_estimates);
void svm_free_model_content(struct svm_model *model_ptr);
void svm_free_and_destroy_model(struct svm_model **model_ptr_ptr);
void svm_destroy_param(struct svm_parameter *param);
const char *svm_check_parameter(const struct svm_problem *prob, const struct svm_parameter *param);
int svm_check_probability_model(const struct svm_model *model);
void svm_set_print_string_function(void (*print_func)(const char *));
#ifdef __cplusplus
#endif
#endif /* _LIBSVM_H */
svm_train.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "svm.h"
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
struct svm_parameter param; // set by parse_command_line
struct svm_problem prob; // set by read_problem
struct svm_model *model;
struct svm_node *x_space;
struct svm_node ** x;
struct svm_node *testnode;
void main(void)
param.svm_type = C_SVC;
param.kernel_type = RBF;
param.degree = 3;
param.gamma = 0.5;
param.coef0 = 0;
param.nu = 0.5;
param.cache_size = 100;
param.C = 1;
param.eps = 1e-3;
param.p = 0.1;
param.shrinking = 1;
param.probability = 0;
param.nr_weight = 0;
param.weight_label = NULL;
param.weight = NULL;
//Problem definition-------------------------------------------------------------
prob.l = 4;
//x values matrix of xor values (training data)
double matrix[prob.l][2];
matrix[0][0] = 1;
matrix[0][1] = 1;
matrix[1][0] = 1;
matrix[1][1] = 0;
matrix[2][0] = 0;
matrix[2][1] = 1;
matrix[3][0] = 0;
matrix[3][1] = 0;
// this part i do not understand
struct svm_node** x = (struct svm_node * *)malloc((prob.l)*sizeof(struct svm_node *));
//Trying to assign from matrix to svm_node training examples
for (int row = 0;row <prob.l; row++)
struct svm_node* x_space = Malloc(struct svm_node,3);
for (int col = 0;col < 2;col++)
x_space[col].index = col;
x_space[col].value = matrix[row][col];
x_space[2].index = -1; //Each row of properties should be terminated with a -1 according to the readme
x[row] = x_space;
prob.x = x;
//yvalues
prob.y = (double *)malloc((prob.l)*sizeof(double));
prob.y[0] = -1;
prob.y[1] = 1;
prob.y[2] = 1;
prob.y[3] = -1;
//Train model---------------------------------------------------------------------
struct svm_model *model = svm_train(&prob,¶m);
//Test model----------------------------------------------------------------------
struct svm_node* testnode = (struct svm_node *) malloc((3)*sizeof(struct svm_node));
testnode[0].index = 0;
testnode[0].value = 1;
testnode[1].index = 1;
testnode[1].value = 0;
testnode[2].index = -1;
double retval = svm_predict(model,testnode);
svm_destroy_param(¶m);
free(prob.y);
free(prob.x);
free(x_space);
【问题讨论】:
您需要链接库并包含必要的头文件。因为它无法找到它抱怨的参考。 @LethalProgrammer 如何将库链接到我的程序?我已经将它添加到我的源代码中,并且我的“svm_train.c”中的函数在“svm.cpp”文件中。你能解释一下吗? 通过这个问题,这将帮助您了解如何链接库,但在 Eclipse 中,您需要添加库路径并在属性中包含头文件位置。 ***.com/questions/6016815/… @LethalProgrammer 我读了你发给我的问题,但我仍然不明白我应该如何将我的 svm.cpp 文件与我的程序链接。而且我不明白您所说的“添加库路径”是什么意思。你能一步一步地给我解释一下吗?谢谢! 【参考方案1】:那些未定义的符号似乎与 SVM 无关,但与您的工具链有关。必须有一个您未链接的开发环境标准库(我们无法猜测,因为我们不知道您正在开发的平台)
【讨论】:
但是只有在我添加了 svm-train.c 和 svm.cpp 文件时才会出现这个错误。当我删除这两个文件时,不再有错误,并且我能够构建我的项目的其余部分(这与 LIBSVM 无关)。这些错误是否与堆内存有关,还是因为我没有正确链接 scm.cpp 文件? 你的项目中有所有的 svm 代码。如您所见,源代码中没有这些符号。也许文件的 cpp 扩展名会触发与其他 C 文件不同的编译器选项? 我明白了。但是我该如何解决这个问题呢?我不确定如何将我的 cpp 文件与我的 C 程序的其余部分链接。以上是关于在 Eclipse IDE 中在 C 上使用 LIBSVM 时出错的主要内容,如果未能解决你的问题,请参考以下文章
带有 Visual Studio 2013 编译器的 Eclipse CDT (C++ IDE)
在 Eclipse IDE 中从 Java 调用 c/c++ DLL