示例#1
0
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;
}
示例#2
0
	//-------------------------------------------------------------------------------
	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;
	}