read svm_model

The implementation reads the svm_model stored in a file into memory.

char* readline(FILE *input)
{
int len;

if(fgets(line,max_line_len,input) == NULL)//Read max_line_len characters from input to line, return pointer line
return NULL if successful;
//Search for the last time in the string pointed to by parameter str The position where the character c (an unsigned character) occurs.
//Return position, if not found return null pointer
while(strrchr(line,'\n') == NULL)
{
max_line_len *= 2;
line = (char *) realloc(line,max_line_len);
len = (int) strlen(line);
if(fgets(line+len,max_line_len-len,input) == NULL)
break;
}
return line;
}

#define FSCANF(_stream, _format, _var) do{ if (fscanf(_stream, _format, _var) != 1) return false; }while(0)
bool read_model_header(FILE *fp, struct svm_model* model)//format The read-in model
{
//svm_parameter& param = model->param;
//This is a reference in C++, and struct is omitted in C++, param is a real variable, and the reference is an alias
// parameters for training only won 't be assigned, but arrays are assigned as NULL for safety
// parameters used only for training will not be assigned, but arrays are assigned as NULL for safety
model->param.nr_weight = 0;
model->param .weight_label = NULL;
model->param.weight = NULL;

char cmd[81];
while(1)
{
FSCANF(fp,"%80s",cmd);//Read formatted input from fp, up to 80 character strings to cmd
//s this will read Takes consecutive characters until a space character is encountered
// If successful, the function returns the number of successful matches and assignments. EOF is returned if the end of file is reached or a read error occurs.

if(strcmp(cmd,"svm_type")==0)//比较cmd中的字符串与"svm_type"大小,应该是按ascii比较,如果相等返回零
{
FSCANF(fp,"%80s",cmd);
int i;
for(i=0;svm_type_table[i];i++)
{
if(strcmp(svm_type_table[i],cmd)==0)
{
model->param.svm_type=i;
break;
}
}
if(svm_type_table[i] == NULL)
{
fprintf(stderr,"unknown svm type.\n");
return false;
}
}
else if(strcmp(cmd,"kernel_type")==0)//有
{
FSCANF(fp,"%80s",cmd);
int i;
for(i=0;kernel_type_table[i];i++)
{
if(strcmp(kernel_type_table[i],cmd)==0)
{
model->param.kernel_type=i;
break;
}
}
if(kernel_type_table[i] == NULL)
{
fprintf(stderr,"unknown kernel function.\n");
return false;
}
}
else if(strcmp(cmd,"gamma")==0)//有
FSCANF(fp,"%lf",&model->param.gamma);

else if(strcmp(cmd,"nr_class")==0)//有
FSCANF(fp,"%d",&model->nr_class);
else if(strcmp(cmd,"total_sv")==0)//有
FSCANF(fp,"%d",&model->l);
else if(strcmp(cmd,"rho")==0)//有
{
int n = model->nr_class * (model->nr_class-1)/2;//nr_class为4,n为6
model->rho = Malloc(double,n);
int i;
for(i=0;i<n;i++)
FSCANF(fp,"%lf",&model->rho[i]);
}
else if(strcmp(cmd,"label")==0)//有
{
int i;
int n = model->nr_class;
model->label = Malloc(int,n);
for(i=0;i<n;i++)
FSCANF(fp,"%d",&model->label[i ]);
}

else if(strcmp(cmd,"nr_sv")==0)//with
{
int i;
int n = model->nr_class;
model->nSV = Malloc(int,n);
for(i= 0;i<n;i++)
FSCANF(fp,"%d",&model->nSV[i]);
}
else if(strcmp(cmd,"SV")==0)//with
{
while(1)
{
// Get the next character (an unsigned character) from the specified stream, and move the position identifier forward.
//This function returns the read character as unsigned char cast to int, or EOF if the end of file is reached or a read error occurs.
int c = getc(fp);
if(c==EOF || c=='\n') break;
}
break;



fprintf(stderr,"unknown text in model file: [%s]\n",cmd);
return false;
}
}

return true;

}

struct svm_model *svm_load_model(const char *model_file_name)
{
FILE *fp = fopen(model_file_name,"rb");//Open the file
if(fp==NULL) return NULL;//If the opening fails, return a null pointer

char *old_locale = setlocale(LC_ALL, NULL);//Set or read localization information.
if (old_locale) {
old_locale = strdup(old_locale);
}
setlocale(LC_ALL, "C");

// read parameters

struct svm_model *model = Malloc(struct svm_model,1);//宏定义分配内存
model->rho = NULL;//先初始化为空,
model->probA = NULL;
model->probB = NULL;
model->sv_indices = NULL;
model->label = NULL;
model->nSV = NULL;

// read header
if (!read_model_header(fp, model))
{
fprintf(stderr, "ERROR: fscanf failed to read model\n");
setlocale(LC_ALL, old_locale);
free(old_locale);
free(model->rho);
free(model->label);
free(model->nSV);
free(model);
return NULL;
}

// read sv_coef and SV

int elements = 0;
long pos = ftell(fp);//Returns the current file position for the given stream stream.

max_line_len = 1024;
line = Malloc(char,max_line_len);//Allocate memory,
char *p,*endptr,*idx,*val;

while(readline(fp)!=NULL)
{
//Get the first string
p = strtok(line,":");//Decompose the string str into a set of strings, delim is the delimiter.
while(1)
{
//Get another string
p = strtok(NULL,":");
if(p == NULL)
break;
++elements;
}
}
elements += model->l;

fseek(fp,pos,SEEK_SET);

int m = model->nr_class - 1;
int l = model->l;
model->sv_coef = Malloc(double *,m);
int i;
for(i=0;i<m;i++)
model->sv_coef[i] = Malloc(double,l);
model->SV = Malloc(struct svm_node*,l);
struct svm_node *x_space = NULL;
if(l>0) x_space = Malloc(struct svm_node,elements);

int j=0;
for(i=0;i<l;i++)
{
int k;
readline(fp);
model->SV[i] = &x_space[j];

p = strtok(line, " \t");
model->sv_coef[0][i] = strtod(p,&endptr);
for(k=1;k<m;k++)
{
p = strtok(NULL, " \t");
model->sv_coef[k][i] = strtod(p,&endptr);
}

while(1)
{
idx = strtok(NULL, ":");
val = strtok(NULL, " \t");

if(val == NULL)
break;
x_space[j].index = (int) strtol(idx,&endptr,10);
x_space[j].value = strtod(val,&endptr);

++j;
}
x_space[j++].index = -1;
}
free(line);

setlocale(LC_ALL, old_locale);
free(old_locale);

if (ferror(fp) != 0 || fclose(fp) != 0)
return NULL;

model->free_sv = 1; // XXX
return model;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325087382&siteId=291194637