勇哥的视觉实验:SVM分类器(四) 支持向量机的应用例子,可视化支持向量机的支持向量

前言:

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

分类器相对于深度学习来讲是一种古老传统的图片处理技术。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%被占用。
分类器相对于深度学习来讲不吃硬件,所以相对来讲算是轻量级的应用。

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

为了搞清楚啥是“支持向量”,有必须再介绍一下“支持向量机”的基础知识。

SVM即支持向量机,用于实现数据的二分类。SVM用于二分类,即只有两种类别的分类。
SVM,英文全称为 Support Vector Machine,中文名为支持向量机,由数学家Vapnik等人早在1963年提出。
在深度学习兴起之前,SVM一度风光无限,是机器学习近几十年来最为经典的,也是最受欢迎的分类方法之一。
如下图所示,有两类样本数据(橙色和蓝色的小圆点),中间的红线是分类超平面,
两条虚线上的点(橙色圆点3个和蓝色圆点2个)是距离超平面最近的点,这些点即为支持向量。
简单地说,作为支持向量的样本点非常非常重要,以至于其他的样本点可以视而不见。
而这个分类超平面正是SVM分类器,通过这个分类超平面实现对样本数据一分为二。

在这里插入图片描述

halcon中使用算子get_support_vector_num_class_svm取得“支持向量”。
有了它,你就可以可视化超平面,清楚的看到数据是怎么被分类的。

程序运行结果如下图所示:

紫色点显示出类2的支持向量,青色点显示出类1的支持向量。
它们两者中间的圆弧就超平面。

gen_image_const (Image, 'byte', 200, 200)
for R := 0 to 199 by 1
    for C := 0 to 199 by 1
        classify_class_svm (SVMHandle, [real(R),real(C)], 1, Class)
        set_grayval (Image, R, C, Class)
    endfor
endfor
label_to_region (Image, Classes)

image.png

这里比较有意思的是超平面是怎么画出来的?
它是对整个图像中每个像素进行分类,最后用算子label_to_region分割图像而来的。
因为图片画面只会存在[0,1] ,是个二值化图,所以正好用label_to_region来分割。
分割效果如下图所示:

image.png

所以超平面并不是由支持向量的点拟合出来的。

*这个示例程序演示了如何使用get_support_vector_class_svm来可视化支持向量机的支持向量。
*在本例中,二维数据用于特征,因为它们可以很容易地可视化为区域。
*这个例子使用了两个彼此接近的类,它们之间有一个弯曲的边界。它从每个类中生成样本,
*并用样本训练支持向量机。然后,利用支持向量机对完整的二维特征空间进行分类。此外,支持向量是可视化的。
dev_close_window ()
dev_open_window (0, 0, 600, 600, 'black', WindowHandle)
dev_set_part (0, 0, 199, 199)
dev_update_off ()
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
set_system ('clip_region', 'false')
gen_region_points (Region1, rand(1000) * 200, rand(1000) * 200)
gen_region_points (Region2, rand(1000) * 200, rand(1000) * 200)
set_system ('clip_region', 'true')
gen_ellipse (Ellipse1, 60, 45, rad(-80), 60, 25)
gen_ellipse (Ellipse2, 150, 120, rad(-30), 60, 35)
union2 (Ellipse1, Ellipse2, Ellipse1)
gen_ellipse (Ellipse2, 60, 130, rad(-45), 70, 40)
intersection (Ellipse1, Region1, Region1)
intersection (Ellipse2, Region2, Region2)
dev_clear_window ()
dev_set_draw ('fill')
dev_set_color ('red')
dev_display (Region1)
dev_set_color ('green')
dev_display (Region2)
dev_set_color ('white')
set_tposition (WindowHandle, 5, 5)
write_string (WindowHandle, 'Training samples of the two classes')
stop ()
get_region_points (Region1, Rows1, Cols1)
get_region_points (Region2, Rows2, Cols2)
*在这里改变参数Nu是有指导意义的。
*由于Nu是支持向量个数的上界,增加Nu将导致支持向量个数增加,反之亦然。
*此外,修改上面的椭圆以使类重叠也是有益的。
*注意,在这种情况下,有必要将Nu设置为与类的重叠相对应的值,
*以便获得平滑的类边界(即,避免过度拟合)。
create_class_svm (2, 'rbf', 0.02, 0.01, 2, 'one-versus-one', 'normalization', 0, SVMHandle)
* Add the samples to the SVM.
for J := 0 to |Rows1| - 1 by 1
    add_sample_class_svm (SVMHandle, [real(Rows1[J]),real(Cols1[J])], 0)
endfor
for J := 0 to |Rows2| - 1 by 1
    add_sample_class_svm (SVMHandle, [real(Rows2[J]),real(Cols2[J])], 1)
endfor
* 训练SVM.
train_class_svm (SVMHandle, 0.001, 'default')
* 创建两个区域来可视化这两个类的支持向量.
get_support_vector_num_class_svm (SVMHandle, NumSupportVectors, NumSVPerSVM)
Rows1 := []
Cols1 := []
Rows2 := []
Cols2 := []
for J := 0 to NumSupportVectors - 1 by 1
    get_support_vector_class_svm (SVMHandle, J, Index)
    get_sample_class_svm (SVMHandle, Index, Features, Target)
    if (Target == 0)
        Rows1 := [Rows1,Features[0]]
        Cols1 := [Cols1,Features[1]]
    else
        Rows2 := [Rows2,Features[0]]
        Cols2 := [Cols2,Features[1]]
    endif
endfor
gen_cross_contour_xld (RegionSV1, Rows1, Cols1, 3, rad(45))
gen_cross_contour_xld (RegionSV2, Rows2, Cols2, 3, rad(45))
*对二维特征空间中的每个点进行分类,并将分类结果累加到分类标签图像中。
gen_image_const (Image, 'byte', 200, 200)
for R := 0 to 199 by 1
    for C := 0 to 199 by 1
        classify_class_svm (SVMHandle, [real(R),real(C)], 1, Class)
        set_grayval (Image, R, C, Class)
    endfor
endfor
label_to_region (Image, Classes)
dev_clear_window ()
dev_set_colored (3)
dev_set_draw ('margin')
dev_display (Classes)
dev_set_draw ('fill')
dev_set_color ('red')
dev_display (Region1)
set_tposition (WindowHandle, 182, 2)
write_string (WindowHandle, 'Samples class 1 and class region')
dev_set_color ('green')
dev_display (Region2)
set_tposition (WindowHandle, 2, 2)
write_string (WindowHandle, 'Samples class 2 and class region')
dev_set_line_width (2)
dev_set_color ('cyan')
dev_display (RegionSV1)
set_tposition (WindowHandle, 190, 2)
write_string (WindowHandle, 'Support vectors class 1')
dev_set_color ('magenta')
dev_display (RegionSV2)
set_tposition (WindowHandle, 10, 2)
write_string (WindowHandle, 'Support vectors class 2')
dev_set_line_width (1)



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

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


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

发表评论:

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

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 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