选用神经网络还是支持向量机

来源:互联网 发布:冰点降低数据法 编辑:程序博客网 时间:2024/05/22 03:31

以一个具体的识别问题为例,从音频监控中实时的检测哭声,也就是哭声 vs 其它声音 数据的两类分类问题。


在第一个阶段,以无噪声下哭声 vs 正常人声(语音) 简化分类问题,达到较好效果后,再进一步加大难度,如加入各类声音(喇叭、音乐等)以提高检测性能。


虽然是对音频的处理,但是在提取和构造完音频特征(如MFCC等)之后,可以借助OpenCV里的机器学习功能。


那么,问题就来了,是选用支持向量机算法还是选用人工神经网络呢?


如果是SVM,我们这么做:


CvSVM svm;CvSVMParams param1;param1.svm_type = CvSVM::C_SVC;param1.kernel_type = CvSVM::RBF;param1.C = 1;    param1.gamma = 0.01;param1.term_crit = cvTermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 1000, FLT_EPSILON);// for grid params not in use, set to 0CvParamGrid pGrid = CvParamGrid(1,1,0.0);CvParamGrid nuGrid = CvParamGrid(1,1,0.0);      CvParamGrid coeffGrid = CvParamGrid(1,1,0.0);      CvParamGrid degreeGrid = CvParamGrid(1,1,0.0); /*start to svm trainingfor cry model*/    if ((stricmp(mode, "cry") == 0) && (stricmp(typeML, "svm") == 0)){cout << "开始训练SVM分类器 -- 参数优化中 (.Train_auto)  " << endl;svm.train_auto(sampleFeatureMat,sampleLabelMat,     Mat(),     Mat(),     param1,    10,    svm.get_default_grid(CvSVM::C),    svm.get_default_grid(CvSVM::GAMMA),    pGrid,    nuGrid,    coeffGrid,    degreeGrid); /*    finish svm model    save to xml file    */    cout << "训练完成  " << endl;        svm.save(modelname);//将训练好的SVM模型保存为xml文件}

if(stricmp(typeML, "svm") == 0){result = svm.predict(featureVector, false);            // svm.predict            // 哭声 为正面样本            cout << "SVM predict:  " << result << "  @frame " << i << "        ";}


如果是ANN,我们这么做:

// NN hereif ((stricmp(mode, "cry") == 0) && (stricmp(typeML, "nn") == 0)){cout << "Start Neural Network Learning...   " << endl;CvANN_MLP nn;int x1= 16;int x2= 8;int x3= 2;Mat layerSizes=(Mat_<int>(1,3)<<x1,x2,x3);//nn.create(const Mat& layerSizes, int activateFunc=CvANN_MLP::SIGMOID_SYM, double fparam1=0, double fparam2=0 );nn.create(layerSizes, CvANN_MLP::SIGMOID_SYM, 1,1);CvANN_MLP_TrainParams param;//5000,0.01        param.term_crit=cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,5000,0.001);Mat sampleLabelMatNN;sampleLabelMatNN = Mat::zeros(frame_number_pos + frame_number_neg, 2, CV_32FC1);for (int i=0;i<frame_number_pos;i++){sampleLabelMatNN.at<float>(i, 0)=1; // positivesampleLabelMatNN.at<float>(i, 1)=0; // negative}for (int i=frame_number_pos;i<frame_number_pos + frame_number_neg;i++){sampleLabelMatNN.at<float>(i, 0)=0;sampleLabelMatNN.at<float>(i, 1)=1;}//train(const Mat& inputs, const Mat& outputs, const Mat& sampleWeights, const Mat& sampleIdx=Mat(), CvANN_MLP_TrainParams params=CvANN_MLP_TrainParams(), int flags=0 );nn.train(sampleFeatureMat,sampleLabelMatNN,Mat(),Mat(),param);nn.save(modelname);cout << "Learning Finished!  " << endl;}


if(stricmp(typeML, "nn") == 0){Mat resultMatNN;resultMatNN=Mat::zeros(1, 2, CV_32FC1);nn.predict(featureVector, resultMatNN);float a = resultMatNN.at<float>(0,0);float b = resultMatNN.at<float>(0,1);if (resultMatNN.at<float>(0,0) > resultMatNN.at<float>(0,1) ) result = 1.0;else result = -1.0;            // svm.predict            // 哭声 为正面样本            cout << "Neural Network predict:  " << result << "  @frame " << i << "        ";}


如果要解决这个算法选型的问题,就要明白两种算法的优缺点:


SVM,优点: 最优解,小样本优势,缺点:依赖核函数形式,不能直接用于多类分类

ANN,优点:直接实现多类分类,缺点:理论上不自洽(这意味着什么?),依赖隐层等结构设计,依赖激活函数形式。


除了算法的优缺点外,还需要研究建模对象哭声数据点的分布特性,看哪种算法合适。


一时不知道哪种算法合适,也不知道数据分布特点,因此决定依赖实测性能,从错误样本中分析两种分类器的差异。




0 0