Ejemplo n.º 1
0
float CMlLearningEngine::_LearnPotentials()
{
    int iteration = 1;
    float log_lik = 0.0f;
    CStaticGraphicalModel *grmodel = this->GetStaticModel();
    CFactor *parameter = NULL;
    
    float epsilon = m_precisionIPF;
    const CPotential *joint_prob = NULL;
    CPotential *clique_jpd = NULL;
    
    CMatrix<float> *itogMatrix;
    
    CInfEngine *m_pInfEngine = 
        CNaiveInfEngine::Create(grmodel);
    intVector obsNodes(0);
    valueVector obsValues(0);
    CEvidence *emptyEvidence = CEvidence::Create(grmodel->GetModelDomain(), obsNodes, obsValues);
    m_pInfEngine -> EnterEvidence( emptyEvidence );
    int querySize = grmodel->GetNumberOfNodes();
    int *query;
    query = new int [querySize];

    int i;
    for( i = 0; i < querySize; i++ )
    {
        query[i] = i;
    }
    m_pInfEngine -> MarginalNodes( query, querySize );
    joint_prob = m_pInfEngine->GetQueryJPD();
    CPotential *itog_joint_prob = 
        static_cast<CPotential *>(joint_prob ->Marginalize(query, querySize));
    
    int DomainSize;
    const int *domain;
    
    potsPVector learn_factors;
    CPotential *tmp_factor;
    
    for (i = 0; i <  grmodel -> GetNumberOfFactors(); i++)
    {
        factor = grmodel -> GetFactor(i);
        factor -> GetDomain( &DomainSize, &domain );
        CDistribFun *correspData= factor -> GetDistribFun();
        
        CMatrix<float> *learnMatrix = correspData ->
            GetStatisticalMatrix(stMatTable);
        
        CPotential *factor = CTabularPotential::Create(	domain, DomainSize,
            parameter->GetModelDomain());
        
        learn_factors.push_back(factor);
        learn_factors[i] -> AttachMatrix(learnMatrix->NormalizeAll(), matTable);
    }
    
    int data_length;
    float *old_itog_data = NULL;
    const float *itog_data;
    
    delete [] query;
    int convergence = 0;	
    while( !convergence && (iteration <= m_maxIterIPF))
    {
        iteration++;
        itogMatrix = (itog_joint_prob->GetDistribFun())
            -> GetMatrix(matTable);
        static_cast<CNumericDenseMatrix<float>*>(itogMatrix)->
            GetRawData(&data_length, &itog_data);
        old_itog_data = new float[data_length];
        for( i = 0; i < data_length; i++)
        {
            old_itog_data[i] = itog_data[i];
        }
        for( int clique = 0; clique < grmodel->GetNumberOfFactors(); clique++)
        {
            factor = grmodel -> GetFactor(clique);
            factor -> GetDomain( &DomainSize, &domain );
            clique_jpd = static_cast<CPotential *>
                (itog_joint_prob -> Marginalize( domain, DomainSize ));
            
            
            tmp_factor = itog_joint_prob -> Multiply(learn_factors[clique]);
            delete (itog_joint_prob);
            itog_joint_prob = tmp_factor;
            tmp_factor = itog_joint_prob -> Divide(clique_jpd);
            delete (itog_joint_prob);
            delete (clique_jpd);
            itog_joint_prob = tmp_factor;
            
        }
        itogMatrix = (itog_joint_prob->GetDistribFun())
            -> GetMatrix(matTable);
        
        static_cast<CNumericDenseMatrix<float>*>(itogMatrix)->
            GetRawData(&data_length, &itog_data);
        convergence = true;
        for (int j = 0; j < data_length; j++)
        {
            if( fabs( itog_data[j] - old_itog_data[j] ) > epsilon)
            {
                convergence = false;
                break;
            }
            
        }
        delete []old_itog_data;
    }
    if(iteration > m_maxIterIPF)
    {
        PNL_THROW(CNotConverged, 
            "maximum number of iterations for IPF procedure")
    }
    
    for(int  clique = 0; clique < grmodel -> GetNumberOfFactors(); clique++)
    {
        CMatrix<float> *matrix = NULL;
        factor = grmodel -> GetFactor(clique);
        int DomainSize;
        const int *domain;
        int data_length;
        const float *data;
        factor -> GetDomain( &DomainSize, &domain );
        
        matrix = itog_joint_prob->Marginalize( domain, DomainSize )
            ->GetDistribFun()-> GetMatrix( matTable );
        static_cast<CNumericDenseMatrix<float>*>(matrix)->GetRawData(&data_length, &data);
        CNumericDenseMatrix<float>* matLearn = 
            static_cast<CNumericDenseMatrix<float>*>(
            parameter->GetDistribFun()->GetStatisticalMatrix(stMatTable));
        for(int offset = 0; offset < data_length; offset++)
        {
            float prob = float( ( data[offset] < FLT_EPSILON ) ? -FLT_MAX : log( data[offset] ) );
            
            log_lik += matLearn->GetElementByOffset(offset)*prob - 
                m_Vector_pEvidences.size();
        }
        factor ->AttachMatrix(matrix, matTable);
        delete (learn_factors[clique]);
    }
    delete (itog_joint_prob);
    learn_factors.clear();
    
    return log_lik;
}