AlphaReal TreeLearnerUCT::run() { if ( _numOfCalling == 0 ) { if (_verbose > 0) { cout << "Initializing tree..." << endl; } InnerNodeUCTSparse::setDepth( _numBaseLearners ); InnerNodeUCTSparse::setBranchOrder( _pTrainingData->getNumAttributes() ); _root.setChildrenNum(); //createUCTTree(); } _numOfCalling++; set< int > tmpIdx, idxPos, idxNeg; _pTrainingData->clearIndexSet(); for( int i = 0; i < _pTrainingData->getNumExamples(); i++ ) tmpIdx.insert( i ); vector< int > trajectory(0); _root.getBestTrajectory( trajectory ); // for UCT for(int ib = 0; ib < _numBaseLearners; ++ib) _baseLearners[ib]->setTrainingData(_pTrainingData); AlphaReal edge = numeric_limits<AlphaReal>::max(); BaseLearner* pPreviousBaseLearner = 0; //floatBaseLearner tmpPair, tmpPairPos, tmpPairNeg; // for storing the inner point (learneres) which will be extended //vector< floatBaseLearner > bLearnerVector; InnerNodeType innerNode; priority_queue<InnerNodeType, deque<InnerNodeType>, greater_first<InnerNodeType> > pq; //train the first learner //_baseLearners[0]->run(); pPreviousBaseLearner = _baseLearners[0]->copyState(); dynamic_cast<FeaturewiseLearner*>(pPreviousBaseLearner)->run( trajectory[0] ); //this contains the number of baselearners int ib = 0; NodePointUCT tmpNodePoint, nodeLeft, nodeRight; //////////////////////////////////////////////////////// //set the edge //tmpPair.first = getEdge( pPreviousBaseLearner, _pTrainingData ); //tmpPair.second.first.first = pPreviousBaseLearner; // set the pointer of the parent //tmpPair.second.first.second.first = 0; // set that this is a neg child //tmpPair.second.first.second.second = 0; //tmpPair.second.second = tmpIdx; //bLearnerVector = calculateChildrenAndEnergies( tmpPair ); /// pPreviousBaseLearner->setTrainingData( _pTrainingData ); tmpNodePoint._edge = pPreviousBaseLearner->getEdge(); tmpNodePoint._learner = pPreviousBaseLearner; tmpNodePoint._idx = 0; tmpNodePoint._depth = 0; tmpNodePoint._learnerIdxSet = tmpIdx; calculateChildrenAndEnergies( tmpNodePoint, trajectory[1] ); //////////////////////////////////////////////////////// //insert the root into the priority queue if ( tmpNodePoint._extended ) { if (_verbose > 2) { //cout << "Edges: (parent, pos, neg): " << bLearnerVector[0].first << " " << bLearnerVector[1].first << " " << bLearnerVector[2].first << endl << flush; //cout << "alpha[" << (ib) << "] = " << _alpha << endl << flush; cout << "Edges: (parent, pos, neg): " << tmpNodePoint._edge << " " << tmpNodePoint._leftEdge << " " << tmpNodePoint._rightEdge << endl << flush; } // if the energy is getting higher then we push it into the priority queue if ( tmpNodePoint._edge < ( tmpNodePoint._leftEdge + tmpNodePoint._rightEdge ) ) { float deltaEdge = abs( tmpNodePoint._edge - ( tmpNodePoint._leftEdge + tmpNodePoint._rightEdge ) ); innerNode.first = deltaEdge; innerNode.second = tmpNodePoint; pq.push( innerNode ); } else { //delete bLearnerVector[0].second.first.first; delete tmpNodePoint._leftChild; delete tmpNodePoint._rightChild; } } if ( pq.empty() ) { // we don't extend the root BaseLearner* tmpBL = _baseLearners[0]; _baseLearners[0] = tmpNodePoint._learner; delete tmpBL; ib = 1; } while ( ! pq.empty() && ( ib < _numBaseLearners ) ) { //get the best learner from the priority queue innerNode = pq.top(); if (_verbose > 2) { cout << "Delta energy: " << innerNode.first << endl << flush; cout << "Size of priority queue: " << pq.size() << endl << flush; } pq.pop(); tmpNodePoint = innerNode.second; //tmpPair = bLearnerVector[0]; //tmpPairPos = bLearnerVector[1]; //tmpPairNeg = bLearnerVector[2]; nodeLeft._edge = tmpNodePoint._leftEdge; nodeLeft._learner = tmpNodePoint._leftChild; nodeLeft._learnerIdxSet = tmpNodePoint._leftChildIdxSet; nodeRight._edge = tmpNodePoint._rightEdge; nodeRight._learner = tmpNodePoint._rightChild; nodeRight._learnerIdxSet = tmpNodePoint._rightChildIdxSet; //store the baselearner if the deltaenrgy will be higher if ( _verbose > 3 ) { cout << "Insert learner: " << ib << endl << flush; } int parentIdx = tmpNodePoint._parentIdx; BaseLearner* tmpBL = _baseLearners[ib]; _baseLearners[ib] = tmpNodePoint._learner; delete tmpBL; nodeLeft._parentIdx = ib; nodeRight._parentIdx = ib; nodeLeft._leftOrRightChild = 0; nodeRight._leftOrRightChild = 1; nodeLeft._depth = tmpNodePoint._depth + 1; nodeRight._depth = tmpNodePoint._depth + 1; if ( ib > 0 ) { //set the descendant idx _idxPairs[ parentIdx ][ tmpNodePoint._leftOrRightChild ] = ib; } ib++; if ( ib >= _numBaseLearners ) break; //extend positive node if ( nodeLeft._learner ) { calculateChildrenAndEnergies( nodeLeft, trajectory[ nodeLeft._depth + 1 ] ); } else { nodeLeft._extended = false; } //calculateChildrenAndEnergies( nodeLeft ); // if the energie is getting higher then we push it into the priority queue if ( nodeLeft._extended ) { if (_verbose > 2) { //cout << "Edges: (parent, pos, neg): " << bLearnerVector[0].first << " " << bLearnerVector[1].first << " " << bLearnerVector[2].first << endl << flush; //cout << "alpha[" << (ib) << "] = " << _alpha << endl << flush; cout << "Edges: (parent, pos, neg): " << nodeLeft._edge << " " << nodeLeft._leftEdge << " " << nodeLeft._rightEdge << endl << flush; } // if the energy is getting higher then we push it into the priority queue if ( nodeLeft._edge < ( nodeLeft._leftEdge + nodeLeft._rightEdge ) ) { float deltaEdge = abs( nodeLeft._edge - ( nodeLeft._leftEdge + nodeLeft._rightEdge ) ); innerNode.first = deltaEdge; innerNode.second = nodeLeft; pq.push( innerNode ); } else { //delete bLearnerVector[0].second.first.first; delete nodeLeft._leftChild; delete nodeLeft._rightChild; if ( ib >= _numBaseLearners ) { delete nodeLeft._learner; break; } else { //this will be a leaf, we do not extend further int parentIdx = nodeLeft._parentIdx; BaseLearner* tmpBL = _baseLearners[ib]; _baseLearners[ib] = nodeLeft._learner; delete tmpBL; _idxPairs[ parentIdx ][ 0 ] = ib; ib += 1; } } } //extend negative node if ( nodeRight._learner ) { calculateChildrenAndEnergies( nodeRight, trajectory[ nodeRight._depth + 1 ] ); } else { nodeRight._extended = false; } // if the energie is getting higher then we push it into the priority queue if ( nodeRight._extended ) { if (_verbose > 2) { cout << "Edges: (parent, pos, neg): " << nodeRight._edge << " " << nodeRight._leftEdge << " " << nodeRight._rightEdge << endl << flush; //cout << "alpha[" << (ib) << "] = " << _alpha << endl << flush; } // if the energie is getting higher then we push it into the priority queue if ( nodeRight._edge < ( nodeRight._leftEdge + nodeRight._rightEdge ) ) { float deltaEdge = abs( nodeRight._edge - ( nodeRight._leftEdge + nodeRight._rightEdge ) ); innerNode.first = deltaEdge; innerNode.second = nodeRight; pq.push( innerNode ); } else { //delete bLearnerVector[0].second.first.first; delete nodeRight._leftChild; delete nodeRight._rightChild; if ( ib >= _numBaseLearners ) { delete nodeRight._learner; break; } else { //this will be a leaf, we do not extend further int parentIdx = nodeRight._parentIdx; BaseLearner* tmpBL = _baseLearners[ib]; _baseLearners[ib] = nodeRight._learner; delete tmpBL; _idxPairs[ parentIdx ][ 1 ] = ib; ib += 1; } } } } for(int ib2 = ib; ib2 < _numBaseLearners; ++ib2) delete _baseLearners[ib2]; _numBaseLearners = ib; if (_verbose > 2) { cout << "Num of learners: " << _numBaseLearners << endl << flush; } //clear the priority queur while ( ! pq.empty() && ( ib < _numBaseLearners ) ) { //get the best learner from the priority queue innerNode = pq.top(); pq.pop(); tmpNodePoint = innerNode.second; delete tmpNodePoint._learner; delete tmpNodePoint._leftChild; delete tmpNodePoint._rightChild; } _id = _baseLearners[0]->getId(); for(int ib = 0; ib < _numBaseLearners; ++ib) _id += "_x_" + _baseLearners[ib]->getId(); //calculate alpha this->_alpha = 0.0; float eps_min = 0.0, eps_pls = 0.0; _pTrainingData->clearIndexSet(); for( int i = 0; i < _pTrainingData->getNumExamples(); i++ ) { vector< Label> l = _pTrainingData->getLabels( i ); for( vector< Label >::iterator it = l.begin(); it != l.end(); it++ ) { float result = this->classify( _pTrainingData, i, it->idx ); if ( ( result * it->y ) < 0 ) eps_min += it->weight; if ( ( result * it->y ) > 0 ) eps_pls += it->weight; } } //update the weights in the UCT tree double updateWeight = 0.0; if ( _updateRule == EDGE_SQUARE ) { double edge = getEdge(); updateWeight = 1 - sqrt( 1 - ( edge * edge ) ); } else if ( _updateRule == ALPHAS ) { double alpha = this->getAlpha(); updateWeight = alpha; } else if ( _updateRule == ESQUARE ) { double edge = getEdge(); updateWeight = edge * edge; } _root.updateInnerNodes( updateWeight, trajectory ); if (_verbose > 2) { cout << "Update weight (" << updateWeight << ")" << "\tUpdate rule index: "<< _updateRule << endl << flush; } // set the smoothing value to avoid numerical problem // when theta=0. setSmoothingVal( (float)1.0 / (float)_pTrainingData->getNumExamples() * (float)0.01 ); this->_alpha = getAlpha( eps_min, eps_pls ); // calculate the energy (sum of the energy of the leaves float energy = this->getEnergy( eps_min, eps_pls ); return energy; }
//------------------------------------------------------------------------------- float BanditTreeLearner::run() { if ( ! this->_banditAlgo->isInitialized() ) { init(); } // the bandit algorithm selects the subset the tree learner is aloowed to use // the armindexes will be stored in _armsForPulling getArms(); //declarations NodePoint tmpNodePoint, nodeLeft, nodeRight; ScalarLearner* pPreviousBaseLearner = 0; set< int > tmpIdx; //this contains the current number of baselearners int ib = 0; floatInnerNode innerNode; // for storing the inner point (learneres) which will be extended priority_queue<floatInnerNode, deque<floatInnerNode>, greater_first<floatInnerNode> > pq; for(int ib = 0; ib < _numBaseLearners; ++ib) _baseLearners[ib]->setTrainingData(_pTrainingData); //train the first learner on the whole dataset _pTrainingData->clearIndexSet(); pPreviousBaseLearner = dynamic_cast<ScalarLearner* >(_baseLearners[0]->copyState()); float energy = dynamic_cast< FeaturewiseLearner* >(pPreviousBaseLearner)->run( _armsForPulling ); if ( energy != energy ) { if (_verbose > 2) { cout << "Cannot find weak hypothesis, constant learner is used!!" << endl; } delete pPreviousBaseLearner; //cannot find better than constant learner ScalarLearner* pConstantWeakHypothesisSource = dynamic_cast<ScalarLearner*>(BaseLearner::RegisteredLearners().getLearner("ConstantLearner")); ScalarLearner* cLearner = dynamic_cast<ScalarLearner*>(pConstantWeakHypothesisSource->create()); cLearner->setTrainingData(_pTrainingData); float constantEnergy = cLearner->run(); tmpNodePoint._edge = 0.0; tmpNodePoint._learner = cLearner; tmpNodePoint._idx = 0; tmpNodePoint._learnerIdxSet = tmpIdx; tmpNodePoint._extended = false; } else { //try to extend the root for( int i = 0; i < _pTrainingData->getNumExamples(); i++ ) tmpIdx.insert( i ); tmpNodePoint._edge = pPreviousBaseLearner->getEdge(); tmpNodePoint._learner = pPreviousBaseLearner; tmpNodePoint._idx = 0; tmpNodePoint._learnerIdxSet = tmpIdx; calculateChildrenAndEnergies( tmpNodePoint ); } //////////////////////////////////////////////////////// //insert the root into the priority queue if ( tmpNodePoint._extended ) { if (_verbose > 2) { //cout << "Edges: (parent, pos, neg): " << bLearnerVector[0].first << " " << bLearnerVector[1].first << " " << bLearnerVector[2].first << endl << flush; //cout << "alpha[" << (ib) << "] = " << _alpha << endl << flush; cout << "Edges: (parent, pos, neg): " << tmpNodePoint._edge << " " << tmpNodePoint._leftEdge << " " << tmpNodePoint._rightEdge << endl << flush; } // if the energy is getting higher then we push it into the priority queue if ( tmpNodePoint._edge < ( tmpNodePoint._leftEdge + tmpNodePoint._rightEdge ) ) { float deltaEdge = abs( tmpNodePoint._edge - ( tmpNodePoint._leftEdge + tmpNodePoint._rightEdge ) ); innerNode.first = deltaEdge; innerNode.second = tmpNodePoint; pq.push( innerNode ); } else { //delete bLearnerVector[0].second.first.first; delete tmpNodePoint._leftChild; delete tmpNodePoint._rightChild; } } // we cannot extend the root node if ( pq.empty() ) { // we don't extend the root BaseLearner* tmpBL = _baseLearners[0]; _baseLearners[0] = tmpNodePoint._learner; delete tmpBL; ib = 1; } while ( ! pq.empty() && ( ib < _numBaseLearners ) ) { //get the best learner from the priority queue innerNode = pq.top(); if (_verbose > 2) { cout << "Delta edge: " << innerNode.first << endl << flush; cout << "Size of priority queue: " << pq.size() << endl << flush; } pq.pop(); tmpNodePoint = innerNode.second; nodeLeft._edge = tmpNodePoint._leftEdge; nodeLeft._learner = tmpNodePoint._leftChild; nodeLeft._learnerIdxSet = tmpNodePoint._leftChildIdxSet; nodeRight._edge = tmpNodePoint._rightEdge; nodeRight._learner = tmpNodePoint._rightChild; nodeRight._learnerIdxSet = tmpNodePoint._rightChildIdxSet; //store the baselearner if the delta enrgy will be higher if ( _verbose > 3 ) { cout << "Insert learner: " << ib << endl << flush; } int parentIdx = tmpNodePoint._parentIdx; BaseLearner* tmpBL = _baseLearners[ib]; _baseLearners[ib] = tmpNodePoint._learner; delete tmpBL; nodeLeft._parentIdx = ib; nodeRight._parentIdx = ib; nodeLeft._leftOrRightChild = 0; nodeRight._leftOrRightChild = 1; if ( ib > 0 ) { //set the descendant idx _idxPairs[ parentIdx ][ tmpNodePoint._leftOrRightChild ] = ib; } ib++; if ( ib >= _numBaseLearners ) break; //extend positive node if ( nodeLeft._learner ) { calculateChildrenAndEnergies( nodeLeft ); } else { nodeLeft._extended = false; } //calculateChildrenAndEnergies( nodeLeft ); // if the energy is getting higher then we push it into the priority queue if ( nodeLeft._extended ) { if (_verbose > 2) { //cout << "Edges: (parent, pos, neg): " << bLearnerVector[0].first << " " << bLearnerVector[1].first << " " << bLearnerVector[2].first << endl << flush; //cout << "alpha[" << (ib) << "] = " << _alpha << endl << flush; cout << "Edges: (parent, pos, neg): " << nodeLeft._edge << " " << nodeLeft._leftEdge << " " << nodeLeft._rightEdge << endl << flush; } // if the energy is getting higher then we push it into the priority queue if ( nodeLeft._edge < ( nodeLeft._leftEdge + nodeLeft._rightEdge ) ) { float deltaEdge = abs( nodeLeft._edge - ( nodeLeft._leftEdge + nodeLeft._rightEdge ) ); innerNode.first = deltaEdge; innerNode.second = nodeLeft; pq.push( innerNode ); } else { //delete bLearnerVector[0].second.first.first; delete nodeLeft._leftChild; delete nodeLeft._rightChild; if ( ib >= _numBaseLearners ) { delete nodeLeft._learner; break; } else { //this will be a leaf, we do not extend further int parentIdx = nodeLeft._parentIdx; BaseLearner* tmpBL = _baseLearners[ib]; _baseLearners[ib] = nodeLeft._learner; delete tmpBL; _idxPairs[ parentIdx ][ 0 ] = ib; ib += 1; } } } //extend negative node if ( nodeRight._learner ) { calculateChildrenAndEnergies( nodeRight ); } else { nodeRight._extended = false; } // if the energie is getting higher then we push it into the priority queue if ( nodeRight._extended ) { if (_verbose > 2) { cout << "Edges: (parent, pos, neg): " << nodeRight._edge << " " << nodeRight._leftEdge << " " << nodeRight._rightEdge << endl << flush; //cout << "alpha[" << (ib) << "] = " << _alpha << endl << flush; } // if the energie is getting higher then we push it into the priority queue if ( nodeRight._edge < ( nodeRight._leftEdge + nodeRight._rightEdge ) ) { float deltaEdge = abs( nodeRight._edge - ( nodeRight._leftEdge + nodeRight._rightEdge ) ); innerNode.first = deltaEdge; innerNode.second = nodeRight; pq.push( innerNode ); } else { //delete bLearnerVector[0].second.first.first; delete nodeRight._leftChild; delete nodeRight._rightChild; if ( ib >= _numBaseLearners ) { delete nodeRight._learner; break; } else { //this will be a leaf, we do not extend further int parentIdx = nodeRight._parentIdx; BaseLearner* tmpBL = _baseLearners[ib]; _baseLearners[ib] = nodeRight._learner; delete tmpBL; _idxPairs[ parentIdx ][ 1 ] = ib; ib += 1; } } } } for(int ib2 = ib; ib2 < _numBaseLearners; ++ib2) delete _baseLearners[ib2]; _numBaseLearners = ib; if (_verbose > 2) { cout << "Num of learners: " << _numBaseLearners << endl << flush; } //clear the priority queur while ( ! pq.empty() && ( ib < _numBaseLearners ) ) { //get the best learner from the priority queue innerNode = pq.top(); pq.pop(); tmpNodePoint = innerNode.second; delete tmpNodePoint._learner; delete tmpNodePoint._leftChild; delete tmpNodePoint._rightChild; } _id = _baseLearners[0]->getId(); for(int ib = 0; ib < _numBaseLearners; ++ib) _id += "_x_" + _baseLearners[ib]->getId(); //calculate alpha this->_alpha = 0.0; float eps_min = 0.0, eps_pls = 0.0; _pTrainingData->clearIndexSet(); for( int i = 0; i < _pTrainingData->getNumExamples(); i++ ) { vector< Label> l = _pTrainingData->getLabels( i ); for( vector< Label >::iterator it = l.begin(); it != l.end(); it++ ) { float result = this->classify( _pTrainingData, i, it->idx ); if ( ( result * it->y ) < 0 ) eps_min += it->weight; if ( ( result * it->y ) > 0 ) eps_pls += it->weight; } } // set the smoothing value to avoid numerical problem // when theta=0. setSmoothingVal( (float)(1.0 / _pTrainingData->getNumExamples() * 0.01 ) ); this->_alpha = getAlpha( eps_min, eps_pls ); // calculate the energy (sum of the energy of the leaves energy = this->getEnergy( eps_min, eps_pls ); //bandit part we calculate the reward _reward = getRewardFromEdge( getEdge() ); provideRewardForBanditAlgo(); return energy; }