예제 #1
0
void InferenceEngineBP::computeBeliefs(Beliefs &beliefs, FeatureGenerator *fGen, 
	DataSequence *X, Model *m, int bComputePartition, int seqLabel, bool bUseStatePerNodes)
{  
	// Variable definition  
	int xi, xj, nbNodes, seqLength;
	std::map<int,BPNode*> nodes; // tree graph
	std::map<int,BPNode*>::iterator itm;
	std::list<BPNode*>::iterator itl;
	BPNode* root;
	iMatrix adjMat;
	iVector nbStates;
	dVector*  phi_i  = 0; // singleton potentials
	dMatrix** phi_ij = 0; // pairwise potentials
	dVector** msg    = 0; // messages

	if( m->isMultiViewMode() )
		m->getAdjacencyMatrixMV(adjMat, X);
	else {
		uMatrix uAdjMat;
		m->getAdjacencyMatrix(uAdjMat, X);
		adjMat.resize(uAdjMat.getWidth(),uAdjMat.getHeight());
		for(xi=0; xi<uAdjMat.getHeight(); xi++)
			for(xj=0; xj<uAdjMat.getWidth(); xj++)
				adjMat(xi,xj) = uAdjMat(xi,xj);
	}

	nbNodes = adjMat.getHeight(); 
	seqLength = X->length();

	// Create a vector that contains nbStates
	nbStates.create(nbNodes);
	for(xi=0; xi<nbNodes; xi++)
		nbStates[xi] = (m->isMultiViewMode()) 
			? m->getNumberOfStatesMV(xi/seqLength) : m->getNumberOfStates();

	// Create BPGraph from adjMat
	for(xi=0; xi<nbNodes; xi++) {		
		BPNode* v = new BPNode(xi, nbStates[xi]);
		nodes.insert( std::pair<int,BPNode*>(xi,v) );
	}
	for(xi=0; xi<nbNodes; xi++) {
		for(xj=xi+1; xj<nbNodes; xj++) {
			if( !adjMat(xi,xj) ) continue;
			nodes[xi]->addNeighbor(nodes[xj]);
			nodes[xj]->addNeighbor(nodes[xi]);
		}
	}

	// Initialize  
	initMessages(msg, X, m, adjMat, nbStates);
	initBeliefs(beliefs, X, m, adjMat, nbStates);
	initPotentials(phi_i, phi_ij, fGen, X, m, adjMat, nbStates, seqLabel);
	
	// Message update
	root = nodes[0]; // any node can be the root node
	{
		for(itl=root->neighbors.begin(); itl!=root->neighbors.end(); itl++)
			collect(root, *itl, phi_i, phi_ij, msg);
		for(itl=root->neighbors.begin(); itl!=root->neighbors.end(); itl++)
			distribute(root, *itl, phi_i, phi_ij, msg);
	}
	updateBeliefs(beliefs, phi_i, phi_ij, msg, X, m, adjMat);

	// Clean up
	for(xi=0; xi<nbNodes; xi++) { 		
		delete[] msg[xi]; msg[xi] = 0; 
		delete[] phi_ij[xi]; phi_ij[xi] = 0;
	}
	delete[] msg; msg=0;
	delete[] phi_i; phi_i = 0;
	delete[] phi_ij;  phi_ij  = 0; 

	for(itm=nodes.begin(); itm!=nodes.end(); itm++) 
		delete (*itm).second; 
	nodes.clear();   
}
void InferenceEngineLoopyBP::computeBeliefs(Beliefs &beliefs, FeatureGenerator *fGen,
                                            DataSequence *X, Model *m, int bComputePartition, int seqLabel, bool bUseStatePerNodes)
{
  // Get adjacency matrix; values indicate edge index (use upper triangle only)
  iMatrix adjMat;
  if( m->isMultiViewMode() )
    m->getAdjacencyMatrixMV(adjMat, X);
  else {
    // Quick and dirty, but I don't want to change Model::makeChain()
    int edgeID = 1;
    adjMat.create(X->length(),X->length());
    for(int r=1; r<adjMat.getHeight(); r++) {
      adjMat(r,r-1) = edgeID;
      adjMat(r-1,r) = edgeID;
      edgeID++;
    }
  }
  int adjMatMax = adjMat.getMaxValue();
  
  // 1. Initialize beliefs
  initializeBeliefs(beliefs, X, m, adjMat);
  
  // 2. Initialize messages
  std::vector<dVector> messages, prev_messages;
  initializeMessages(messages, X, m, adjMat, adjMatMax, false);
  for(unsigned int i=0; i<messages.size(); i++) {
    dVector v; prev_messages.push_back(v);
  }
  
  // 3. Initialize potentials
  Beliefs potentials;
  initializePotentials(potentials, fGen, X, m, adjMat, seqLabel, bUseStatePerNodes);
  
  // 4. Update loopy belief network
  int T = X->length();
  int V = m->getNumberOfViews();
  int nbNodes = V*T;
  
  int *messageUpdateOrder = new int[nbNodes];
  
  for(int iter=0; iter<m_max_iter; iter++)
  {
    // Get message update order
    getRandomUpdateOrder(messageUpdateOrder, X, m);
    
    // Update messages
    for( int i=0; i<nbNodes; i++ ) {
      int xi = messageUpdateOrder[i];
      for( int xj=0; xj<nbNodes; xj++ ) {
        if( !adjMat(xi,xj) ) continue;
        sendMessage(xi,xj,nbNodes,potentials,messages,adjMat,adjMatMax,m->isMaxMargin());
      }
    }
    
    // Convergence check
    if( iter>0 ) {
      double error = 0;
      for(unsigned int i=0; i<messages.size(); i++)
        for(int j=0; j<messages[i].getLength(); j++)
          error += fabs(messages[i][j] - prev_messages[i][j]);
      if( error < m_min_threshold ) break;
    }
    
    // Copy messages
    for(unsigned int i=0; i<messages.size(); i++)
      prev_messages[i] = messages[i];
  }
  
  // Compute beliefs & compute partition
  updateBeliefs(nbNodes, beliefs, potentials, messages, adjMat, adjMatMax);
  
  // 5. Clean up and Return
  if( messageUpdateOrder ) {
    delete[] messageUpdateOrder; messageUpdateOrder = 0;
  }
}