支持向量机学习笔记:LIBSVM应用(人脸识别)
2014-01-15 23:06
603 查看
如果你已经看完并理解了我的上一篇SVM的博客,那么接下来你要面对的是怎么应用SVM这个实际的问题,现在SVM里面应用最广泛的就是LIBSVM这个函数库,OpenCV中也基于LIBSVM推出了CvSVM 的函数。因此下面的内容,我主要是介绍一下LIBSVM的应用方法,主要是参考文献[1,2]。
LIBSVM是国立台湾大学 Chih-Jen Lin开发的一个SVM的函数库,他不但提供了编译好的可在Windows系列系统的执行文件,还提供了源代码,方便改进、修改以及在其它操作系统上应用;该软件对SVM所涉及的参数调节相对比较少,提供了很多的默认参数,利用这些默认参数可以解决很多问题;并提供了交互检验(Cross Validation)的功能。该软件包可在http://www.csie.ntu.edu.tw/~cjlin/免费获得。该软件可以解决C-SVM、ν-SVM、ε-SVR和ν-SVR等问题,包括基于一对一算法的多类模式识别问题。
上一篇博客中谈的内容是从理论出发的东西,但是在实际应用中,我们常常无法找到一个完美无缺的判别超平面,那么为了能够在这样子的不可分的集合中学习支持向量机,需要引入软间隔(soft margin)来进行分类,即是允许一些训练模式停留在判别超平面的“错误”一侧,或者说允许其他类的模式停留在间隔内,则上一篇博客中的公式(3)修改为:
其中
为松弛变量,对应数据点偏离对应的间隔面(非分类超平面)的距离(见图1)。因此,最终的结果是margin可以比1小,但是当某些点出现这种margin比1小的情况时(这些点也称离散点),意味着我们放弃啦对这些点的精确分类,而这对分类器来说是一种损失,但是放弃这些点也带来了好处,就是分类面不必向这些点的方向移动,因而可以得到更大的几何margin。显然,我们必须权衡这种损失和好处。好处是明显的,我们得到的分类间隔越大,好处就越多。
图1 松弛变量
下面还有几点需要注意:
并非所有的样本点都有一个松弛变量与其对应。实际上只有“离群点”才有,或者也可以这么看,所有没离群的点松弛变量都等于0(对负类来说,离群点就是在前面图中,跑到H2右侧的那些负样本点,对正类来说,就是跑到H1左侧的那些正样本点)。
松弛变量的值实际上标示出了对应的点到底离群有多远,值越大,点就越远。
惩罚因子C决定了你有多重视离群点带来的损失,显然当所有离群点的松弛变量的和一定时,你定的C越大,对目标函数的损失也越大,此时就暗示着你非常不愿意放弃这些离群点,最极端的情况是你把C定为无限大,这样只要稍有一个点离群,目标函数的值马上变成无限大,马上让问题变成无解,这就退化成了硬间隔问题。
惩罚因子C不是一个变量,整个优化问题在解的时候,C是一个你必须事先指定的值,指定这个值以后,解一下,得到一个分类器,然后用测试数据看看结果怎么样,如果不够好,换一个C的值,再解一次优化问题,得到另一个分类器,再看看效果,如此就是一个参数寻优的过程,但这和优化问题本身决不是一回事,优化问题在解的过程中,C一直是定值,要记住。
尽管加了松弛变量这么一说,但这个优化问题仍然是一个优化问题(汗,这不废话么),解它的过程比起原始的硬间隔问题来说,没有任何更加特殊的地方。
现在,我们来看看在实际应用中的C-SVM:
文献[1]中推荐的SVM使用步骤如下:
【将数据变换成SVM格式】Transform data to the format of an SVM package
【数据规范化(scale)】Conduct simple scaling on the data
【考虑使用RBF核】Consider the RBF Kernel
【使用交叉验证获取最优参数C和Gamma】Use Corss-validation to find the best parameter C and Gamma
【使用最优参数来训练整个训练集】Use the best parameter C and Gamma to train the whole training set
【新来数据的测试】Test
描述如下:
Data Preprocessing
Categorical Feature
SVM要求数据实例是实数向量,因此,我们必须先把它的类别特征转换成数值特征。这里推荐使用m个值去代表m类的特征。例如,一个三类特征{red,green,blue}可以表示成(0,0,1)(0,1,0)(1,0,0)。经验表明,当类别不是非常大时,这种特征类别编码方式更稳定
Scaling
Scaling在SVM中非常重要,这里推荐使用linearly scaling each attribute to the range [-1,+1] or [0,1]。
Model Selection
RBF Kernel
一般情况下,RBF Kernel 是一个合理的第一选择,可以首先尝试这个核函数。
Cross-validation and Grid-search
RBF核函数有两个参数:C和Gamma。针对一个给定的问题,需要通过参数搜索方法来获取他们的最优值。一个常用的方法是将训练数据分成2个部分,其中一部分为“未知的”,通过对未知数据的分类效果来反映系统分类性能。该方法的一个提升版本就是Cross-validation交叉验证。在v-fold交叉验证中,我们首先将数据分成v组,将每个子集分别做一次测试集,其余v-1组作为训练集,这样就会得到v个模型,用这v个模型最终的测试集的分类准确率作为v-fold
cross-validation分类性能的指标。这里我们推荐使用“grid-search”,即尝试各个参数对(C,gamma),我们发现使用指数增长能更快找到最佳参数值。如
C = 2^(-5) 2^(-3) .... 2^15
gamma = 2^(-15) 2^(-13) ... 2^3
————————————————————————————————————————————————————————————
下面,我贴一个用SVM进行人脸识别的例子(效果很不好,特征和参数没细调)
参考文献
[1] Hsu C W, Chang C C, Lin C J. A practical guide to support vector classification[J]. 2003.
[2] Chang C C, Lin C J. LIBSVM: a library for support vector machines[J]. ACM Transactions on Intelligent Systems and Technology (TIST), 2011, 2(3): 27.
LIBSVM是国立台湾大学 Chih-Jen Lin开发的一个SVM的函数库,他不但提供了编译好的可在Windows系列系统的执行文件,还提供了源代码,方便改进、修改以及在其它操作系统上应用;该软件对SVM所涉及的参数调节相对比较少,提供了很多的默认参数,利用这些默认参数可以解决很多问题;并提供了交互检验(Cross Validation)的功能。该软件包可在http://www.csie.ntu.edu.tw/~cjlin/免费获得。该软件可以解决C-SVM、ν-SVM、ε-SVR和ν-SVR等问题,包括基于一对一算法的多类模式识别问题。
上一篇博客中谈的内容是从理论出发的东西,但是在实际应用中,我们常常无法找到一个完美无缺的判别超平面,那么为了能够在这样子的不可分的集合中学习支持向量机,需要引入软间隔(soft margin)来进行分类,即是允许一些训练模式停留在判别超平面的“错误”一侧,或者说允许其他类的模式停留在间隔内,则上一篇博客中的公式(3)修改为:
其中
为松弛变量,对应数据点偏离对应的间隔面(非分类超平面)的距离(见图1)。因此,最终的结果是margin可以比1小,但是当某些点出现这种margin比1小的情况时(这些点也称离散点),意味着我们放弃啦对这些点的精确分类,而这对分类器来说是一种损失,但是放弃这些点也带来了好处,就是分类面不必向这些点的方向移动,因而可以得到更大的几何margin。显然,我们必须权衡这种损失和好处。好处是明显的,我们得到的分类间隔越大,好处就越多。
图1 松弛变量
下面还有几点需要注意:
并非所有的样本点都有一个松弛变量与其对应。实际上只有“离群点”才有,或者也可以这么看,所有没离群的点松弛变量都等于0(对负类来说,离群点就是在前面图中,跑到H2右侧的那些负样本点,对正类来说,就是跑到H1左侧的那些正样本点)。
松弛变量的值实际上标示出了对应的点到底离群有多远,值越大,点就越远。
惩罚因子C决定了你有多重视离群点带来的损失,显然当所有离群点的松弛变量的和一定时,你定的C越大,对目标函数的损失也越大,此时就暗示着你非常不愿意放弃这些离群点,最极端的情况是你把C定为无限大,这样只要稍有一个点离群,目标函数的值马上变成无限大,马上让问题变成无解,这就退化成了硬间隔问题。
惩罚因子C不是一个变量,整个优化问题在解的时候,C是一个你必须事先指定的值,指定这个值以后,解一下,得到一个分类器,然后用测试数据看看结果怎么样,如果不够好,换一个C的值,再解一次优化问题,得到另一个分类器,再看看效果,如此就是一个参数寻优的过程,但这和优化问题本身决不是一回事,优化问题在解的过程中,C一直是定值,要记住。
尽管加了松弛变量这么一说,但这个优化问题仍然是一个优化问题(汗,这不废话么),解它的过程比起原始的硬间隔问题来说,没有任何更加特殊的地方。
现在,我们来看看在实际应用中的C-SVM:
文献[1]中推荐的SVM使用步骤如下:
【将数据变换成SVM格式】Transform data to the format of an SVM package
【数据规范化(scale)】Conduct simple scaling on the data
【考虑使用RBF核】Consider the RBF Kernel
【使用交叉验证获取最优参数C和Gamma】Use Corss-validation to find the best parameter C and Gamma
【使用最优参数来训练整个训练集】Use the best parameter C and Gamma to train the whole training set
【新来数据的测试】Test
描述如下:
Data Preprocessing
Categorical Feature
SVM要求数据实例是实数向量,因此,我们必须先把它的类别特征转换成数值特征。这里推荐使用m个值去代表m类的特征。例如,一个三类特征{red,green,blue}可以表示成(0,0,1)(0,1,0)(1,0,0)。经验表明,当类别不是非常大时,这种特征类别编码方式更稳定
Scaling
Scaling在SVM中非常重要,这里推荐使用linearly scaling each attribute to the range [-1,+1] or [0,1]。
Model Selection
RBF Kernel
一般情况下,RBF Kernel 是一个合理的第一选择,可以首先尝试这个核函数。
Cross-validation and Grid-search
RBF核函数有两个参数:C和Gamma。针对一个给定的问题,需要通过参数搜索方法来获取他们的最优值。一个常用的方法是将训练数据分成2个部分,其中一部分为“未知的”,通过对未知数据的分类效果来反映系统分类性能。该方法的一个提升版本就是Cross-validation交叉验证。在v-fold交叉验证中,我们首先将数据分成v组,将每个子集分别做一次测试集,其余v-1组作为训练集,这样就会得到v个模型,用这v个模型最终的测试集的分类准确率作为v-fold
cross-validation分类性能的指标。这里我们推荐使用“grid-search”,即尝试各个参数对(C,gamma),我们发现使用指数增长能更快找到最佳参数值。如
C = 2^(-5) 2^(-3) .... 2^15
gamma = 2^(-15) 2^(-13) ... 2^3
————————————————————————————————————————————————————————————
下面,我贴一个用SVM进行人脸识别的例子(效果很不好,特征和参数没细调)
close all; clc; clear; num = 25; M = 112;N = 92;accu = 0; suma = zeros(28,28); Gt = zeros(28,28); for ii = 1:1:num for k = 1:9 name1 = strcat('s',num2str(ii)); name2 = strcat(name1,'\'); name3 = strcat(num2str(k),'.bmp'); name4 = strcat(name2,name3); name = strcat('E:\快盘\文献阅读\DATAbase\ORLFACE\',name4); I = imread(name); if ndims(I)==3 I = rgb2gray(I); end I_re = imresize(I,[112 112]); temp = double(I_re(1:4:112,1:4:112)); suma = suma+temp; end end aver_A = suma/(num*9); for ii = 1:1:num for k =1:9 name1 = strcat('s',num2str(ii)); name2 = strcat(name1,'\'); name3 = strcat(num2str(k),'.bmp'); name4 = strcat(name2,name3); name = strcat('E:\快盘\文献阅读\DATAbase\ORLFACE\',name4); I=imread(name); if ndims(I)==3 I = rgb2gray(I); end I_re = imresize(I,[112 112]); temp = double(I_re(1:4:112,1:4:112)); Gt = Gt+(temp-aver_A)'*(temp-aver_A); end end Gt = Gt/(num*9); [v,d] = eigs(Gt,25); [eigenvalues, index] = sort(diag(d),'descend'); ratio = cumsum(eigenvalues)/sum(eigenvalues); xnum = find(ratio>.98); D_num = xnum(1); index_select = index(1:D_num); V_select = zeros(size(v,1),D_num); V_select(:,1:D_num) = v(:,index_select(1:D_num)); i_oo=1; for ii = 1:1:num for k = 1:9 name1 = strcat('s',num2str(ii)); name2 = strcat(name1,'\'); name3 = strcat(num2str(k),'.bmp'); name4 = strcat(name2,name3); name = strcat('E:\快盘\文献阅读\DATAbase\ORLFACE\',name4); I = imread(name); if ndims(I)==3 I = rgb2gray(I); end I_re = imresize(I,[112 112]); temp = double(I_re(1:4:112,1:4:112)); temp2 = temp*V_select; Y_matrix(i_oo,:) = reshape(temp2,1,588); i_oo=i_oo+1; end end t_label=[]; for ii = 1:1:num for jj = 1:9 t_label =[t_label,ii]; Y_label = t_label'; end end %% 现在准备开始建立model,为predict做准备 model = svmtrain(Y_label,Y_matrix); %% 测试部分 for ii = 1:1:num k = 10; name1 = strcat('s',num2str(ii)); name2 = strcat(name1,'\'); name3 = strcat(num2str(k),'.bmp'); name4 = strcat(name2,name3); name = strcat('E:\快盘\文献阅读\DATAbase\ORLFACE\',name4); I = imread(name); if ndims(I)==3 I = rgb2gray(I); end I_re = imresize(I,[112 112]); temp = double(I_re(1:4:112,1:4:112)); tempY = temp*V_select; X_test(ii,:) = reshape(tempY,1,588); end label_temp = [1:num];X_label=label_temp'; [predict_label, accuracy, dec_values] = svmpredict(X_label,X_test,model);
参考文献
[1] Hsu C W, Chang C C, Lin C J. A practical guide to support vector classification[J]. 2003.
[2] Chang C C, Lin C J. LIBSVM: a library for support vector machines[J]. ACM Transactions on Intelligent Systems and Technology (TIST), 2011, 2(3): 27.
相关文章推荐
- 吴恩达Coursera深度学习课程 DeepLearning.ai 提炼笔记(4-4)-- 特殊应用:人脸识别和神经风格迁移
- 吴恩达Coursera深度学习课程 DeepLearning.ai 提炼笔记(4-4)-- 特殊应用:人脸识别和神经风格迁移
- 2011斯坦福大学iOS应用开发教程学习笔记(第五课)Protocols,手势识别
- 支持向量机(SVM)算法在人脸识别上的应用
- 吴恩达深度学习笔记五:卷积神经网络 人脸识别和风格迁移部分
- 斯坦福大学公开课 iOS应用开发教程学习笔记(第五课)Protocols,手势识别
- 第12节--支持向量机(SVM)算法在人脸识别上的应用
- OpenCV Python 学习笔记(五) 人脸识别
- Facial Expression Recognition Using Enhanced Deep 3D Convolutional Neural Networks 视频人脸表情识别论文学习笔记
- 2011斯坦福大学iOS应用开发教程学习笔记(第五课)Protocols,手势识别
- 2011斯坦福大学iOS应用开发教程学习笔记(第五课)Protocols,手势识别
- [置顶] Tensorflow学习笔记-基于LeNet5结构的ORL数据集人脸识别
- 百度AI开放平台人脸识别学习笔记(2)
- 【OpenCV学习笔记 014】人脸人眼识别
- 深度学习在图像识别中的应用--学习笔记5
- python3.6.3+opencv3.3.0学习笔记七--人脸识别效果实录
- OpenCV学习笔记(五十五)——用OpenCV做人脸识别和性别识别contrib
- 【OpenCV学习笔记】三十一、轮廓特征属性及应用(八)——颜色物体识别与跟踪
- 模式识别学习笔记之四:模式识别的主要应用领域
- (学习笔记三)——人脸识别