Merge pull request #10057 from LaurentBerger:ParaCalcError

pull/10072/head
Alexander Alekhin 7 years ago
commit c6fb99357c
  1. 86
      modules/ml/src/inner_functions.cpp

@ -72,49 +72,91 @@ bool StatModel::train( InputArray samples, int layout, InputArray responses )
return train(TrainData::create(samples, layout, responses));
}
float StatModel::calcError( const Ptr<TrainData>& data, bool testerr, OutputArray _resp ) const
class ParallelCalcError : public ParallelLoopBody
{
private:
const Ptr<TrainData>& data;
bool &testerr;
Mat &resp;
const StatModel &s;
vector<double> &errStrip;
public:
ParallelCalcError(const Ptr<TrainData>& d, bool &t, Mat &_r,const StatModel &w, vector<double> &e) :
data(d),
testerr(t),
resp(_r),
s(w),
errStrip(e)
{
}
virtual void operator()(const Range& range) const
{
int idxErr = range.start;
CV_TRACE_FUNCTION_SKIP_NESTED();
Mat samples = data->getSamples();
int layout = data->getLayout();
Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
const int* sidx_ptr = sidx.ptr<int>();
int i, n = (int)sidx.total();
bool isclassifier = isClassifier();
bool isclassifier = s.isClassifier();
Mat responses = data->getResponses();
int responses_type = responses.type();
if( n == 0 )
n = data->getNSamples();
if( n == 0 )
return -FLT_MAX;
Mat resp;
if( _resp.needed() )
resp.create(n, 1, CV_32F);
double err = 0;
for( i = 0; i < n; i++ )
for (int i = range.start; i < range.end; i++)
{
int si = sidx_ptr ? sidx_ptr[i] : i;
Mat sample = layout == ROW_SAMPLE ? samples.row(si) : samples.col(si);
float val = predict(sample);
float val = s.predict(sample);
float val0 = (responses_type == CV_32S) ? (float)responses.at<int>(si) : responses.at<float>(si);
if( isclassifier )
if (isclassifier)
err += fabs(val - val0) > FLT_EPSILON;
else
err += (val - val0)*(val - val0);
if( !resp.empty() )
if (!resp.empty())
resp.at<float>(i) = val;
/*if( i < 100 )
{
printf("%d. ref %.1f vs pred %.1f\n", i, val0, val);
}*/
}
if( _resp.needed() )
errStrip[idxErr]=err ;
};
ParallelCalcError& operator=(const ParallelCalcError &) {
return *this;
};
};
float StatModel::calcError(const Ptr<TrainData>& data, bool testerr, OutputArray _resp) const
{
CV_TRACE_FUNCTION_SKIP_NESTED();
Mat samples = data->getSamples();
Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
int n = (int)sidx.total();
bool isclassifier = isClassifier();
Mat responses = data->getResponses();
if (n == 0)
n = data->getNSamples();
if (n == 0)
return -FLT_MAX;
Mat resp;
if (_resp.needed())
resp.create(n, 1, CV_32F);
double err = 0;
vector<double> errStrip(n,0.0);
ParallelCalcError x(data, testerr, resp, *this,errStrip);
parallel_for_(Range(0,n),x);
for (size_t i = 0; i < errStrip.size(); i++)
err += errStrip[i];
if (_resp.needed())
resp.copyTo(_resp);
return (float)(err / n * (isclassifier ? 100 : 1));

Loading…
Cancel
Save