您的位置:首页 > 理论基础 > 计算机网络

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

2015-07-18 17:58 573 查看
以一个具体的识别问题为例,从音频监控中实时的检测哭声,也就是哭声 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 0
CvParamGrid 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 training
for 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 here
if ((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; // positive
sampleLabelMatNN.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,优点:直接实现多类分类,缺点:理论上不自洽(这意味着什么?),依赖隐层等结构设计,依赖激活函数形式。

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

一时不知道哪种算法合适,也不知道数据分布特点,因此决定依赖实测性能,从错误样本中分析两种分类器的差异。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: