mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 06:26:29 +08:00
Merge pull request #10057 from LaurentBerger:ParaCalcError
This commit is contained in:
commit
c6fb99357c
@ -72,49 +72,91 @@ bool StatModel::train( InputArray samples, int layout, InputArray responses )
|
|||||||
return train(TrainData::create(samples, layout, 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>();
|
||||||
|
bool isclassifier = s.isClassifier();
|
||||||
|
Mat responses = data->getResponses();
|
||||||
|
int responses_type = responses.type();
|
||||||
|
|
||||||
|
double err = 0;
|
||||||
|
|
||||||
|
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 = s.predict(sample);
|
||||||
|
float val0 = (responses_type == CV_32S) ? (float)responses.at<int>(si) : responses.at<float>(si);
|
||||||
|
|
||||||
|
if (isclassifier)
|
||||||
|
err += fabs(val - val0) > FLT_EPSILON;
|
||||||
|
else
|
||||||
|
err += (val - val0)*(val - val0);
|
||||||
|
if (!resp.empty())
|
||||||
|
resp.at<float>(i) = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
CV_TRACE_FUNCTION_SKIP_NESTED();
|
||||||
Mat samples = data->getSamples();
|
Mat samples = data->getSamples();
|
||||||
int layout = data->getLayout();
|
|
||||||
Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
|
Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
|
||||||
const int* sidx_ptr = sidx.ptr<int>();
|
int n = (int)sidx.total();
|
||||||
int i, n = (int)sidx.total();
|
|
||||||
bool isclassifier = isClassifier();
|
bool isclassifier = isClassifier();
|
||||||
Mat responses = data->getResponses();
|
Mat responses = data->getResponses();
|
||||||
int responses_type = responses.type();
|
|
||||||
|
|
||||||
if( n == 0 )
|
if (n == 0)
|
||||||
n = data->getNSamples();
|
n = data->getNSamples();
|
||||||
|
|
||||||
if( n == 0 )
|
if (n == 0)
|
||||||
return -FLT_MAX;
|
return -FLT_MAX;
|
||||||
|
|
||||||
Mat resp;
|
Mat resp;
|
||||||
if( _resp.needed() )
|
if (_resp.needed())
|
||||||
resp.create(n, 1, CV_32F);
|
resp.create(n, 1, CV_32F);
|
||||||
|
|
||||||
double err = 0;
|
double err = 0;
|
||||||
for( i = 0; i < n; i++ )
|
vector<double> errStrip(n,0.0);
|
||||||
{
|
ParallelCalcError x(data, testerr, resp, *this,errStrip);
|
||||||
int si = sidx_ptr ? sidx_ptr[i] : i;
|
|
||||||
Mat sample = layout == ROW_SAMPLE ? samples.row(si) : samples.col(si);
|
|
||||||
float val = predict(sample);
|
|
||||||
float val0 = (responses_type == CV_32S) ? (float)responses.at<int>(si) : responses.at<float>(si);
|
|
||||||
|
|
||||||
if( isclassifier )
|
parallel_for_(Range(0,n),x);
|
||||||
err += fabs(val - val0) > FLT_EPSILON;
|
|
||||||
else
|
|
||||||
err += (val - val0)*(val - val0);
|
|
||||||
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() )
|
for (size_t i = 0; i < errStrip.size(); i++)
|
||||||
|
err += errStrip[i];
|
||||||
|
|
||||||
|
if (_resp.needed())
|
||||||
resp.copyTo(_resp);
|
resp.copyTo(_resp);
|
||||||
|
|
||||||
return (float)(err / n * (isclassifier ? 100 : 1));
|
return (float)(err / n * (isclassifier ? 100 : 1));
|
||||||
|
Loading…
Reference in New Issue
Block a user