在 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.csvm.cpp 文件添加到“src”文件夹,我已经在源文件中添加了#include 'svm.h',这是我从README LIBSVM 中的文件。我按照 README 文件中的所有说明进行操作,其中指出 "You need to #include "svm.h" in your C/C++ source files and link your program withsvm.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,&param);


    //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(&param);
    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 时出错的主要内容,如果未能解决你的问题,请参考以下文章

Eclipse|Netbeans中C/C++的远程系统开发

带有 Visual Studio 2013 编译器的 Eclipse CDT (C++ IDE)

在 Eclipse IDE 中从 Java 调用 c/c++ DLL

如何在 Eclipse IDE 中运行一个简单的 C 程序

是否有与 C/C++ Eclipse IDE 一起使用的插件来提供代码建议和自动完成功能? [关闭]

JavaEE基础/Eclipse介绍