快捷搜索:
来自 计算机编程 2019-10-22 06:48 的文章
当前位置: 67677新澳门手机版 > 计算机编程 > 正文

67677新澳门手机版:LibSVM之C# Wrapper

  后人有在V2.89的功底上做一些修改,提议了:SVM.NET with Parallel Optimization。相关描述为:When finding parameters, C and Gamma, in Grid-search algorithm using ParameterSelection.PGrid instead of the original ParameterSelection.Grid will increase the calculation speed.

【现有libsvm的C#/.Net版本】

  该进度中,DllImport要怎么着行使,感兴趣的读者可自行学习,这里要求注意的是C 函数中的数据结构到C#中的数据结构是有炫彩关系的,上边附上一张dll援用常用转化表:

  为何libsvmSharp.dll如此低效?

  LIBSVM是湖南高校林智仁(Lin Chih-Jen)助教等开荒设计的叁个简便、易于使用和高效有效的SVM方式识别与回归的软件包,他不但提供了编写翻译好的可在Windows连串系统的实行文书,还提供了源代码,方便革新、修改以致在其余操作系统上应用;该软件对SVM所提到的参数调解相对比非常少,提供了点不清的暗中同意参数,利用这几个私下认可参数能够缓和广大难点;并提供了交互核实(CrossValidation)的成效。该软件能够化解C-SVM、ν-SVM、ε-SVCR-V和ν-SV汉兰达等难点,包罗基于豆蔻梢头对欣欣向荣算法的多类形式识别难题……

  这里大家用libsvm中的svm_predict作为例子来教学。

 1         public static double Predict(SVMModel model, SVMNode[] x)
 2         {
 3             if (model == null)
 4             {
 5                 throw new ArgumentNullException("model");
 6             }
 7             if (x == null)
 8             {
 9                 throw new ArgumentNullException("x");
10             }
11             IntPtr intPtr = SVMModel.Allocate(model);
12             double result = SVM.Predict(intPtr, x);
13             SVMModel.Free(intPtr);
14             return result;
15         }
16 
17         public static double Predict(IntPtr ptr_model, SVMNode[] x)
18         {
19             if (ptr_model == IntPtr.Zero)
20             {
21                 throw new ArgumentNullException("ptr_model");
22             }
23             if (x == null)
24             {
25                 throw new ArgumentNullException("x");
26             }
27             List<SVMNode> list = (from a in x
28             select a.Clone()).ToList<SVMNode>();
29             list.Add(new SVMNode(-1, 0.0));
30             IntPtr intPtr = SVMNode.Allocate(list.ToArray());
31             double result = libsvm.svm_predict(ptr_model, intPtr);
32             SVMNode.Free(intPtr);
33             return result;
34         }

  同样是C#对C 的wrapper,一样都以基于libsvm,一样是对C 所编写翻译的dll的援用,效能竟相差百倍!本着活龙活现颗学习的心,小编主宰朝气蓬勃探毕竟……

  1.wrapper第一步(准备)

    • .Net implementation
    • Parallel kernel implementation
    • SVM CUDA acceleration – kernels and solver
    • CUDA SVM with sparse data formats: CSR, Ellpack-R, Sliced-Ellpack
    • For non commercial and academic use: Free MIT license when use please cite: Bibtex CUDA SVM CSR

  二〇一〇年,斯坦福大学的马特hewa Johnson博士将SVM.NET更新到了V2.89,也正是当今的风行版本。无语未来不FQ竟已经找不到SVM.NET的原生版了。这份神秘感使小编以为,这几个C#本子的libsvm应该是质量最高的。

    2、calss:SVMNode、SVMModel、SVMProblem、SVMParameter。

  首先大家看张libsvm官方网站首页上的截图:

    二是一直找别的的svm库。

  进行到近来,大家只是完结了数据结构搭建的一小部分,上边是从EmguCV中学习到的美观部分!将要下篇作介绍~

  因此,在EmguCV的ML满意不断的景况下,萌生了三个主张:

  在反编写翻译后的源代码中(稍后将介绍如何反编写翻译C#编写翻译出来的dll文件),大家能够看出libsvmSharp所用的数据结构有:

【C# Wrapper 动机】

 double svm_predict(const svm_model *model, const svm_node *x)

    1、struct:svm_node、svm_model、svm_problem、svm_parameter;

  安装C#的dll反编写翻译工具,这里推荐ILSpy。为啥要设置?比起协和杏黄中寻找,假设有可以参照他事他说加以考察借鉴的能源,不以为意是何其缺憾的豆蔻年华件事啊。EmguCV真的称得上wrapper中的卓绝。

  DllImport时,越来越多关于C 数据结构到C#数据结构的新闻请读者查阅资料取得。由上可以看到,IntPtr是个很着重的数据结构,由它注解的变量实际上是四个指针值(即内部存款和储蓄器地址值)。第八个参数IntPtr model,须要传入model所在内部存储器区域的地点,第三个参数IntPtr x,要求传入特征节点数组所在内部存款和储蓄器区域的地方。上面,大家看看libsvmSharp是怎么利用那几个函数的:

  其次,加多须求wrapper的C dll文件。右键单击解决方案能源管理器中的libsvmSharpCyc,然后增添现有项,把libsvm.dll增多进项目。

  到场过三个项目,使用IDE是VS winform,工具包为EmguCV 2.4.10。大家领略OpenCV第22中学的svm部分是基于libsvm-2.6编写制定的,该版本的libsvm已经能够estimate预测可能率了(libsvm首页的change log中有详尽表明),但是OpenCV却废弃了predictProbability。在切实可行的档期的顺序中,如果能够得到预测可能率音讯,那将对加强识别性有非常大的援救。可是,opencv2抛弃了识别可能率,包罗opencv3,笔者看源代码的svm部分也是基于libsvm-2.6更换的,也从未引入predictProbability。

5、libsvm-net by Nicolas Panel

  豆蔻梢头切都以因为C#有指针,但不是特别大家所熟谙的指针。C#还没像Java同样完全撤消指针,但为了代码安全考虑而减少指针。C#是面向对象的言语,里面其余一种数据结构都未有指针那豆蔻梢头性质,除非您本人在定义数据结构时,将指针作为成员变量。我们所熟识的EmguCV就是这般达成对OpenCV的wrapper的。

  并且,能够看看种种的达成中,有无尽“结构体=>类”、“指针=>结构体”、“类=>指针”等如此的类型调换。大家清楚,C#要援引C 所编写翻译的dll,用得最多的就是IntPtr这些数据结构。而libsvmSharp低效的来头,也正在于对指针的管理政策选择不当,它只在必要传指针的时候,硬生生地用马尔斯hal类重新在内部存款和储蓄器中开拓当前数据结构大小的区域,并回到指针,美其名曰convert到指针。这种措施,无论是在岁月上照旧空间上,都有太多没要求的浪费。

    public struct svm_node
    {
        /// <summary>
        /// 索引
        /// </summary>
        public int index;

        /// <summary>
        /// 值
        /// </summary>
        public double value;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="i"></param>
        /// <param name="v"></param>
        public svm_node(int i,double v)
        {
            this.index = i;
            this.value = v;
        }
        public bool Equals(svm_node x)
        {
            return this.index.Equals(x.index) && this.value.Equals(x.value);
        }
    }
    public struct svm_problem
    {
        /// <summary>
        /// 支持向量个数
        /// </summary>
        public int l;

        /// <summary>
        /// 标签值
        /// </summary>
        public IntPtr y;

        /// <summary>
        /// 节点情况
        /// </summary>
        public IntPtr x;
    }
    ……

  下载起来同样十三分利于: NuGet package : PM> Install-Package libsvm.net,比起libsvmSharp有更加高的名气。

    黄金时代是修改OpenCV代码,然后再次CMake得到cvextern.dll;

  若是你对libsvm还远远不足通晓,建议先浏览下百度百科等对libsvm的牵线~

67677新澳门手机版 1

  留神的您有未有察觉什么难点?看不懂?毕竟自身是以文害辞。可是,请看第11行,每一遍调用都要双重给model分配内部存款和储蓄器哦!再如,第27、28、29、30行,在熟习C 的人看来,that's what?参数字传送进来的可不是数组名吗,干嘛如此冥思遐想?内部存款和储蓄器不会被玩坏吗?

 1 struct svm_node
 2 {
 3     int index;
 4     double value;
 5 };
 6 
 7 struct svm_problem
 8 {
 9     int l;
10     double *y;
11     struct svm_node **x;
12 };
13 
14 enum { C_SVC, NU_SVC, ONE_CLASS, EPSILON_SVR, NU_SVR };    /* svm_type */
15 enum { LINEAR, POLY, RBF, SIGMOID, PRECOMPUTED }; /* kernel_type */
16 
17 struct svm_parameter
18 {
19     int svm_type;
20     int kernel_type;
21     int degree;    /* for poly */
22     double gamma;    /* for poly/rbf/sigmoid */
23     double coef0;    /* for poly/sigmoid */
24 
25     /* these are for training only */
26     double cache_size; /* in MB */
27     double eps;    /* stopping criteria */
28     double C;    /* for C_SVC, EPSILON_SVR and NU_SVR */
29     int nr_weight;        /* for C_SVC */
30     int *weight_label;    /* for C_SVC */
31     double* weight;        /* for C_SVC */
32     double nu;    /* for NU_SVC, ONE_CLASS, and NU_SVR */
33     double p;    /* for EPSILON_SVR */
34     int shrinking;    /* use the shrinking heuristics */
35     int probability; /* do probability estimates */
36 };
37 
38 //
39 // svm_model
40 // 
41 struct svm_model
42 {
43     struct svm_parameter param;    /* parameter */
44     int nr_class;        /* number of classes, = 2 in regression/one class svm */
45     int l;            /* total #SV */
46     struct svm_node **SV;        /* SVs (SV[l]) */
47     double **sv_coef;    /* coefficients for SVs in decision functions (sv_coef[k-1][l]) */
48     double *rho;        /* constants in decision functions (rho[k*(k-1)/2]) */
49     double *probA;        /* pariwise probability information */
50     double *probB;
51     int *sv_indices;        /* sv_indices[0,...,nSV-1] are values in [1,...,num_traning_data] to indicate SVs in the training set */
52 
53     /* for classification only */
54 
55     int *label;        /* label of each class (label[k]) */
56     int *nSV;        /* number of SVs for each class (nSV[k]) */
57                 /* nSV[0]   nSV[1]   ...   nSV[k-1] = l */
58     /* XXX */
59     int free_sv;        /* 1 if svm_model is created by svm_load_model*/
60                 /* 0 if svm_model is created by svm_train */
61 };

  上边,大家看看今后libsvm有怎样C#版本:

  1. wrapper第二步(DllImport)

  对应地,我们在C#中成立数据结构:

  接着,新建类,用于DllImport。笔者建的是LsInvoke.cs,能够像下图所示那样,把想要使用的函数方法给Import进来:

  在libsvm.dll(该dll由C 编写翻译获得)中,函数为:

  恐怕有读者会问,结构体你加构造函数和其余函数干嘛?那实质上是为了今后好简化代码。不然,每趟对象创制于赋值分开操作有一点点辛勤。

4、libsvmSharp by ccerhan

  获取你要wrapper的dll(由C 编写翻译得到),最佳有源代码,当然有参照他事他说加以考察手册也足以,不过只要除去dll的名字,对该dll不学无术,那只怕就不能够了。

  首先,VS新建C#工程,项目项目选项类库,那样结尾生成施工方案后,便能够在bin/Debug目录下获得实用的dll文件了。小编将品种命名字为libsvmSharpCyc。

  Key Features

  前文已经轻便地介绍过libsvm的数据结构了。这里再次一下:

【百度百科】

            C              C#
        =====================================
        WORD              ushort
        DWORD             uint
        UCHAR             int/byte   大部分情况都可以使用int代替,而如果需要严格对齐的话则应该用bytebyte 
        UCHAR*            string/IntPtr
        unsigned char*    [MarshalAs(UnmanagedType.LPArray)]byte[]/?(Intptr)
        char*             string
        LPCTSTR           string
        LPTSTR            [MarshalAs(UnmanagedType.LPTStr)] string
        long              int
        ulong             uint
        Handle            IntPtr
        HWND              IntPtr
        void*             IntPtr
        int               int
        int*              ref int
        *int              IntPtr
        unsigned int      uint
        COLORREF          uint

3、KMLib(Kernel Machine Library with GPU SVM solver in .Net) by Krzysztof Sopyła

67677新澳门手机版 2

  首先尝试CMake。像OpenCV这样的大类别,CMake起来着实不轻巧,更何况是从零开始学CMake。在时光差异意的标准化下,只得走第二条路。找到libsvmSharp后,小编大喜过望。不过,十分的快笔者又再度失望了,因为实时性供给满足不断(EmguCV自带SVM能够在5ms内成功辨认预测,而libsvmSharp必要500ms)。

  1、SVM.NET by Matthewa Johnson

  其余,还会有有个别急需强调的是,它是基于libsvm的java版本调换过来的。也正因如此,笔者备感用起来大概会微微劳碌,故并未有选取。

 [DllImport("libsvm.dll", CallingConvention = CallingConvention.Cdecl)]
 public static extern double svm_predict(IntPtr model, IntPtr x);

【开始libsvm的C# Wrapper之旅】

  2、NSVM by Joannes

  目前,LIBSVM拥有C、Java、Matlab、C#、Ruby、Python、福特Explorer、Perl、Common LISP、Labview等数十种语言版本。最常使用的是C、Matlab、Java和命令行(c语言编写翻译的工具)的版本。

  选用它的理由很简短,有料定的下载量(从众心思又起来生事了!)下载方便,用VS的Nuget package,通过命令“PM> Install-Package LibSVMsharp”即下载到本地。

  那是干吗?

67677新澳门手机版 3

【分析libsvmSharp】

    3年时光,却独有2下载量,何其惨淡……好啊,大概你也像本人一样主观臆断了。

  在libsvmSharp.dll(该dll由C#编写翻译获得)中,大家如此注解它:

3、wrapper第三步(数据结构)

  很好,大家得以进去正题了。笔者将以wrapper libsvm为例,分步骤讲授整个经过。读者能够推而广之,希望本文能够协理你加深你对跨语言编制程序的敞亮。

  这一步是极度主要的一步,在C#中新建数据结构,必须求与C 中的数据结构相平等,不然遇到不能预料的难题。

事实上,结构体能做的事务,类完全也能做,就好像结构体未有存在的不可或缺。

本文由67677新澳门手机版发布于计算机编程,转载请注明出处:67677新澳门手机版:LibSVM之C# Wrapper

关键词: