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; } }