我在尝试使用SVM训练数据时遇到了一个问题。 我从脸部图像中得到了一些不同的区域(一组连通像素),而且眼睛的区域非常相似,所以我想使用Hu时刻进行形状描述,使用SVM进行训练。 但是SVM不能正常工作,方法svm.predict后来评估所有内容为非眼睛,而且标记并在训练阶段用作眼睛的相同区域被评估为非眼睛。 特征数据仅包含7个Hu时刻。我会在这里发布一些源代码示例,提前谢谢:)
其他信息:
输入图片: http://i.stack.imgur.com/GyLO0.png
为1张图片设置基本svm:
int image_regions = 10;
Mat training_mat(image_regions ,7,CV_32FC1); // 7 hu moments
Mat labels(image_regions ,1,CV_32FC1); // for labels 1 (eye) and -1 (non eye)
// computing hu moments
Moments moments2=moments(croppedImage,false);
double hu[7];
HuMoments(moments2,hu);
// putting them into svm traning mat
for (int k=0;k<huCounter;k++)
training_mat.at<float>(counter,k) = hu[k]; // counter is current number of region
if (isEye(...))
{
labels.at<float>(counter,0)=1.0;
}
else
{
labels.at<float>(counter,0)=-1.0;
}
//I use the following:
CvSVM svm;
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 1e-6);
// ... do the above mentioned phase, and then:
svm.train(training_mat, labels, Mat(), Mat(), params);
答案 0 :(得分:2)
我希望以下建议可以帮助你......
最简单的任务是使用聚类算法并尝试将数据聚类为两个类。如果像'k-means'这样的算法能够完成这项工作,那么为什么要使用SVM和神经网络使事情复杂化。我建议你使用这种技术,因为你的特征向量尺寸非常小(7胡时刻)以及你的样本数量。
执行要素标准化(在第4点中指定)以确保值落在有限的范围内。
检查“您的数据是否真的可以分离?”由于您的数据很小,请从正图像中取一些样本,从负图像中取一些样本并绘制特征向量。如果您可以直观地看到差异,那么任何学习算法都可以为您完成工作。正如我之前所说,简单的技巧比复杂的数学更好。
只有当您决定使用SVM时,您才应该知道以下内容:
•正如我从您的代码中看到的那样,您使用的是线性SVM,您的数据可能是线性内核无法分离的。尝试使用一些多项式内核或其他内核。在openCV中有一个选项bool CvSVM :: train_auto只是看看。
•尝试检查您获得的特征向量值是否为正确值(确保它们不是某些垃圾值)。
•在您将其用于培训之前,您还可以执行功能标准化“ZERO MEAN和UNIT VARIENCE”。
•最重要的是增加培训图像的数量,包括正面和负面标记。
•最后但并非最不重要的是SVM并不神奇,在一天结束时它只是在两组点之间画一条线。因此,不要指望它将您提供的任何内容归类为输入。
如果没有任何效果“只需改进您的特征提取技术”