void WeakDiscreteTreeLearner::sortIndexesBasedOnDataPositions(indices_t &positions, const size_t featureIndex) const { const FeaturesResponses &featuresResponses = _trainingData->getFeatureResponses(); std::sort(positions.begin(), positions.end(), comparator(featuresResponses, featureIndex)); return; }
int WeakDiscreteTreeLearner::createNode( const weights_t &weights, const indices_t &indices, const size_t start, const size_t end, TreeNode::shared_ptr &node, double &minError, const bool isLeft, const int root_node_bottom_height, const int root_node_left_width) const { TrainingData::point_t modelWindow = _trainingData->getModelWindow(); const int shrinking_factor = bootstrapping::integral_channels_computer_t::get_shrinking_factor(), modelWidth = modelWindow.x() / shrinking_factor , modelHeight = modelWindow.y() / shrinking_factor; //for all features get responses on every image //find feature with lowest error const size_t numFeatures = _trainingData->getFeaturesPoolSize(); std::vector<std::pair<double, size_t> > minErrorsForSearch(numFeatures, std::make_pair(std::numeric_limits<double>::max(), 0)); indices_t indicesCrop; const int binsize = 1000; if(start > end) { throw std::invalid_argument("WeakDiscreteTreeLearner::createNode received start > end but expected start <= end"); } indicesCrop.resize(end - start); std::copy(indices.begin() + start, indices.begin() + end, indicesCrop.begin()); if (indicesCrop.size() == 0) { return -1; } int return_value = 0; //find max valid feature index size_t max_valid_feature_index= 0; for (size_t featureIndex = numFeatures-1; featureIndex >=0; --featureIndex) { if (_trainingData->getFeatureValidity(featureIndex)) { max_valid_feature_index = featureIndex+1; break; } } //biasing features not yet supported double _pushBias = 0; #pragma omp parallel for reduction(+:return_value) schedule(guided) for (size_t featureIndex = 0; featureIndex < max_valid_feature_index; ++featureIndex) { if (_trainingData->getFeatureValidity(featureIndex)){ const int minv = (*_mins)[featureIndex], maxv = (*_maxs)[featureIndex]; double error = std::numeric_limits<double>::max(); return_value += getErrorEstimate(weights, indicesCrop, featureIndex, binsize, minv, maxv, error); minErrorsForSearch[featureIndex] = std::make_pair(error, featureIndex); } } // end of "for each feature" //if ( *(std::min_element(minErrorsForSearch.begin(),minErrorsForSearch.end(), sort_pair())) >2)//== mm) if (return_value < 0) { //create dummy node and return; //node = TreeNode::shared_ptr(new TreeNode(minthr, alphamin, _features[minFeat], minFeat, indicesCrop, splitIndexMin )); return -1; } const int deltaH=0; //get kth minimal elements //std::sort(minErrorsForSearch.begin(), minErrorsForSearch.end(), sort_pair()); //thrust::sort(thrust::reinterpret_tag<thrust::omp::tag>(minErrorsForSearch.begin()), // thrust::reinterpret_tag<thrust::omp::tag>(minErrorsForSearch.end()), // sort_pair()); std::sort(minErrorsForSearch.begin(), minErrorsForSearch.end(), sort_pair()); //search the feature that is highest up in the image int miny = std::numeric_limits<int>::max(); int minx = std::numeric_limits<int>::max(); int minFeatureIndex = -1; double errorth; if (minErrorsForSearch.size() > 0){ errorth= std::min(0.49999999999, minErrorsForSearch[0].first* (1.0+_pushBias)); } else{ throw std::runtime_error("minErrorsForSearch has size 0: no features in pool?"); } for (size_t i = 0; i< minErrorsForSearch.size(); ++i){ const int this_feat_idx = minErrorsForSearch[i].second; double error= minErrorsForSearch[i].first; if (_pushBias ==0){ minFeatureIndex = this_feat_idx; break; } if (error > errorth) break; const Feature this_feat = _trainingData->getFeature(this_feat_idx); int y = this_feat.y + this_feat.height; int x = this_feat.x + this_feat.width; } if (minFeatureIndex == -1) { //create dummy node and return; //node = TreeNode::shared_ptr(new TreeNode(minthr, alphamin, _features[minFeat], minFeat, indicesCrop, splitIndexMin )); return -1; } sortIndexesBasedOnDataPositions(indicesCrop, minFeatureIndex); int splitIndexMin = -1; int minThreshold = -1; int alphaMin = -1; if (findThreshold(weights, indicesCrop, minFeatureIndex, minError, minThreshold, alphaMin, splitIndexMin) == -1) { return -1; } if(splitIndexMin < 0) { throw std::runtime_error("WeakDiscreteTreeLearner::createNode, findThreshold failed to find an adequate split index"); } // set the shared_ptr to point towards a new node instance node.reset(new TreeNode(minThreshold, alphaMin, _trainingData->getFeature(minFeatureIndex), minFeatureIndex, indicesCrop, splitIndexMin, isLeft)); return 0; }