Ejemplo n.º 1
0
// m_ij(x_j) = sum_xi {phi(i)*phi(i,j)*prod_{u \in N(i)\j} {m_uj(xi)}}
// m_ij(x_j) = max_xi {phi(i)*phi(i,j)*prod_{u \in N(i)\j} {m_uj(xi)}}
void InferenceEngineBP::sendMessage(BPNode* xi, BPNode* xj, dVector* phi_i, dMatrix** phi_ij, dVector** msg)
{    
	// potential(i) -> Vi
	dVector Vi(phi_i[xi->id]);
	
	// potential(i,j) -> Mij
	dMatrix Mij;
	if( xi->id < xj->id )
		Mij.set( phi_ij[xi->id][xj->id] );
	else {
		Mij.set( phi_ij[xj->id][xi->id] );
		Mij.transpose();
	}

	// prod_{u \in N(i)\j} {m_ui(xi)}	-> Vi
	std::list<BPNode*>::iterator it;
	for(it=xi->neighbors.begin(); it!=xi->neighbors.end(); it++) {
		if( xj->equal(*it) ) continue;
		Vi.add( msg[(*it)->id][xi->id] );
	}

	if( isSumProduct )
		logMultiply( Vi, Mij, msg[xi->id][xj->id] ); 
	else
		logMultiplyMaxProd( Vi, Mij, msg[xi->id][xj->id] ); 
}  
Ejemplo n.º 2
0
// m_ij(x_j) = sum_xi {potential(i)*potential(i,j)*prod_{u \in N(i)\j} {m_ui(xi)}}
void InferenceEngineLoopyBP::sendMessage(int xi, int xj, int nbNodes, const Beliefs potentials,
                                         std::vector<dVector>& messages, iMatrix adjMat, int adjMatMax, bool bMaxProd)
{
  int max_hi=-1; // for Viterbi decoding
  
  // potential(i)
  dVector Vi(potentials.belStates[xi]);
  
  // potential(i,j)
  dMatrix Mij(potentials.belEdges[adjMat(xi,xj)-1]);
  if( xi>xj ) Mij.transpose();
  
  // prod_{u \in N(i)\j} {m_ui(xi)}}
  int msg_idx;
  for( int xu=0; xu<nbNodes; xu++ ) {
    if( !adjMat(xu,xi) || xu==xj ) continue;
    msg_idx = (xu>xi) ? adjMatMax+adjMat(xu,xi)-1 : adjMat(xu,xi)-1;
    Vi.add(messages[msg_idx]);
  }
  
  // m_ij(xj) = Vi \dot Mij
  msg_idx = (xi>xj) ? adjMatMax+adjMat(xi,xj)-1 : adjMat(xi,xj)-1;
  if( bMaxProd )
    max_hi = logMultiplyMaxProd(Vi, Mij, messages[msg_idx]);
  else
    logMultiply(Vi, Mij, messages[msg_idx]);
  
  // Normalize messages to avoid numerical over/under-flow
  // Make \sum_{xj} m_ij(xj)=1. Other methods could also be used.
  double min = messages[msg_idx].min();
  if( min < 0 ) messages[msg_idx].add(-min);
  messages[msg_idx].multiply(1/messages[msg_idx].sum());
}
Ejemplo n.º 3
0
// b_i(xi) = potential(i) * prod_{u \in N(i)}{m_ui}
// b_ij(xi,xj) = potential(i) * potential(j) * potential(i,j)
//			     * prod_{u \in N(i)\j}{m_ui} * prod_{u \in N(j)\i}{m_uj}
void InferenceEngineBP::updateBeliefs(Beliefs& b, dVector* phi_i, dMatrix** phi_ij, 
	dVector** msg, DataSequence* X, Model* m, iMatrix adjMat)
{
	int xi, xj, xu, nbNodes, seqLength;
	dVector Vi, Vj;
	dMatrix Mij;
	
	nbNodes = adjMat.getHeight();
	seqLength = X->length();

	// b_i(xi) = potential(i) * prod_{u \in N(i)}{m_ui}
	for(xi=0; xi<nbNodes; xi++) {
		b.belStates[xi].set( phi_i[xi] ); 
		for(int xu=0; xu<nbNodes; xu++) {
			if( !adjMat(xu,xi) ) continue;
			b.belStates[xi].add( msg[xu][xi] );
		}	  
	}

	// b_ij(xi,xj) = potential(i) * potential(j) * potential(i,j)
	//			   * prod_{u \in N(i)\j}{m_ui} * prod_{u \in N(j)\i}{m_uj}	 
	for(xi=0; xi<nbNodes; xi++) {
		for(xj=xi+1; xj<nbNodes; xj++) { // xj starts from xi+1 because b_ij==b_ji
			if( !adjMat(xi,xj) ) continue;

			// potential(i) * prod_{u \in N(i)\j){m_ui}
			Vi.set( phi_i[xi] );
			for(xu=0; xu<nbNodes; xu++ ) {
				if( !adjMat(xu,xi) || xu==xj ) continue;
				Vi.add( msg[xu][xi] );
			}

			// potential(j) * prod_{u \in N(j)\i){m_uj}
			Vj.set( phi_i[xj] );
			for(xu=0; xu<nbNodes; xu++ ) {
				if( !adjMat(xu,xj) || xu==xi ) continue;
				Vj.add( msg[xu][xj] );
			}

			// (Vi*Vj*Mij) * potential(i,j)
			Mij.create(Vj.getLength(), Vi.getLength());
			logMultiply(Vi, Vj, Mij);
			Mij.add( phi_ij[xi][xj] );

			if( m->isMultiViewMode() )
				b.belEdges[adjMat(xi,xj)-1].set(Mij);
			else
				b.belEdges[xi].set(Mij);
		}
	}   

	// Normalize beliefs and compute partition
	unsigned int i;
	double logZ = 0;
	// marginals are consistent across nodes
	logZ = b.belStates[0].logSumExp(); 
	for(i=0; i<b.belStates.size(); i++) {
		b.belStates[i].add(-logZ);
		b.belStates[i].eltExp();
	}
	for(i=0; i<b.belEdges.size(); i++) {
		b.belEdges[i].add(-logZ);
		b.belEdges[i].eltExp();
	} 
	b.partition = logZ;
}
Ejemplo n.º 4
0
// b_i(xi)     = potential(i) * prod_{u \in N(i)}{m_ui}
// b_ij(xi,xj) = potential(i) * potential(j) * potential(i,j)
//			   * prod_{u \in N(i)\j}{m_ui} * prod_{u \in N(j)\i}{m_uj}
void InferenceEngineLoopyBP::updateBeliefs(int nbNodes, Beliefs& beliefs,
                                           const Beliefs potentials, const std::vector<dVector> messages,
                                           iMatrix adjMat, int adjMatMax)
{
  int msg_idx;
  dVector Vi, Vj;
  dMatrix Mij;
  
  // b_i(xi) = potential(i) * prod_{u \in N(i)}{m_ui}
  for(int xi=0; xi<nbNodes; xi++) {
    beliefs.belStates[xi].set(potentials.belStates[xi]);
    for(int xu=0; xu<nbNodes; xu++) {
      if( !adjMat(xu,xi) ) continue;
      msg_idx = (xu>xi) ? adjMatMax+adjMat(xu,xi)-1 : adjMat(xu,xi)-1;
      beliefs.belStates[xi].add(messages[msg_idx]);
    }
  }
  
  // b_ij(xi,xj) = potential(i) * potential(j) * potential(i,j)
  //			   * prod_{u \in N(i)\j}{m_ui} * prod_{u \in N(j)\i}{m_uj}
  for(int xi=0; xi<nbNodes; xi++) {
    for(int xj=xi+1; xj<nbNodes; xj++ ) { // xj starts from xi+1 because b_ij==b_ji
      if( !adjMat(xi,xj) ) continue;
      
      // potential(i) * prod_{u \in N(i)\j){m_ui}
      Vi.set(potentials.belStates[xi]);
      for(int xu=0; xu<nbNodes; xu++ ) {
        if( !adjMat(xu,xi) || xu==xj ) continue;
        msg_idx = (xu>xi) ? adjMatMax+adjMat(xu,xi)-1 : adjMat(xu,xi)-1;
        Vi.add(messages[msg_idx]);
      }
      
      // potential(j) * prod_{u \in N(j)\i){m_uj}
      Vj.set(potentials.belStates[xj]);
      for(int xu=0; xu<nbNodes; xu++ ) {
        if( !adjMat(xu,xj) || xu==xi ) continue;
        msg_idx = (xu>xj) ? adjMatMax+adjMat(xu,xj)-1 : adjMat(xu,xj)-1;
        Vj.add(messages[msg_idx]);
      }
      
      // potential(i,j) * Vi*Vj*Mij
      Mij.create( Vj.getLength(), Vi.getLength() );
      logMultiply(Vi,Vj,Mij);
      Mij.add(potentials.belEdges[adjMat(xi,xj)-1]);
      beliefs.belEdges[adjMat(xi,xj)-1].set(Mij);
    }
  }
  
  // Normalize beliefs and compute partition
  double logZ = 0;
  beliefs.partition = 0;
  for(unsigned int i=0; i<beliefs.belStates.size(); i++) {
    logZ = beliefs.belStates[i].logSumExp();
    beliefs.belStates[i].add(-logZ);
    beliefs.belStates[i].eltExp();
    beliefs.partition += logZ;
  }
  for(unsigned int i=0; i<beliefs.belEdges.size(); i++) {
    logZ = beliefs.belEdges[i].logSumExp();
    beliefs.belEdges[i].add(-logZ);
    beliefs.belEdges[i].eltExp();
    beliefs.partition += logZ;
  }
}