Exemple #1
0
int main (int argc, char* argv[])
{

    cout << endl;
    cout << "       " << "DIFFERENT NODE TYPES EXAMPLE";
    cout << endl << endl;



/*------------------------------------------------------------------------------
 *
 *                         PREPARE TRAINING DATA
 *
 *----------------------------------------------------------------------------*/

    //
    // 1. Generate the node and edge types
    //   

    size_t N_classes_type_1        = 2;
    size_t N_nodeFeatures_type_1   = 3;
    size_t N_edgeFeatures_type_1   = 3;

    size_t N_classes_type_2        = 3;
    size_t N_nodeFeatures_type_2   = 2;
    size_t N_edgeFeatures_type_2   = 2;

    // PERSONS

    CNodeTypePtr simpleNodeType1Ptr( new CNodeType(N_classes_type_1,
                                                   N_nodeFeatures_type_1,
                                                   string("Persons") ) );

    CEdgeTypePtr simpleEdgeType1Ptr ( new CEdgeType(N_edgeFeatures_type_1,
                                                    simpleNodeType1Ptr,
                                                    simpleNodeType1Ptr,
                                                    string("Edges between two persons")) );

    // ROOMS

    CNodeTypePtr simpleNodeType2Ptr( new CNodeType(N_classes_type_2,
                                                   N_nodeFeatures_type_2,
                                                   string("Rooms") ) );

    CEdgeTypePtr simpleEdgeType2Ptr ( new CEdgeType(N_edgeFeatures_type_2,
                                                    simpleNodeType1Ptr,
                                                    simpleNodeType2Ptr,
                                                    "Edges between a person and a room") );

    // Add the node and edge types to the trainingDataset

    CTrainingDataSet trainingDataset;

    // Since the edge between a room and a person is asymetric and probably with
    // a different number of classes, we need to especify that.

    Eigen::VectorXi typeOfEdgeFeatures( N_edgeFeatures_type_2 );
    typeOfEdgeFeatures << 1,1;

    trainingDataset.addNodeType( simpleNodeType1Ptr );
    trainingDataset.addEdgeType( simpleEdgeType1Ptr );
    trainingDataset.addNodeType( simpleNodeType2Ptr );
    trainingDataset.addEdgeType( simpleEdgeType2Ptr, typeOfEdgeFeatures );

    //
    // 2. Create some scenarios with nodes and edges and add them to the
    //    training dataset.
    //

/*--------------------------------- Graph 1 ----------------------------------*/


    CGraph graph;
    std::map<size_t,size_t> groundTruth;

    Eigen::VectorXd nodeFeatures1(3);
    nodeFeatures1 << 15, 30, 1;

    Eigen::VectorXd nodeFeatures2(2);
    nodeFeatures2 << 10, 1;

    Eigen::VectorXd edgeFeatures1(2);
    edgeFeatures1 << 1.5, 1;

    CNodePtr nodePtr2 ( new CNode( simpleNodeType2Ptr,
                                   nodeFeatures2,
                                   string("room-1") ) );

    CNodePtr nodePtr1 ( new CNode( simpleNodeType1Ptr,
                                   nodeFeatures1,
                                   string("object-1") ) );

    CEdgePtr edgePtr1 ( new CEdge( nodePtr2, nodePtr1,
                                   simpleEdgeType2Ptr,
                                   edgeFeatures1 ) ) ;

    graph.addNode( nodePtr1 );
    graph.addNode( nodePtr2 );

    graph.addEdge( edgePtr1 );

    groundTruth[ nodePtr1->getID() ] = 0;
    groundTruth[ nodePtr2->getID() ] = 0;

    trainingDataset.addGraph( graph );
    trainingDataset.addGraphGroundTruth( groundTruth );


/*--------------------------------- Graph 2 ----------------------------------*/


    CGraph graph2;
    std::map<size_t,size_t> groundTruth2;

    Eigen::VectorXd nodeFeatures12(3);
    nodeFeatures12 << 100, 70, 1;

    Eigen::VectorXd nodeFeatures22(2);
    nodeFeatures22 << 30, 1;

    Eigen::VectorXd edgeFeatures12(2);
    edgeFeatures12 << 3.33, 1;

    CNodePtr nodePtr12 ( new CNode( simpleNodeType1Ptr,
                                    nodeFeatures12 ) );

    CNodePtr nodePtr22 ( new CNode( simpleNodeType2Ptr,
                                    nodeFeatures22 ) );

    CEdgePtr edgePtr12 ( new CEdge( nodePtr12,
                                    nodePtr22,
                                    simpleEdgeType2Ptr,
                                    edgeFeatures12 ) );

    graph2.addNode( nodePtr12 );
    graph2.addNode( nodePtr22 );

    graph2.addEdge( edgePtr12 );

    groundTruth2[ nodePtr12->getID() ] = 1;
    groundTruth2[ nodePtr22->getID() ] = 1;

    trainingDataset.addGraph( graph2 );
    trainingDataset.addGraphGroundTruth( groundTruth2 );


/*--------------------------------- Graph 3 ----------------------------------*/


    CGraph graph3;
    std::map<size_t,size_t> groundTruth3;

    Eigen::VectorXd nodeFeatures13(3);
    nodeFeatures13 << 16, 28, 1;

    Eigen::VectorXd nodeFeatures23(3);
    nodeFeatures23 << 95, 72, 1;

    Eigen::VectorXd edgeFeatures13(3);
    edgeFeatures13 << 69, 44, 1;

    CNodePtr nodePtr13 ( new CNode( simpleNodeType1Ptr,
                                    nodeFeatures13 ) );

    CNodePtr nodePtr23 ( new CNode( simpleNodeType1Ptr,
                                    nodeFeatures23 ) );

    CEdgePtr edgePtr13 ( new CEdge( nodePtr13,
                                    nodePtr23,
                                    simpleEdgeType1Ptr,
                                    edgeFeatures13 ) );

    graph3.addNode( nodePtr13 );
    graph3.addNode( nodePtr23 );

    graph3.addEdge( edgePtr13 );

    groundTruth3[ nodePtr13->getID() ] = 0;
    groundTruth3[ nodePtr23->getID() ] = 1;

    trainingDataset.addGraph( graph3 );
    trainingDataset.addGraphGroundTruth( groundTruth3 );


/*------------------------------------------------------------------------------
 *
 *                               TRAINING!
 *
 *----------------------------------------------------------------------------*/

    //
    // 3.  Train a PGM with that scenarios.
    //

    cout << "---------------------------------------------------" << endl;
    cout << "                    Training" << endl;
    cout << "---------------------------------------------------" << endl;

    UPGMpp::TTrainingOptions to;
    to.l2Regularization     = true;
    to.nodeLambda           = 10;
    to.edgeLambda           = 1;
    to.showTrainedWeights   = false;
    to.showTrainingProgress = false;

    trainingDataset.setTrainingOptions( to );
    trainingDataset.train();


/*------------------------------------------------------------------------------
 *
 *                                TESTING!
 *
 *----------------------------------------------------------------------------*/

    //
    // 4. Perform a MAP inference (decoding) to check that the system performance.
    //

    //
    // Build a graph to test the trained model
    //

    CGraph graph4;
    std::map<size_t,size_t> groundTruth4;

    Eigen::VectorXd nodeFeatures14(3);
    nodeFeatures14 << 17, 35, 1;

    Eigen::VectorXd nodeFeatures24(2);
    nodeFeatures24 << 12, 1;

    Eigen::VectorXd edgeFeatures14(2);
    edgeFeatures14 << 1.41, 1;

    CNodePtr nodePtr14 ( new CNode( simpleNodeType1Ptr,
                                    nodeFeatures14 ) );

    CNodePtr nodePtr24 ( new CNode( simpleNodeType2Ptr,
                                    nodeFeatures24 ) );


    CEdgePtr edgePtr14 ( new CEdge( nodePtr14,
                                    nodePtr24,
                                    simpleEdgeType2Ptr,
                                    edgeFeatures14 ) );

    graph4.addNode( nodePtr14 );
    graph4.addNode( nodePtr24 );

    graph4.addEdge( edgePtr14 );

    groundTruth4[ nodePtr14->getID() ] = 0;
    groundTruth4[ nodePtr24->getID() ] = 0;

    graph4.computePotentials();    

    //
    // Now compute the MAP decoding and show the results
    //

    CICMInferenceMAP          decodeICM;

    TInferenceOptions options;
    options.maxIterations   = 100;
    options.convergency     = 0.0001;

    cout << "---------------------------------------------------" << endl;
    cout << "                  ICM decoding"<< endl;
    cout << "---------------------------------------------------" << endl;

    std::map<size_t,size_t> resultsMap;

    decodeICM.setOptions( options );
    decodeICM.infer( graph4, resultsMap );

    std::map<size_t,size_t>::iterator it;

    for ( it = resultsMap.begin(); it != resultsMap.end(); it++ )
    {
        std::cout << "Node id " << it->first << " labeled as " << it->second <<
                     " being of class " << groundTruth4[it->first] << std::endl;
    }

    cout << "---------------------------------------------------" << endl;

    // We are ready to do some sport :)

    return 1;
}
Exemple #2
0
void fillGraph( CGraph &graph,
                const Eigen::MatrixXd &graph_nodeFeatures,
                CNodeTypePtr nodeType,
                const Eigen::MatrixXi &graph_adj,
                CEdgeTypePtr edgeType,
                vector<Eigen::MatrixXi> &g1_relations,
                const Eigen::VectorXi &g1_groundTruth,
                std::map<size_t,size_t> &groundTruth // returned GT taking into account the node IDs
              )
{


    // 1. Add nodes to the graph
    // 2. Add edges

    size_t n_nodes = graph_nodeFeatures.rows();
    size_t n_features = graph_nodeFeatures.cols();

    vector<CNodePtr> nodes;

    //
    // ADD NODES
    //

    for ( size_t i = 0; i < n_nodes; i++ )
    {
        Eigen::VectorXd node_feat(n_features);
        node_feat = graph_nodeFeatures.row(i);

        Eigen::VectorXd multipliers(5);
        multipliers << 90, 100, 50, 40, 50;
        //multipliers << 50, 60, 50, 50, 50;
        //node_feat = node_feat.cwiseProduct( multipliers );

        CNodePtr nodePtr ( new CNode( nodeType, node_feat ) );
        nodes.push_back( nodePtr );

        graph.addNode( nodePtr );

        groundTruth[ nodePtr->getID() ] = g1_groundTruth(i);

    }   

    //
    // ADD EDGES
    //

    for ( size_t row = 0; row < n_nodes; row++ )
    {
        for ( size_t col = row; col < n_nodes; col++ )
        {
            if ( graph_adj(row,col) == 1 )
            {
                // Retrieve the nodes linked by the edge and their features
                CNodePtr node1 = nodes.at(row);
                CNodePtr node2 = nodes.at(col);

                Eigen::VectorXd &feat1 = node1->getFeatures();
                Eigen::VectorXd &feat2 = node2->getFeatures();

                // Compute edge features
                Eigen::VectorXd edgeFeatures( edgeType->getWeights().size());

                // Perpendicularity

                edgeFeatures(0) = (std::abs(feat1(0) - feat2(0))==0) ? 0 : 1;

                // Height distance between centers
                edgeFeatures(1) = std::abs((float)feat1(1) - (float)feat2(1));

                // Ratio between areas
                float a1 = feat1(2);
                float a2 = feat2(2);

                if ( a1 < a2 )
                {
                    float aux = a2;
                    a2 = a1;
                    a1 = aux;
                }

                //edgeFeatures(2) = a1 / a2;

                //  Difference between elongations
                //edgeFeatures(3) = std::abs(feat1(3) - feat2(3));

                // Use the isOn semantic relation
                //edgeFeatures(4) = (g1_relations[0])(row,col);
                edgeFeatures(2) = (g1_relations[0])(row,col);

                // Coplanar semantic relation
                //edgeFeatures(5) = (g1_relations[1])(row,col);

                // Bias feature
                //edgeFeatures(6) = 1;
                edgeFeatures(3) = 1;

                //Eigen::VectorXd multipliers(7);
                //multipliers << 0, 0, 0, 0, 0, 0, 1;
                //multipliers << 0, 0, 0, 0, 0, 0, 0;

                Eigen::VectorXd multipliers(4);
                multipliers << 1, 1, 10, 1;

                //edgeFeatures = edgeFeatures.cwiseProduct( multipliers );

                CEdgePtr edgePtr ( new CEdge( node1, node2,
                                            edgeType, edgeFeatures ) );
                graph.addEdge( edgePtr );
            }
        }
    }

}
Exemple #3
0
        /** Method for getting a bound graph from the one stored into the object.
          * \param boundGraph: resulting graph, it must be empty when the method
          * is called.
          * \param nodesToBound: a map containing as key the id of a node, and
          * as value the class/state to be bound.
          */
        void getBoundGraph( CGraph &boundGraph,
                            std::map<size_t,size_t> nodesToBound )
        {
            // Check that the graph is empty
            assert( boundGraph.getNodes().size() == 0 );

            // Copy the graph into boundGraph

            // Copy nodes
            for ( size_t node = 0; node < m_nodes.size(); node++ )
            {
                CNodePtr nodePtr(new CNode(*m_nodes[node]));
                boundGraph.addNode( nodePtr );
            }

            // Copy edges
            for ( size_t edge = 0; edge < m_edges.size(); edge++ )
            {
                CEdgePtr edgePtr( new CEdge(*m_edges[edge]));
                boundGraph.addEdge( edgePtr );
            }

            // Okey, now iterate over the nodes to be bound, removing then from
            // the resulting graph by expanding the potential associated with
            // their bound state
            for ( std::map<size_t,size_t>::iterator it = nodesToBound.begin();
                  it != nodesToBound.end();
                  it++ )
            {
                size_t nodeID = it->first;
                size_t nodeState = it->second;

                // Potential of the state to be bounded
                double nodePotential = boundGraph.getNodeWithID( nodeID )->getPotentials()( nodeState );

                // Iterate over the neighbours, updating their node potentials
                // according to the state of the node to be bound and its potential

                pair<multimap<size_t,CEdgePtr>::iterator,multimap<size_t,CEdgePtr>::iterator > neighbors;

                neighbors = boundGraph.getEdgesF().equal_range(nodeID);

                for ( multimap<size_t,CEdgePtr>::iterator it = neighbors.first;
                      it != neighbors.second;
                      it++ )
                {
                    CEdgePtr edgePtr( (*it).second );
                    Eigen::MatrixXd edgePotentials = edgePtr->getPotentials();

                    size_t ID1, ID2;
                    edgePtr->getNodesID(ID1,ID2);

                    // If the node to be bound is the first one appearing in the
                    // edge.
                    if ( ID1 == nodeID )
                    {
                        CNodePtr nodePtr                = boundGraph.getNodeWithID( ID2 );
                        Eigen::VectorXd boundPotentials = edgePotentials.row(nodeState).transpose()*nodePotential;
                        Eigen::VectorXd newPotentials   = nodePtr->getPotentials().cwiseProduct(boundPotentials);
                        nodePtr->setPotentials( newPotentials );
                    }
                    else    // If it is the second one in the edge
                    {
                        CNodePtr nodePtr                = boundGraph.getNodeWithID( ID1 );
                        Eigen::VectorXd boundPotentials = edgePotentials.col( nodeState )*nodePotential;
                        Eigen::VectorXd newPotentials   = nodePtr->getPotentials().cwiseProduct(boundPotentials);
                        nodePtr->setPotentials( newPotentials );
                    }
                }

                // Now that the potential of the state of the node to bound
                // has been expanded, delete the node from the graph.
                boundGraph.deleteNode( nodeID );
            }
        }