栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

SVM训练(C++实现)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SVM训练(C++实现)

在很多文献中,都把HOG和SVM结合起来使用,可以得到很不错的分类效果,SVM就不用再复习啦,就是一个线性分类器,给一个简单的图就能很好理解,

对于有标签的正样本和负样本,如果只有两个维度,也就是只有两个特征,要做的就是找到一条线,能够很好的划分为两个区域分别包含正负样本,并且这条线尽可能远离两个样本中心

(摘自上课的PPT)

但是这是针对二维的情况,如果扩展到多维,可能就无法找到一条线,即使找到了也可能有很多样本发生了错分,所以就需要在更高维度上考虑,高斯是最常用的。

目前我是打算将23维图像降为1维,空间信息损失实在太多啦,但是也想看看效果,就跑了跑。


一、代码及解释
	//使用SVM分类器训练  
    //设置参数的方式1
    Ptr svm = SVM::create();
    svm->setKernel(SVM::RBF);
    svm->setType(SVM::C_SVC);
    svm->setC(10);
    svm->setCoef0(1.0);
    svm->setP(1.0);
    svm->setNu(0.5);
    svm->setTermCriteria(TermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON));

    //使用SVM学习     
    //    
    svm->train(featureVectorOfSample, ROW_SAMPLE, classOfSample);

    //保存分类器
    svm->save("Classifier.xml");
    cout<<"//-------------开始训练-------//" < svm = cv::ml::SVM::create();
    svm->setType(cv::ml::SVM::C_SVC);
    svm->setKernel(cv::ml::SVM::LINEAR);//注意必须使用线性SVM进行训练,因为HogDescriptor检测函数只支持线性检测!!!
    svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 10, FLT_EPSILON)); //迭代终止条件

    //使用SVM学习
    svm->train(samFeatureMat,cv::ml::ROW_SAMPLE, samLabelMat);

    //保存分类器(里面包括了SVM的参数,支持向量,α和rho)
    svm->save("Classifier.xml");
    end = clock();
    cout << "The obtain hog feature run time is :" << (double)(end - start) / CLOCKS_PER_SEC << "s" << endl;

    
    //获取支持向量机:矩阵默认是CV_32F
    Mat supportVector = svm->getSupportVectors();//

    //获取alpha和rho
    Mat alpha;//每个支持向量对应的参数α(拉格朗日乘子),默认alpha是float64的
    Mat svIndex;//支持向量所在的索引
    float rho = svm->getDecisionFunction(0, alpha, svIndex);

    //转换类型:这里一定要注意,需要转换为32的
    Mat alpha2;
    alpha.convertTo(alpha2, CV_32FC1);

    //结果矩阵,两个矩阵相乘
    Mat result(1, 3780, CV_32FC1);
    result = alpha2*supportVector;

    //乘以-1,这里为什么会乘以-1?
    //注意因为svm.predict使用的是alpha*sv*another-rho,如果为负的话则认为是正样本,在HOG的检测函数中,使用rho+alpha*sv*another(another为-1)
    for (int i = 0; i < 3780; ++i)
    result.at(0, i) *= -1;

    //将分类器保存到文件,便于HOG识别
    //这个才是真正的判别函数的参数(ω),HOG可以直接使用该参数进行识别
    FILE *fp = fopen("HOG_SVM.txt", "wb");
    for (int i = 0; i<3780; i++)
    {
     fprintf(fp, "%f n", result.at(0,i));
    }
    fprintf(fp, "%f", rho);
    fclose(fp);

    cout <<"真正参数得到啦"<< endl;
二、总结

如果要使用SVM进行训练的话,可能需要GPU,又或者是我维度太高了,想要二分类比较困难,这还是一个问题,等后面来解决!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/938526.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号