勇哥的视觉实验:SVM分类器(八) 支持向量机的应用例子,对2d数据进行分类

前言:

==========================================================

分类器相对于深度学习来讲是一种古老传统的图片处理技术。halcon中常见的有四类分类器:

  • MLP(多层神经网络neural Nets)

  • SVM(支持向量机)

  • K-NN(K-最邻近)

  • GMM(高斯混合类型)

分类器的应用领域主要是下面这些:

  • image segmentation         图像分割  

  • object recognition             对象识别 

  • quality control                 质量控制

  • novelty detection             缺陷检测 

  • optical character recognition(OCR)      光学字符识别

勇哥第一次见到分类器的视觉项目是锂电池的极片缺陷检测,效果还不错。
这两年深度学习火起来后,发现深度学习完成上面所说的领域的应用更容易,效果也更好。

但深度学习对硬件要求太高,你把IPC加装个一百多W的显卡很多时候是不现实的。
如果你用cpu来跑,会发现速度乎快乎慢,cpu全部内核会100%被占用。
分类器相对于深度学习来讲不吃硬件,所以相对来讲算是轻量级的应用。

==========================================================

先前讲GMM的时候,也有这个对2D数据进行分类的例子,参见:http://www.skcircle.com/?id=1627


下面这个示例程序演示了如何使用支持向量机(SVM)对二维数据进行分类。

使用二维数据是因为它可以很容易地可视化为区域和图像。

该示例使用了三个基本重叠的类。

它从每个类中生成样本,并用样本训练支持向量机。然后,利用支持向量机对完整的二维特征空间进行分类。

从结果可以看出,支持向量机将特征空间中的每个点分类为三类中的一类。因此,即使在训练样本的凸包之外很远的点也将被分配给三个类中的一个。

这是支持向量机分类器的一个普遍性质,有时需要训练一个显式拒绝类。

此外,这个例子程序表明,参数Nu需要仔细选择,如果类重叠,它设置的效果应该大于不可避免的错误点。



首先随机生成的3个类,它们有一部分是重叠的。

image.png


当设置Nu=0.01的时候,我们看到分类的结果明显是错误的。

image.png

当Nu=0.18的时候,是过滤拟合的,结果仍然不理想。

image.png

当Nu=0.25的时候,取得了很好的分类效果。

image.png

dev_close_window ()
dev_open_window (0, 0, 600, 600, 'black', WindowHandle)
dev_set_part (0, 0, 199, 199)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_update_off ()
* 生成三个重叠的椭圆作为提取训练样本的区域
gen_ellipse (RegionClass1, 60, 60, rad(-45), 60, 40)
gen_ellipse (RegionClass2, 70, 130, rad(-145), 70, 30)
gen_ellipse (RegionClass3, 140, 100, rad(100), 55, 40)
* Sample feature points from each region by segmenting a different noisy image
* for each region and intersecting the segmented region with the class region.
gen_image_const (Image, 'byte', 200, 200)
add_noise_white (Image, ImageNoise1, 60)
add_noise_white (Image, ImageNoise2, 60)
add_noise_white (Image, ImageNoise3, 60)
threshold (ImageNoise1, RegionNoise1, 40, 255)
threshold (ImageNoise2, RegionNoise2, 40, 255)
threshold (ImageNoise3, RegionNoise3, 40, 255)
intersection (RegionClass1, RegionNoise1, SamplesClass1)
intersection (RegionClass2, RegionNoise2, SamplesClass2)
intersection (RegionClass3, RegionNoise3, SamplesClass3)
* 显示每个类的示例.
dev_clear_window ()
dev_set_color ('red')
dev_display (SamplesClass1)
dev_set_color ('green')
dev_display (SamplesClass2)
dev_set_color ('blue')
dev_display (SamplesClass3)
Message := 'Training samples of the 3 classes'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
classify_2d_feature_space (SamplesClass1, SamplesClass2, SamplesClass3, RegionClass1, RegionClass2, RegionClass3, WindowHandle, 'rbf', 0.05, 0.01)
Message := 'Nu = 0.01: Wrong classification'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
classify_2d_feature_space (SamplesClass1, SamplesClass2, SamplesClass3, RegionClass1, RegionClass2, RegionClass3, WindowHandle, 'rbf', 0.05, 0.18)
Message := 'Nu = 0.18: Overfitting'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
classify_2d_feature_space (SamplesClass1, SamplesClass2, SamplesClass3, RegionClass1, RegionClass2, RegionClass3, WindowHandle, 'rbf', 0.05, 0.25)
Message := 'Nu = 0.25: Good generalization'
disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')

函数classify_2d_feature_space的代码:

image.png

* 读取样本点并将其作为训练样本添加到支持向量机中.
concat_obj (SamplesClass1, SamplesClass2, Samples)
concat_obj (Samples, SamplesClass3, Samples)
* 对Nu尝试不同的值是有意义的。
*对于太小的值(约0.2,取决于随机样本的分布),类区域的边界将变得非常不平滑,
*表明对于所选Nu,类重叠过多,因此SVM需要对训练数据进行过度拟合。
*根据KernelType和KernelParam的选择,类边界的形状会有很大的不同。
*因此,可以看出,要获得最佳平滑的类边界,最好对类重叠的百分比进行估计。
create_class_svm (2, KernelType, KernelParam, Nu, 3, 'one-versus-one', 'normalization', 0, SVMHandle)
for Class := 0 to 2 by 1
    select_obj (Samples, SamplesClass, Class + 1)
    get_region_points (SamplesClass, Rows, Cols)
    for J := 0 to |Rows| - 1 by 1
        add_sample_class_svm (SVMHandle, real([Rows[J],Cols[J]]), Class)
    endfor
endfor
get_sample_num_class_svm (SVMHandle, NumSamples)
*训练SVM.
train_class_svm (SVMHandle, 0.001, 'default')
* 现在对二维特征空间中的所有点进行分类,并将分类存储在类别标签图像中。
gen_image_const (LabelClass, 'byte', 200, 200)
for R := 0 to 199 by 1
    for C := 0 to 199 by 1
        Features := real([R,C])
        classify_class_svm (SVMHandle, Features, 1, Class)
        set_grayval (LabelClass, R, C, Class)
    endfor
endfor
label_to_region (LabelClass, Classes)
* 显示特征空间中类的每个点.
dev_set_colored (3)
dev_display (Classes)
dev_set_color ('white')
dev_set_draw ('margin')
dev_display (RegionClass1)
dev_display (RegionClass2)
dev_display (RegionClass3)
dev_set_draw ('fill')
set_tposition (WindowHandle, 5, 5)
write_string (WindowHandle, 'Class regions')
return ()


其实有关Nu的设置,在上一篇介绍新奇检测的例子中已经讲的比较详细了,http://www.skcircle.com/?id=1645

本篇的侧重点则在于介绍类的过渡拟合问题。


--------------------- 

作者:hackpig
来源:
www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864