Здравствуйте. Мне нужно использовать библиотеку liblinear в моей программе на C#. Я экспортировал её в dll. функции вроде вызываются, но программа падает от ошибок работы с памятью, а именно, скорее всего потому, что происходят ошибки при её освобождении или она вообще не освобождается. то что было | Код | struct feature_node { int index; double value; };
struct problem { int l, n; int *y; struct feature_node **x; double bias; /* < 0 if no bias term */ };
enum { L2R_LR, L2R_L2LOSS_SVC_DUAL, L2R_L2LOSS_SVC, L2R_L1LOSS_SVC_DUAL, MCSVM_CS, L1R_L2LOSS_SVC, L1R_LR, L2R_LR_DUAL }; /* solver_type */
struct parameter { int solver_type;
/* these are for training only */ double eps; /* stopping criteria */ double C; int nr_weight; int *weight_label; double* weight; };
struct model { struct parameter param; int nr_class; /* number of classes */ int nr_feature; double *w; int *label; /* label of each class */ double bias; };
__declspec(dllexport) struct model* train(const struct problem *prob, const struct parameter *param); __declspec(dllexport) void cross_validation(const struct problem *prob, const struct parameter *param, int nr_fold, int *target);
__declspec(dllexport) int predict_values(const struct model *model_, const struct feature_node *x, double* dec_values); __declspec(dllexport) int predict(const struct model *model_, const struct feature_node *x); __declspec(dllexport) int predict_probability(const struct model *model_, const struct feature_node *x, double* prob_estimates);
__declspec(dllexport) int save_model(const char *model_file_name, const struct model *model_); __declspec(dllexport) int save_model_and_clean(char *model_file_name, struct model *model_,parameter* param);
__declspec(dllexport) struct model *load_model(const char *model_file_name);
__declspec(dllexport) int get_nr_feature(const struct model *model_); __declspec(dllexport) int get_nr_class(const struct model *model_); __declspec(dllexport) void get_labels(const struct model *model_, int* label);
__declspec(dllexport) void free_model_content(struct model *model_ptr); __declspec(dllexport) void free_and_destroy_model(struct model **model_ptr_ptr); __declspec(dllexport) void destroy_param(struct parameter *param);
__declspec(dllexport) const char *check_parameter(const struct problem *prob, const struct parameter *param); __declspec(dllexport) int check_probability_model(const struct model *model); __declspec(dllexport) void set_print_string_function(void (*print_func) (const char*));
|
это как я объявил функции в C# программе | Код | unsafe struct LiBlinear {
public struct feature_node { public int index; public double value; };
public struct problem { public int l, n; public int* y; public feature_node** x; public double bias; /* < 0 if no bias term */ };
public struct parameter { public int solver_type;
/* these are for training only */ public double eps; /* stopping criteria */ public double C; public int nr_weight; public int* weight_label; public double* weight; };
public struct model { public parameter param; public int nr_class; /* number of classes */ public int nr_feature; public double* w; public int* label; /* label of each class */ public double bias; };
public enum ENUM_ { L2R_LR, L2R_L2LOSS_SVC_DUAL, L2R_L2LOSS_SVC, L2R_L1LOSS_SVC_DUAL, MCSVM_CS, L1R_L2LOSS_SVC, L1R_LR, L2R_LR_DUAL }; /* solver_type */
[DllImport("LIBlinearDLL.dll", EntryPoint = "train")] public static extern model* train( problem* prob, parameter* param); [DllImport("LIBlinearDLL.dll")] public static extern int predict_values(model* model_, feature_node* x, double* dec_values); [DllImport("LIBlinearDLL.dll")] public static extern int predict(model* model_, feature_node* x); [DllImport("LIBlinearDLL.dll")] public static extern int save_model(byte* model_file_name, model* model_); [DllImport("LIBlinearDLL.dll")] public static extern int save_model_and_clean(byte* model_file_name, model* model_, parameter* param); [DllImport("LIBlinearDLL.dll")] public static extern model* load_model(char* model_file_name); [DllImport("LIBlinearDLL.dll")] public static extern int get_nr_feature(model* model_); [DllImport("LIBlinearDLL.dll")] public static extern void free_and_destroy_model(model** model_ptr_ptr); [DllImport("LIBlinearDLL.dll")] public static extern void destroy_param(parameter* param); }
|
собственно использование | Код | const int NUM_FEATURES = 2000; LiBlinear.problem prob = new LiBlinear.problem(); prob.l = selection.Count; // number of instances prob.bias = -1; // bias feature prob.n = NUM_FEATURES; // number of features + one for bias if needed
prob.y = (int*)Marshal.AllocCoTaskMem(prob.l); // allocate space for labels prob.x = (LiBlinear.feature_node**)Marshal.AllocCoTaskMem(prob.l); // allocate space for features
for (int i = 0; i < prob.l; i++) { prob.x[i] = (LiBlinear.feature_node*)Marshal.AllocCoTaskMem(sizeof(LiBlinear.feature_node) * (NUM_FEATURES + 2)); prob.x[i][NUM_FEATURES].index = -1; // -1 marks the end of list for (int j = 0; j < NUM_FEATURES; j++) { prob.x[i][j].index = 1 + j; // 1-based feature number prob.x[i][j].value = selection[i][j]; } prob.y[i] = labels[i]; selection[i].Clear(); }
selection.Clear(); LiBlinear.parameter param = new LiBlinear.parameter(); param.solver_type = (int)LiBlinear.ENUM_.L2R_L2LOSS_SVC_DUAL; param.C = 1; param.eps = 1e-4; param.nr_weight = 0; param.weight_label = null; param.weight = null;
LiBlinear.model* model = LiBlinear.train(&prob, ¶m); byte[] save_model_file_name=new byte[]{bla bla bla}; byte* save_name = (byte*)Marshal.AllocCoTaskMem(save_model_file_name.Length); for (int i = 0; i < save_model_file_name.Length; i++) save_name[i] = save_model_file_name[i]; LiBlinear.save_model_and_clean(save_name, model, ¶m); Marshal.FreeCoTaskMem((IntPtr)save_name);
Marshal.FreeCoTaskMem((IntPtr)prob.y); for (int i = 0; i < prob.l; i++) Marshal.FreeCoTaskMem((IntPtr)prob.x[i]); Marshal.FreeCoTaskMem((IntPtr)prob.x);
|
если объем памяти используемой не очень велик, то иногда работает нормально, но умирает при повторных вызовах. буду признателен за конструктивные предложения. А нет, сейчас программа вылетает при вызове train(); короче, на сколько я понял, она вылетает от недостатка памяти, а если памяти и хватает, то вылетает при повторном исполнении этой части кода. Все, всем спасибо, кто хотел помочь. Проблему нашел. Оказывается я в функции Marshal.AllocCoTaskMem не умножал кол-во элементов на их размер=> не выделялось достаточно памяти. Это сообщение отредактировал(а) igsilya - 15.10.2011, 03:32
|