mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
initial commit; ml has been refactored; it compiles and the tests run well; some other modules, apps and samples do not compile; to be fixed
This commit is contained in:
+161
-476
@@ -44,257 +44,49 @@
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
// auxiliary functions
|
||||
// 1. nbayes
|
||||
void nbayes_check_data( CvMLData* _data )
|
||||
{
|
||||
if( _data->get_missing() )
|
||||
CV_Error( CV_StsBadArg, "missing values are not supported" );
|
||||
const CvMat* var_types = _data->get_var_types();
|
||||
bool is_classifier = var_types->data.ptr[var_types->cols-1] == CV_VAR_CATEGORICAL;
|
||||
|
||||
Mat _var_types = cvarrToMat(var_types);
|
||||
if( ( fabs( cvtest::norm( _var_types, Mat::zeros(_var_types.dims, _var_types.size, _var_types.type()), CV_L1 ) -
|
||||
(var_types->rows + var_types->cols - 2)*CV_VAR_ORDERED - CV_VAR_CATEGORICAL ) > FLT_EPSILON ) ||
|
||||
!is_classifier )
|
||||
CV_Error( CV_StsBadArg, "incorrect types of predictors or responses" );
|
||||
}
|
||||
bool nbayes_train( CvNormalBayesClassifier* nbayes, CvMLData* _data )
|
||||
{
|
||||
nbayes_check_data( _data );
|
||||
const CvMat* values = _data->get_values();
|
||||
const CvMat* responses = _data->get_responses();
|
||||
const CvMat* train_sidx = _data->get_train_sample_idx();
|
||||
const CvMat* var_idx = _data->get_var_idx();
|
||||
return nbayes->train( values, responses, var_idx, train_sidx );
|
||||
}
|
||||
float nbayes_calc_error( CvNormalBayesClassifier* nbayes, CvMLData* _data, int type, vector<float> *resp )
|
||||
{
|
||||
float err = 0;
|
||||
nbayes_check_data( _data );
|
||||
const CvMat* values = _data->get_values();
|
||||
const CvMat* response = _data->get_responses();
|
||||
const CvMat* sample_idx = (type == CV_TEST_ERROR) ? _data->get_test_sample_idx() : _data->get_train_sample_idx();
|
||||
int* sidx = sample_idx ? sample_idx->data.i : 0;
|
||||
int r_step = CV_IS_MAT_CONT(response->type) ?
|
||||
1 : response->step / CV_ELEM_SIZE(response->type);
|
||||
int sample_count = sample_idx ? sample_idx->cols : 0;
|
||||
sample_count = (type == CV_TRAIN_ERROR && sample_count == 0) ? values->rows : sample_count;
|
||||
float* pred_resp = 0;
|
||||
if( resp && (sample_count > 0) )
|
||||
{
|
||||
resp->resize( sample_count );
|
||||
pred_resp = &((*resp)[0]);
|
||||
}
|
||||
|
||||
for( int i = 0; i < sample_count; i++ )
|
||||
{
|
||||
CvMat sample;
|
||||
int si = sidx ? sidx[i] : i;
|
||||
cvGetRow( values, &sample, si );
|
||||
float r = (float)nbayes->predict( &sample, 0 );
|
||||
if( pred_resp )
|
||||
pred_resp[i] = r;
|
||||
int d = fabs((double)r - response->data.fl[si*r_step]) <= FLT_EPSILON ? 0 : 1;
|
||||
err += d;
|
||||
}
|
||||
err = sample_count ? err / (float)sample_count * 100 : -FLT_MAX;
|
||||
return err;
|
||||
}
|
||||
|
||||
// 2. knearest
|
||||
void knearest_check_data_and_get_predictors( CvMLData* _data, CvMat* _predictors )
|
||||
{
|
||||
const CvMat* values = _data->get_values();
|
||||
const CvMat* var_idx = _data->get_var_idx();
|
||||
if( var_idx->cols + var_idx->rows != values->cols )
|
||||
CV_Error( CV_StsBadArg, "var_idx is not supported" );
|
||||
if( _data->get_missing() )
|
||||
CV_Error( CV_StsBadArg, "missing values are not supported" );
|
||||
int resp_idx = _data->get_response_idx();
|
||||
if( resp_idx == 0)
|
||||
cvGetCols( values, _predictors, 1, values->cols );
|
||||
else if( resp_idx == values->cols - 1 )
|
||||
cvGetCols( values, _predictors, 0, values->cols - 1 );
|
||||
else
|
||||
CV_Error( CV_StsBadArg, "responses must be in the first or last column; other cases are not supported" );
|
||||
}
|
||||
bool knearest_train( CvKNearest* knearest, CvMLData* _data )
|
||||
{
|
||||
const CvMat* responses = _data->get_responses();
|
||||
const CvMat* train_sidx = _data->get_train_sample_idx();
|
||||
bool is_regression = _data->get_var_type( _data->get_response_idx() ) == CV_VAR_ORDERED;
|
||||
CvMat predictors;
|
||||
knearest_check_data_and_get_predictors( _data, &predictors );
|
||||
return knearest->train( &predictors, responses, train_sidx, is_regression );
|
||||
}
|
||||
float knearest_calc_error( CvKNearest* knearest, CvMLData* _data, int k, int type, vector<float> *resp )
|
||||
{
|
||||
float err = 0;
|
||||
const CvMat* response = _data->get_responses();
|
||||
const CvMat* sample_idx = (type == CV_TEST_ERROR) ? _data->get_test_sample_idx() : _data->get_train_sample_idx();
|
||||
int* sidx = sample_idx ? sample_idx->data.i : 0;
|
||||
int r_step = CV_IS_MAT_CONT(response->type) ?
|
||||
1 : response->step / CV_ELEM_SIZE(response->type);
|
||||
bool is_regression = _data->get_var_type( _data->get_response_idx() ) == CV_VAR_ORDERED;
|
||||
CvMat predictors;
|
||||
knearest_check_data_and_get_predictors( _data, &predictors );
|
||||
int sample_count = sample_idx ? sample_idx->cols : 0;
|
||||
sample_count = (type == CV_TRAIN_ERROR && sample_count == 0) ? predictors.rows : sample_count;
|
||||
float* pred_resp = 0;
|
||||
if( resp && (sample_count > 0) )
|
||||
{
|
||||
resp->resize( sample_count );
|
||||
pred_resp = &((*resp)[0]);
|
||||
}
|
||||
if ( !is_regression )
|
||||
{
|
||||
for( int i = 0; i < sample_count; i++ )
|
||||
{
|
||||
CvMat sample;
|
||||
int si = sidx ? sidx[i] : i;
|
||||
cvGetRow( &predictors, &sample, si );
|
||||
float r = knearest->find_nearest( &sample, k );
|
||||
if( pred_resp )
|
||||
pred_resp[i] = r;
|
||||
int d = fabs((double)r - response->data.fl[si*r_step]) <= FLT_EPSILON ? 0 : 1;
|
||||
err += d;
|
||||
}
|
||||
err = sample_count ? err / (float)sample_count * 100 : -FLT_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < sample_count; i++ )
|
||||
{
|
||||
CvMat sample;
|
||||
int si = sidx ? sidx[i] : i;
|
||||
cvGetRow( &predictors, &sample, si );
|
||||
float r = knearest->find_nearest( &sample, k );
|
||||
if( pred_resp )
|
||||
pred_resp[i] = r;
|
||||
float d = r - response->data.fl[si*r_step];
|
||||
err += d*d;
|
||||
}
|
||||
err = sample_count ? err / (float)sample_count : -FLT_MAX;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// 3. svm
|
||||
int str_to_svm_type(String& str)
|
||||
{
|
||||
if( !str.compare("C_SVC") )
|
||||
return CvSVM::C_SVC;
|
||||
return SVM::C_SVC;
|
||||
if( !str.compare("NU_SVC") )
|
||||
return CvSVM::NU_SVC;
|
||||
return SVM::NU_SVC;
|
||||
if( !str.compare("ONE_CLASS") )
|
||||
return CvSVM::ONE_CLASS;
|
||||
return SVM::ONE_CLASS;
|
||||
if( !str.compare("EPS_SVR") )
|
||||
return CvSVM::EPS_SVR;
|
||||
return SVM::EPS_SVR;
|
||||
if( !str.compare("NU_SVR") )
|
||||
return CvSVM::NU_SVR;
|
||||
return SVM::NU_SVR;
|
||||
CV_Error( CV_StsBadArg, "incorrect svm type string" );
|
||||
return -1;
|
||||
}
|
||||
int str_to_svm_kernel_type( String& str )
|
||||
{
|
||||
if( !str.compare("LINEAR") )
|
||||
return CvSVM::LINEAR;
|
||||
return SVM::LINEAR;
|
||||
if( !str.compare("POLY") )
|
||||
return CvSVM::POLY;
|
||||
return SVM::POLY;
|
||||
if( !str.compare("RBF") )
|
||||
return CvSVM::RBF;
|
||||
return SVM::RBF;
|
||||
if( !str.compare("SIGMOID") )
|
||||
return CvSVM::SIGMOID;
|
||||
return SVM::SIGMOID;
|
||||
CV_Error( CV_StsBadArg, "incorrect svm type string" );
|
||||
return -1;
|
||||
}
|
||||
void svm_check_data( CvMLData* _data )
|
||||
|
||||
Ptr<SVM> svm_train_auto( Ptr<TrainData> _data, SVM::Params _params,
|
||||
int k_fold, ParamGrid C_grid, ParamGrid gamma_grid,
|
||||
ParamGrid p_grid, ParamGrid nu_grid, ParamGrid coef_grid,
|
||||
ParamGrid degree_grid )
|
||||
{
|
||||
if( _data->get_missing() )
|
||||
CV_Error( CV_StsBadArg, "missing values are not supported" );
|
||||
const CvMat* var_types = _data->get_var_types();
|
||||
for( int i = 0; i < var_types->cols-1; i++ )
|
||||
if (var_types->data.ptr[i] == CV_VAR_CATEGORICAL)
|
||||
{
|
||||
char msg[50];
|
||||
sprintf( msg, "incorrect type of %d-predictor", i );
|
||||
CV_Error( CV_StsBadArg, msg );
|
||||
}
|
||||
}
|
||||
bool svm_train( CvSVM* svm, CvMLData* _data, CvSVMParams _params )
|
||||
{
|
||||
svm_check_data(_data);
|
||||
const CvMat* _train_data = _data->get_values();
|
||||
const CvMat* _responses = _data->get_responses();
|
||||
const CvMat* _var_idx = _data->get_var_idx();
|
||||
const CvMat* _sample_idx = _data->get_train_sample_idx();
|
||||
return svm->train( _train_data, _responses, _var_idx, _sample_idx, _params );
|
||||
}
|
||||
bool svm_train_auto( CvSVM* svm, CvMLData* _data, CvSVMParams _params,
|
||||
int k_fold, CvParamGrid C_grid, CvParamGrid gamma_grid,
|
||||
CvParamGrid p_grid, CvParamGrid nu_grid, CvParamGrid coef_grid,
|
||||
CvParamGrid degree_grid )
|
||||
{
|
||||
svm_check_data(_data);
|
||||
const CvMat* _train_data = _data->get_values();
|
||||
const CvMat* _responses = _data->get_responses();
|
||||
const CvMat* _var_idx = _data->get_var_idx();
|
||||
const CvMat* _sample_idx = _data->get_train_sample_idx();
|
||||
return svm->train_auto( _train_data, _responses, _var_idx,
|
||||
_sample_idx, _params, k_fold, C_grid, gamma_grid, p_grid, nu_grid, coef_grid, degree_grid );
|
||||
}
|
||||
float svm_calc_error( CvSVM* svm, CvMLData* _data, int type, vector<float> *resp )
|
||||
{
|
||||
svm_check_data(_data);
|
||||
float err = 0;
|
||||
const CvMat* values = _data->get_values();
|
||||
const CvMat* response = _data->get_responses();
|
||||
const CvMat* sample_idx = (type == CV_TEST_ERROR) ? _data->get_test_sample_idx() : _data->get_train_sample_idx();
|
||||
const CvMat* var_types = _data->get_var_types();
|
||||
int* sidx = sample_idx ? sample_idx->data.i : 0;
|
||||
int r_step = CV_IS_MAT_CONT(response->type) ?
|
||||
1 : response->step / CV_ELEM_SIZE(response->type);
|
||||
bool is_classifier = var_types->data.ptr[var_types->cols-1] == CV_VAR_CATEGORICAL;
|
||||
int sample_count = sample_idx ? sample_idx->cols : 0;
|
||||
sample_count = (type == CV_TRAIN_ERROR && sample_count == 0) ? values->rows : sample_count;
|
||||
float* pred_resp = 0;
|
||||
if( resp && (sample_count > 0) )
|
||||
{
|
||||
resp->resize( sample_count );
|
||||
pred_resp = &((*resp)[0]);
|
||||
}
|
||||
if ( is_classifier )
|
||||
{
|
||||
for( int i = 0; i < sample_count; i++ )
|
||||
{
|
||||
CvMat sample;
|
||||
int si = sidx ? sidx[i] : i;
|
||||
cvGetRow( values, &sample, si );
|
||||
float r = svm->predict( &sample );
|
||||
if( pred_resp )
|
||||
pred_resp[i] = r;
|
||||
int d = fabs((double)r - response->data.fl[si*r_step]) <= FLT_EPSILON ? 0 : 1;
|
||||
err += d;
|
||||
}
|
||||
err = sample_count ? err / (float)sample_count * 100 : -FLT_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0; i < sample_count; i++ )
|
||||
{
|
||||
CvMat sample;
|
||||
int si = sidx ? sidx[i] : i;
|
||||
cvGetRow( values, &sample, si );
|
||||
float r = svm->predict( &sample );
|
||||
if( pred_resp )
|
||||
pred_resp[i] = r;
|
||||
float d = r - response->data.fl[si*r_step];
|
||||
err += d*d;
|
||||
}
|
||||
err = sample_count ? err / (float)sample_count : -FLT_MAX;
|
||||
}
|
||||
return err;
|
||||
Mat _train_data = _data->getSamples();
|
||||
Mat _responses = _data->getResponses();
|
||||
Mat _var_idx = _data->getVarIdx();
|
||||
Mat _sample_idx = _data->getTrainSampleIdx();
|
||||
|
||||
Ptr<SVM> svm = SVM::create(_params);
|
||||
if( svm->trainAuto( _data, k_fold, C_grid, gamma_grid, p_grid, nu_grid, coef_grid, degree_grid ) )
|
||||
return svm;
|
||||
return Ptr<SVM>();
|
||||
}
|
||||
|
||||
// 4. em
|
||||
@@ -302,79 +94,66 @@ float svm_calc_error( CvSVM* svm, CvMLData* _data, int type, vector<float> *resp
|
||||
int str_to_ann_train_method( String& str )
|
||||
{
|
||||
if( !str.compare("BACKPROP") )
|
||||
return CvANN_MLP_TrainParams::BACKPROP;
|
||||
return ANN_MLP::Params::BACKPROP;
|
||||
if( !str.compare("RPROP") )
|
||||
return CvANN_MLP_TrainParams::RPROP;
|
||||
return ANN_MLP::Params::RPROP;
|
||||
CV_Error( CV_StsBadArg, "incorrect ann train method string" );
|
||||
return -1;
|
||||
}
|
||||
void ann_check_data_and_get_predictors( CvMLData* _data, CvMat* _inputs )
|
||||
|
||||
void ann_check_data( Ptr<TrainData> _data )
|
||||
{
|
||||
const CvMat* values = _data->get_values();
|
||||
const CvMat* var_idx = _data->get_var_idx();
|
||||
if( var_idx->cols + var_idx->rows != values->cols )
|
||||
Mat values = _data->getSamples();
|
||||
Mat var_idx = _data->getVarIdx();
|
||||
int nvars = (int)var_idx.total();
|
||||
if( nvars != 0 && nvars != values.cols )
|
||||
CV_Error( CV_StsBadArg, "var_idx is not supported" );
|
||||
if( _data->get_missing() )
|
||||
if( !_data->getMissing().empty() )
|
||||
CV_Error( CV_StsBadArg, "missing values are not supported" );
|
||||
int resp_idx = _data->get_response_idx();
|
||||
if( resp_idx == 0)
|
||||
cvGetCols( values, _inputs, 1, values->cols );
|
||||
else if( resp_idx == values->cols - 1 )
|
||||
cvGetCols( values, _inputs, 0, values->cols - 1 );
|
||||
else
|
||||
CV_Error( CV_StsBadArg, "outputs must be in the first or last column; other cases are not supported" );
|
||||
}
|
||||
void ann_get_new_responses( CvMLData* _data, Mat& new_responses, map<int, int>& cls_map )
|
||||
|
||||
// unroll the categorical responses to binary vectors
|
||||
Mat ann_get_new_responses( Ptr<TrainData> _data, map<int, int>& cls_map )
|
||||
{
|
||||
const CvMat* train_sidx = _data->get_train_sample_idx();
|
||||
int* train_sidx_ptr = train_sidx->data.i;
|
||||
const CvMat* responses = _data->get_responses();
|
||||
float* responses_ptr = responses->data.fl;
|
||||
int r_step = CV_IS_MAT_CONT(responses->type) ?
|
||||
1 : responses->step / CV_ELEM_SIZE(responses->type);
|
||||
Mat train_sidx = _data->getTrainSampleIdx();
|
||||
int* train_sidx_ptr = train_sidx.ptr<int>();
|
||||
Mat responses = _data->getResponses();
|
||||
int cls_count = 0;
|
||||
// construct cls_map
|
||||
cls_map.clear();
|
||||
for( int si = 0; si < train_sidx->cols; si++ )
|
||||
int nresponses = (int)responses.total();
|
||||
int si, n = !train_sidx.empty() ? (int)train_sidx.total() : nresponses;
|
||||
|
||||
for( si = 0; si < n; si++ )
|
||||
{
|
||||
int sidx = train_sidx_ptr[si];
|
||||
int r = cvRound(responses_ptr[sidx*r_step]);
|
||||
CV_DbgAssert( fabs(responses_ptr[sidx*r_step]-r) < FLT_EPSILON );
|
||||
int cls_map_size = (int)cls_map.size();
|
||||
cls_map[r];
|
||||
if ( (int)cls_map.size() > cls_map_size )
|
||||
int sidx = train_sidx_ptr ? train_sidx_ptr[si] : si;
|
||||
int r = cvRound(responses.at<float>(sidx));
|
||||
CV_DbgAssert( fabs(responses.at<float>(sidx) - r) < FLT_EPSILON );
|
||||
map<int,int>::iterator it = cls_map.find(r);
|
||||
if( it == cls_map.end() )
|
||||
cls_map[r] = cls_count++;
|
||||
}
|
||||
new_responses.create( responses->rows, cls_count, CV_32F );
|
||||
new_responses.setTo( 0 );
|
||||
for( int si = 0; si < train_sidx->cols; si++ )
|
||||
Mat new_responses = Mat::zeros( nresponses, cls_count, CV_32F );
|
||||
for( si = 0; si < n; si++ )
|
||||
{
|
||||
int sidx = train_sidx_ptr[si];
|
||||
int r = cvRound(responses_ptr[sidx*r_step]);
|
||||
int sidx = train_sidx_ptr ? train_sidx_ptr[si] : si;
|
||||
int r = cvRound(responses.at<float>(sidx));
|
||||
int cidx = cls_map[r];
|
||||
new_responses.ptr<float>(sidx)[cidx] = 1;
|
||||
new_responses.at<float>(sidx, cidx) = 1.f;
|
||||
}
|
||||
return new_responses;
|
||||
}
|
||||
int ann_train( CvANN_MLP* ann, CvMLData* _data, Mat& new_responses, CvANN_MLP_TrainParams _params, int flags = 0 )
|
||||
{
|
||||
const CvMat* train_sidx = _data->get_train_sample_idx();
|
||||
CvMat predictors;
|
||||
ann_check_data_and_get_predictors( _data, &predictors );
|
||||
CvMat _new_responses = CvMat( new_responses );
|
||||
return ann->train( &predictors, &_new_responses, 0, train_sidx, _params, flags );
|
||||
}
|
||||
float ann_calc_error( CvANN_MLP* ann, CvMLData* _data, map<int, int>& cls_map, int type , vector<float> *resp_labels )
|
||||
|
||||
float ann_calc_error( Ptr<StatModel> ann, Ptr<TrainData> _data, map<int, int>& cls_map, int type, vector<float> *resp_labels )
|
||||
{
|
||||
float err = 0;
|
||||
const CvMat* responses = _data->get_responses();
|
||||
const CvMat* sample_idx = (type == CV_TEST_ERROR) ? _data->get_test_sample_idx() : _data->get_train_sample_idx();
|
||||
int* sidx = sample_idx ? sample_idx->data.i : 0;
|
||||
int r_step = CV_IS_MAT_CONT(responses->type) ?
|
||||
1 : responses->step / CV_ELEM_SIZE(responses->type);
|
||||
CvMat predictors;
|
||||
ann_check_data_and_get_predictors( _data, &predictors );
|
||||
int sample_count = sample_idx ? sample_idx->cols : 0;
|
||||
sample_count = (type == CV_TRAIN_ERROR && sample_count == 0) ? predictors.rows : sample_count;
|
||||
Mat samples = _data->getSamples();
|
||||
Mat responses = _data->getResponses();
|
||||
Mat sample_idx = (type == CV_TEST_ERROR) ? _data->getTestSampleIdx() : _data->getTrainSampleIdx();
|
||||
int* sidx = !sample_idx.empty() ? sample_idx.ptr<int>() : 0;
|
||||
ann_check_data( _data );
|
||||
int sample_count = (int)sample_idx.total();
|
||||
sample_count = (type == CV_TRAIN_ERROR && sample_count == 0) ? samples.rows : sample_count;
|
||||
float* pred_resp = 0;
|
||||
vector<float> innresp;
|
||||
if( sample_count > 0 )
|
||||
@@ -392,17 +171,16 @@ float ann_calc_error( CvANN_MLP* ann, CvMLData* _data, map<int, int>& cls_map, i
|
||||
}
|
||||
int cls_count = (int)cls_map.size();
|
||||
Mat output( 1, cls_count, CV_32FC1 );
|
||||
CvMat _output = CvMat(output);
|
||||
|
||||
for( int i = 0; i < sample_count; i++ )
|
||||
{
|
||||
CvMat sample;
|
||||
int si = sidx ? sidx[i] : i;
|
||||
cvGetRow( &predictors, &sample, si );
|
||||
ann->predict( &sample, &_output );
|
||||
CvPoint best_cls;
|
||||
cvMinMaxLoc( &_output, 0, 0, 0, &best_cls, 0 );
|
||||
int r = cvRound(responses->data.fl[si*r_step]);
|
||||
CV_DbgAssert( fabs(responses->data.fl[si*r_step]-r) < FLT_EPSILON );
|
||||
Mat sample = samples.row(si);
|
||||
ann->predict( sample, output );
|
||||
Point best_cls;
|
||||
minMaxLoc(output, 0, 0, 0, &best_cls, 0);
|
||||
int r = cvRound(responses.at<float>(si));
|
||||
CV_DbgAssert( fabs(responses.at<float>(si) - r) < FLT_EPSILON );
|
||||
r = cls_map[r];
|
||||
int d = best_cls.x == r ? 0 : 1;
|
||||
err += d;
|
||||
@@ -417,13 +195,13 @@ float ann_calc_error( CvANN_MLP* ann, CvMLData* _data, map<int, int>& cls_map, i
|
||||
int str_to_boost_type( String& str )
|
||||
{
|
||||
if ( !str.compare("DISCRETE") )
|
||||
return CvBoost::DISCRETE;
|
||||
return Boost::DISCRETE;
|
||||
if ( !str.compare("REAL") )
|
||||
return CvBoost::REAL;
|
||||
return Boost::REAL;
|
||||
if ( !str.compare("LOGIT") )
|
||||
return CvBoost::LOGIT;
|
||||
return Boost::LOGIT;
|
||||
if ( !str.compare("GENTLE") )
|
||||
return CvBoost::GENTLE;
|
||||
return Boost::GENTLE;
|
||||
CV_Error( CV_StsBadArg, "incorrect boost type string" );
|
||||
return -1;
|
||||
}
|
||||
@@ -446,76 +224,37 @@ CV_MLBaseTest::CV_MLBaseTest(const char* _modelName)
|
||||
RNG& rng = theRNG();
|
||||
|
||||
initSeed = rng.state;
|
||||
|
||||
rng.state = seeds[rng(seedCount)];
|
||||
|
||||
modelName = _modelName;
|
||||
nbayes = 0;
|
||||
knearest = 0;
|
||||
svm = 0;
|
||||
ann = 0;
|
||||
dtree = 0;
|
||||
boost = 0;
|
||||
rtrees = 0;
|
||||
ertrees = 0;
|
||||
if( !modelName.compare(CV_NBAYES) )
|
||||
nbayes = new CvNormalBayesClassifier;
|
||||
else if( !modelName.compare(CV_KNEAREST) )
|
||||
knearest = new CvKNearest;
|
||||
else if( !modelName.compare(CV_SVM) )
|
||||
svm = new CvSVM;
|
||||
else if( !modelName.compare(CV_ANN) )
|
||||
ann = new CvANN_MLP;
|
||||
else if( !modelName.compare(CV_DTREE) )
|
||||
dtree = new CvDTree;
|
||||
else if( !modelName.compare(CV_BOOST) )
|
||||
boost = new CvBoost;
|
||||
else if( !modelName.compare(CV_RTREES) )
|
||||
rtrees = new CvRTrees;
|
||||
else if( !modelName.compare(CV_ERTREES) )
|
||||
ertrees = new CvERTrees;
|
||||
}
|
||||
|
||||
CV_MLBaseTest::~CV_MLBaseTest()
|
||||
{
|
||||
if( validationFS.isOpened() )
|
||||
validationFS.release();
|
||||
if( nbayes )
|
||||
delete nbayes;
|
||||
if( knearest )
|
||||
delete knearest;
|
||||
if( svm )
|
||||
delete svm;
|
||||
if( ann )
|
||||
delete ann;
|
||||
if( dtree )
|
||||
delete dtree;
|
||||
if( boost )
|
||||
delete boost;
|
||||
if( rtrees )
|
||||
delete rtrees;
|
||||
if( ertrees )
|
||||
delete ertrees;
|
||||
theRNG().state = initSeed;
|
||||
}
|
||||
|
||||
int CV_MLBaseTest::read_params( CvFileStorage* _fs )
|
||||
int CV_MLBaseTest::read_params( CvFileStorage* __fs )
|
||||
{
|
||||
if( !_fs )
|
||||
FileStorage _fs(__fs, false);
|
||||
if( !_fs.isOpened() )
|
||||
test_case_count = -1;
|
||||
else
|
||||
{
|
||||
CvFileNode* fn = cvGetRootFileNode( _fs, 0 );
|
||||
fn = (CvFileNode*)cvGetSeqElem( fn->data.seq, 0 );
|
||||
fn = cvGetFileNodeByName( _fs, fn, "run_params" );
|
||||
CvSeq* dataSetNamesSeq = cvGetFileNodeByName( _fs, fn, modelName.c_str() )->data.seq;
|
||||
test_case_count = dataSetNamesSeq ? dataSetNamesSeq->total : -1;
|
||||
FileNode fn = _fs.getFirstTopLevelNode()["run_params"][modelName];
|
||||
test_case_count = (int)fn.size();
|
||||
if( test_case_count <= 0 )
|
||||
test_case_count = -1;
|
||||
if( test_case_count > 0 )
|
||||
{
|
||||
dataSetNames.resize( test_case_count );
|
||||
vector<string>::iterator it = dataSetNames.begin();
|
||||
for( int i = 0; i < test_case_count; i++, it++ )
|
||||
*it = ((CvFileNode*)cvGetSeqElem( dataSetNamesSeq, i ))->data.str.ptr;
|
||||
FileNodeIterator it = fn.begin();
|
||||
for( int i = 0; i < test_case_count; i++, ++it )
|
||||
{
|
||||
dataSetNames[i] = (string)*it;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cvtest::TS::OK;;
|
||||
@@ -547,8 +286,6 @@ void CV_MLBaseTest::run( int )
|
||||
|
||||
int CV_MLBaseTest::prepare_test_case( int test_case_idx )
|
||||
{
|
||||
int trainSampleCount, respIdx;
|
||||
String varTypes;
|
||||
clear();
|
||||
|
||||
string dataPath = ts->get_data_path();
|
||||
@@ -560,30 +297,27 @@ int CV_MLBaseTest::prepare_test_case( int test_case_idx )
|
||||
|
||||
string dataName = dataSetNames[test_case_idx],
|
||||
filename = dataPath + dataName + ".data";
|
||||
if ( data.read_csv( filename.c_str() ) != 0)
|
||||
{
|
||||
char msg[100];
|
||||
sprintf( msg, "file %s can not be read", filename.c_str() );
|
||||
ts->printf( cvtest::TS::LOG, msg );
|
||||
return cvtest::TS::FAIL_INVALID_TEST_DATA;
|
||||
}
|
||||
|
||||
FileNode dataParamsNode = validationFS.getFirstTopLevelNode()["validation"][modelName][dataName]["data_params"];
|
||||
CV_DbgAssert( !dataParamsNode.empty() );
|
||||
|
||||
CV_DbgAssert( !dataParamsNode["LS"].empty() );
|
||||
dataParamsNode["LS"] >> trainSampleCount;
|
||||
CvTrainTestSplit spl( trainSampleCount );
|
||||
data.set_train_test_split( &spl );
|
||||
int trainSampleCount = (int)dataParamsNode["LS"];
|
||||
|
||||
CV_DbgAssert( !dataParamsNode["resp_idx"].empty() );
|
||||
dataParamsNode["resp_idx"] >> respIdx;
|
||||
data.set_response_idx( respIdx );
|
||||
int respIdx = (int)dataParamsNode["resp_idx"];
|
||||
|
||||
CV_DbgAssert( !dataParamsNode["types"].empty() );
|
||||
dataParamsNode["types"] >> varTypes;
|
||||
data.set_var_types( varTypes.c_str() );
|
||||
String varTypes = (String)dataParamsNode["types"];
|
||||
|
||||
data = TrainData::loadFromCSV(filename, 0, respIdx, respIdx+1, varTypes);
|
||||
if( data.empty() )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "file %s can not be read\n", filename.c_str() );
|
||||
return cvtest::TS::FAIL_INVALID_TEST_DATA;
|
||||
}
|
||||
|
||||
data->setTrainTestSplit(trainSampleCount);
|
||||
return cvtest::TS::OK;
|
||||
}
|
||||
|
||||
@@ -598,114 +332,97 @@ int CV_MLBaseTest::train( int testCaseIdx )
|
||||
FileNode modelParamsNode =
|
||||
validationFS.getFirstTopLevelNode()["validation"][modelName][dataSetNames[testCaseIdx]]["model_params"];
|
||||
|
||||
if( !modelName.compare(CV_NBAYES) )
|
||||
is_trained = nbayes_train( nbayes, &data );
|
||||
else if( !modelName.compare(CV_KNEAREST) )
|
||||
if( modelName == CV_NBAYES )
|
||||
model = NormalBayesClassifier::create();
|
||||
else if( modelName == CV_KNEAREST )
|
||||
{
|
||||
assert( 0 );
|
||||
//is_trained = knearest->train( &data );
|
||||
model = KNearest::create();
|
||||
}
|
||||
else if( !modelName.compare(CV_SVM) )
|
||||
else if( modelName == CV_SVM )
|
||||
{
|
||||
String svm_type_str, kernel_type_str;
|
||||
modelParamsNode["svm_type"] >> svm_type_str;
|
||||
modelParamsNode["kernel_type"] >> kernel_type_str;
|
||||
CvSVMParams params;
|
||||
params.svm_type = str_to_svm_type( svm_type_str );
|
||||
params.kernel_type = str_to_svm_kernel_type( kernel_type_str );
|
||||
SVM::Params params;
|
||||
params.svmType = str_to_svm_type( svm_type_str );
|
||||
params.kernelType = str_to_svm_kernel_type( kernel_type_str );
|
||||
modelParamsNode["degree"] >> params.degree;
|
||||
modelParamsNode["gamma"] >> params.gamma;
|
||||
modelParamsNode["coef0"] >> params.coef0;
|
||||
modelParamsNode["C"] >> params.C;
|
||||
modelParamsNode["nu"] >> params.nu;
|
||||
modelParamsNode["p"] >> params.p;
|
||||
is_trained = svm_train( svm, &data, params );
|
||||
model = SVM::create(params);
|
||||
}
|
||||
else if( !modelName.compare(CV_EM) )
|
||||
else if( modelName == CV_EM )
|
||||
{
|
||||
assert( 0 );
|
||||
}
|
||||
else if( !modelName.compare(CV_ANN) )
|
||||
else if( modelName == CV_ANN )
|
||||
{
|
||||
String train_method_str;
|
||||
double param1, param2;
|
||||
modelParamsNode["train_method"] >> train_method_str;
|
||||
modelParamsNode["param1"] >> param1;
|
||||
modelParamsNode["param2"] >> param2;
|
||||
Mat new_responses;
|
||||
ann_get_new_responses( &data, new_responses, cls_map );
|
||||
int layer_sz[] = { data.get_values()->cols - 1, 100, 100, (int)cls_map.size() };
|
||||
CvMat layer_sizes =
|
||||
cvMat( 1, (int)(sizeof(layer_sz)/sizeof(layer_sz[0])), CV_32S, layer_sz );
|
||||
ann->create( &layer_sizes );
|
||||
is_trained = ann_train( ann, &data, new_responses, CvANN_MLP_TrainParams(cvTermCriteria(CV_TERMCRIT_ITER,300,0.01),
|
||||
str_to_ann_train_method(train_method_str), param1, param2) ) >= 0;
|
||||
Mat new_responses = ann_get_new_responses( data, cls_map );
|
||||
// binarize the responses
|
||||
data = TrainData::create(data->getSamples(), data->getLayout(), new_responses,
|
||||
data->getVarIdx(), data->getTrainSampleIdx());
|
||||
int layer_sz[] = { data->getNAllVars(), 100, 100, (int)cls_map.size() };
|
||||
Mat layer_sizes( 1, (int)(sizeof(layer_sz)/sizeof(layer_sz[0])), CV_32S, layer_sz );
|
||||
model = ANN_MLP::create(layer_sizes, ANN_MLP::Params(TermCriteria(TermCriteria::COUNT,300,0.01),
|
||||
str_to_ann_train_method(train_method_str), param1, param2));
|
||||
}
|
||||
else if( !modelName.compare(CV_DTREE) )
|
||||
else if( modelName == CV_DTREE )
|
||||
{
|
||||
int MAX_DEPTH, MIN_SAMPLE_COUNT, MAX_CATEGORIES, CV_FOLDS;
|
||||
float REG_ACCURACY = 0;
|
||||
bool USE_SURROGATE, IS_PRUNED;
|
||||
bool USE_SURROGATE = false, IS_PRUNED;
|
||||
modelParamsNode["max_depth"] >> MAX_DEPTH;
|
||||
modelParamsNode["min_sample_count"] >> MIN_SAMPLE_COUNT;
|
||||
modelParamsNode["use_surrogate"] >> USE_SURROGATE;
|
||||
//modelParamsNode["use_surrogate"] >> USE_SURROGATE;
|
||||
modelParamsNode["max_categories"] >> MAX_CATEGORIES;
|
||||
modelParamsNode["cv_folds"] >> CV_FOLDS;
|
||||
modelParamsNode["is_pruned"] >> IS_PRUNED;
|
||||
is_trained = dtree->train( &data,
|
||||
CvDTreeParams(MAX_DEPTH, MIN_SAMPLE_COUNT, REG_ACCURACY, USE_SURROGATE,
|
||||
MAX_CATEGORIES, CV_FOLDS, false, IS_PRUNED, 0 )) != 0;
|
||||
model = DTrees::create(DTrees::Params(MAX_DEPTH, MIN_SAMPLE_COUNT, REG_ACCURACY, USE_SURROGATE,
|
||||
MAX_CATEGORIES, CV_FOLDS, false, IS_PRUNED, Mat() ));
|
||||
}
|
||||
else if( !modelName.compare(CV_BOOST) )
|
||||
else if( modelName == CV_BOOST )
|
||||
{
|
||||
int BOOST_TYPE, WEAK_COUNT, MAX_DEPTH;
|
||||
float WEIGHT_TRIM_RATE;
|
||||
bool USE_SURROGATE;
|
||||
bool USE_SURROGATE = false;
|
||||
String typeStr;
|
||||
modelParamsNode["type"] >> typeStr;
|
||||
BOOST_TYPE = str_to_boost_type( typeStr );
|
||||
modelParamsNode["weak_count"] >> WEAK_COUNT;
|
||||
modelParamsNode["weight_trim_rate"] >> WEIGHT_TRIM_RATE;
|
||||
modelParamsNode["max_depth"] >> MAX_DEPTH;
|
||||
modelParamsNode["use_surrogate"] >> USE_SURROGATE;
|
||||
is_trained = boost->train( &data,
|
||||
CvBoostParams(BOOST_TYPE, WEAK_COUNT, WEIGHT_TRIM_RATE, MAX_DEPTH, USE_SURROGATE, 0) ) != 0;
|
||||
//modelParamsNode["use_surrogate"] >> USE_SURROGATE;
|
||||
model = Boost::create( Boost::Params(BOOST_TYPE, WEAK_COUNT, WEIGHT_TRIM_RATE, MAX_DEPTH, USE_SURROGATE, Mat()) );
|
||||
}
|
||||
else if( !modelName.compare(CV_RTREES) )
|
||||
else if( modelName == CV_RTREES )
|
||||
{
|
||||
int MAX_DEPTH, MIN_SAMPLE_COUNT, MAX_CATEGORIES, CV_FOLDS, NACTIVE_VARS, MAX_TREES_NUM;
|
||||
float REG_ACCURACY = 0, OOB_EPS = 0.0;
|
||||
bool USE_SURROGATE, IS_PRUNED;
|
||||
bool USE_SURROGATE = false, IS_PRUNED;
|
||||
modelParamsNode["max_depth"] >> MAX_DEPTH;
|
||||
modelParamsNode["min_sample_count"] >> MIN_SAMPLE_COUNT;
|
||||
modelParamsNode["use_surrogate"] >> USE_SURROGATE;
|
||||
//modelParamsNode["use_surrogate"] >> USE_SURROGATE;
|
||||
modelParamsNode["max_categories"] >> MAX_CATEGORIES;
|
||||
modelParamsNode["cv_folds"] >> CV_FOLDS;
|
||||
modelParamsNode["is_pruned"] >> IS_PRUNED;
|
||||
modelParamsNode["nactive_vars"] >> NACTIVE_VARS;
|
||||
modelParamsNode["max_trees_num"] >> MAX_TREES_NUM;
|
||||
is_trained = rtrees->train( &data, CvRTParams( MAX_DEPTH, MIN_SAMPLE_COUNT, REG_ACCURACY,
|
||||
USE_SURROGATE, MAX_CATEGORIES, 0, true, // (calc_var_importance == true) <=> RF processes variable importance
|
||||
NACTIVE_VARS, MAX_TREES_NUM, OOB_EPS, CV_TERMCRIT_ITER)) != 0;
|
||||
}
|
||||
else if( !modelName.compare(CV_ERTREES) )
|
||||
{
|
||||
int MAX_DEPTH, MIN_SAMPLE_COUNT, MAX_CATEGORIES, CV_FOLDS, NACTIVE_VARS, MAX_TREES_NUM;
|
||||
float REG_ACCURACY = 0, OOB_EPS = 0.0;
|
||||
bool USE_SURROGATE, IS_PRUNED;
|
||||
modelParamsNode["max_depth"] >> MAX_DEPTH;
|
||||
modelParamsNode["min_sample_count"] >> MIN_SAMPLE_COUNT;
|
||||
modelParamsNode["use_surrogate"] >> USE_SURROGATE;
|
||||
modelParamsNode["max_categories"] >> MAX_CATEGORIES;
|
||||
modelParamsNode["cv_folds"] >> CV_FOLDS;
|
||||
modelParamsNode["is_pruned"] >> IS_PRUNED;
|
||||
modelParamsNode["nactive_vars"] >> NACTIVE_VARS;
|
||||
modelParamsNode["max_trees_num"] >> MAX_TREES_NUM;
|
||||
is_trained = ertrees->train( &data, CvRTParams( MAX_DEPTH, MIN_SAMPLE_COUNT, REG_ACCURACY,
|
||||
USE_SURROGATE, MAX_CATEGORIES, 0, false, // (calc_var_importance == true) <=> RF processes variable importance
|
||||
NACTIVE_VARS, MAX_TREES_NUM, OOB_EPS, CV_TERMCRIT_ITER)) != 0;
|
||||
model = RTrees::create(RTrees::Params( MAX_DEPTH, MIN_SAMPLE_COUNT, REG_ACCURACY,
|
||||
USE_SURROGATE, MAX_CATEGORIES, Mat(), true, // (calc_var_importance == true) <=> RF processes variable importance
|
||||
NACTIVE_VARS, TermCriteria(TermCriteria::COUNT, MAX_TREES_NUM, OOB_EPS)));
|
||||
}
|
||||
|
||||
if( !model.empty() )
|
||||
is_trained = model->train(data, 0);
|
||||
|
||||
if( !is_trained )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "in test case %d model training was failed", testCaseIdx );
|
||||
@@ -714,78 +431,46 @@ int CV_MLBaseTest::train( int testCaseIdx )
|
||||
return cvtest::TS::OK;
|
||||
}
|
||||
|
||||
float CV_MLBaseTest::get_error( int /*testCaseIdx*/, int type, vector<float> *resp )
|
||||
float CV_MLBaseTest::get_test_error( int /*testCaseIdx*/, vector<float> *resp )
|
||||
{
|
||||
int type = CV_TEST_ERROR;
|
||||
float err = 0;
|
||||
if( !modelName.compare(CV_NBAYES) )
|
||||
err = nbayes_calc_error( nbayes, &data, type, resp );
|
||||
else if( !modelName.compare(CV_KNEAREST) )
|
||||
{
|
||||
Mat _resp;
|
||||
if( modelName == CV_EM )
|
||||
assert( 0 );
|
||||
/*testCaseIdx = 0;
|
||||
int k = 2;
|
||||
validationFS.getFirstTopLevelNode()["validation"][modelName][dataSetNames[testCaseIdx]]["model_params"]["k"] >> k;
|
||||
err = knearest->calc_error( &data, k, type, resp );*/
|
||||
}
|
||||
else if( !modelName.compare(CV_SVM) )
|
||||
err = svm_calc_error( svm, &data, type, resp );
|
||||
else if( !modelName.compare(CV_EM) )
|
||||
assert( 0 );
|
||||
else if( !modelName.compare(CV_ANN) )
|
||||
err = ann_calc_error( ann, &data, cls_map, type, resp );
|
||||
else if( !modelName.compare(CV_DTREE) )
|
||||
err = dtree->calc_error( &data, type, resp );
|
||||
else if( !modelName.compare(CV_BOOST) )
|
||||
err = boost->calc_error( &data, type, resp );
|
||||
else if( !modelName.compare(CV_RTREES) )
|
||||
err = rtrees->calc_error( &data, type, resp );
|
||||
else if( !modelName.compare(CV_ERTREES) )
|
||||
err = ertrees->calc_error( &data, type, resp );
|
||||
else if( modelName == CV_ANN )
|
||||
err = ann_calc_error( model, data, cls_map, type, resp );
|
||||
else if( modelName == CV_DTREE || modelName == CV_BOOST || modelName == CV_RTREES ||
|
||||
modelName == CV_SVM || modelName == CV_NBAYES || modelName == CV_KNEAREST )
|
||||
err = model->calcError( data, true, _resp );
|
||||
if( !_resp.empty() && resp )
|
||||
_resp.convertTo(*resp, CV_32F);
|
||||
return err;
|
||||
}
|
||||
|
||||
void CV_MLBaseTest::save( const char* filename )
|
||||
{
|
||||
if( !modelName.compare(CV_NBAYES) )
|
||||
nbayes->save( filename );
|
||||
else if( !modelName.compare(CV_KNEAREST) )
|
||||
knearest->save( filename );
|
||||
else if( !modelName.compare(CV_SVM) )
|
||||
svm->save( filename );
|
||||
else if( !modelName.compare(CV_ANN) )
|
||||
ann->save( filename );
|
||||
else if( !modelName.compare(CV_DTREE) )
|
||||
dtree->save( filename );
|
||||
else if( !modelName.compare(CV_BOOST) )
|
||||
boost->save( filename );
|
||||
else if( !modelName.compare(CV_RTREES) )
|
||||
rtrees->save( filename );
|
||||
else if( !modelName.compare(CV_ERTREES) )
|
||||
ertrees->save( filename );
|
||||
model->save( filename );
|
||||
}
|
||||
|
||||
void CV_MLBaseTest::load( const char* filename )
|
||||
{
|
||||
if( !modelName.compare(CV_NBAYES) )
|
||||
nbayes->load( filename );
|
||||
else if( !modelName.compare(CV_KNEAREST) )
|
||||
knearest->load( filename );
|
||||
else if( !modelName.compare(CV_SVM) )
|
||||
{
|
||||
delete svm;
|
||||
svm = new CvSVM;
|
||||
svm->load( filename );
|
||||
}
|
||||
else if( !modelName.compare(CV_ANN) )
|
||||
ann->load( filename );
|
||||
else if( !modelName.compare(CV_DTREE) )
|
||||
dtree->load( filename );
|
||||
else if( !modelName.compare(CV_BOOST) )
|
||||
boost->load( filename );
|
||||
else if( !modelName.compare(CV_RTREES) )
|
||||
rtrees->load( filename );
|
||||
else if( !modelName.compare(CV_ERTREES) )
|
||||
ertrees->load( filename );
|
||||
if( modelName == CV_NBAYES )
|
||||
model = StatModel::load<NormalBayesClassifier>( filename );
|
||||
else if( modelName == CV_KNEAREST )
|
||||
model = StatModel::load<KNearest>( filename );
|
||||
else if( modelName == CV_SVM )
|
||||
model = StatModel::load<SVM>( filename );
|
||||
else if( modelName == CV_ANN )
|
||||
model = StatModel::load<ANN_MLP>( filename );
|
||||
else if( modelName == CV_DTREE )
|
||||
model = StatModel::load<DTrees>( filename );
|
||||
else if( modelName == CV_BOOST )
|
||||
model = StatModel::load<Boost>( filename );
|
||||
else if( modelName == CV_RTREES )
|
||||
model = StatModel::load<RTrees>( filename );
|
||||
else
|
||||
CV_Error( CV_StsNotImplemented, "invalid stat model name");
|
||||
}
|
||||
|
||||
/* End of file. */
|
||||
|
||||
Reference in New Issue
Block a user