关闭

cvTrimWeights函数详细解读

标签: cvTrimWeightsopencv源码分析Adaboost
560人阅读 评论(0) 收藏 举报
分类:

cvTrimWeights的源码在opencv的cvboost.cpp文件之中,具体内容和部分注释如下所

/*
 *cvTrimWeights
 *作用:对小于一定阈值的权重剔除,因为权重较小的样本对训练结果影响很小,剔除后,这样在训练样本时可以缩短训练时间
 */
CV_BOOST_IMPL
CvMat* cvTrimWeights( CvMat* weights,//训练样本的权重矩阵
                      CvMat* idx,    //训练样本的索引序列矩阵
                      float factor ) //剔除小权重的样本后剩余样本的比例,根据这个参数来计算需要剔除较小样本的阈值
{
    CvMat* ptr = 0;

    CV_FUNCNAME( "cvTrimWeights" );
    __BEGIN__;
    int i, index, num;
    float sum_weights;
    uchar* wdata;
    size_t wstep;
    int wnum;
    float threshold;
    int count;
    float* sorted_weights;

    CV_ASSERT( CV_MAT_TYPE( weights->type ) == CV_32FC1 );

    ptr = idx;
    sorted_weights = NULL;

    if( factor > 0.0F && factor < 1.0F )
    {
        size_t data_size;

        CV_MAT2VEC( *weights, wdata, wstep, wnum );
        num = ( idx == NULL ) ? wnum : MAX( idx->rows, idx->cols );

        data_size = num * sizeof( *sorted_weights );
        sorted_weights = (float*) cvAlloc( data_size );
        memset( sorted_weights, 0, data_size );

        sum_weights = 0.0F;
        for( i = 0; i < num; i++ )
        {
            index = icvGetIdxAt( idx, i );//将矩阵idx中第i个位置上的样本序列取出
            sorted_weights[i] = *((float*) (wdata + index * wstep));//取出idx第i个位置上的权重
            sum_weights += sorted_weights[i];//样本的权重和
        }

        icvSort_32f( sorted_weights, num, 0 );//对样本排序

        sum_weights *= (1.0F - factor);      //根据训练样本总的权重和factor来计算需要剔除的小权重训练样本的权重和

        i = -1;
        do { sum_weights -= sorted_weights[++i]; }//对排序后的样本从最小的小权重的样本开始减去,直到while中条件结束
        while( sum_weights > 0.0F && i < (num - 1) );

        threshold = sorted_weights[i];      
       /*跳出do-while循环后,把没有被剔除权重的样本中,最小权重的那个样本的权重赋给threshold。对外表现为:凡是样本的权重小于
        这个阈值,就直接剔除*/

        while( i > 0 && sorted_weights[i-1] == threshold ) i--;//剔除小权重的样本后,再对原来剔除的那部分中等于阈值的样本捡回来,挺人性化的哈

        if( i > 0 || ( idx != NULL && CV_MAT_TYPE( idx->type ) != CV_32FC1 ) )
        {
            CV_CALL( ptr = cvCreateMat( 1, num - i, CV_32FC1 ) );
            count = 0;
            for( i = 0; i < num; i++ )
            {
                index = icvGetIdxAt( idx, i );
                if( *((float*) (wdata + index * wstep)) >= threshold )//只对阈值>threshold的权重操作
                {
                    CV_MAT_ELEM( *ptr, float, 0, count ) = (float) index;
                    count++;
                }
            }

            assert( count == ptr->cols );
        }
        cvFree( &sorted_weights );
    }

    __END__;

    return ptr;     //只返回权重大于阈值的样本
}




0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:125824次
    • 积分:2470
    • 等级:
    • 排名:第15562名
    • 原创:112篇
    • 转载:28篇
    • 译文:5篇
    • 评论:32条
    最新评论