使用Accord.NET通过动态时间扭曲获取类标签

我正在开发一个项目,需要进行手势识别。在寻找实现方法的过程中,我发现了动态时间扭曲。为了尝试这个想法,并且由于我的项目是用C#开发的,我决定尝试使用Accord.NET。在将其应用到我的项目之前,我创建了一个新的项目,并修改了Accord.NET文档中的示例,该示例可以在这里找到:

http://accord-framework.net/docs/html/T_Accord_Statistics_Kernels_DynamicTimeWarping.htm

目前,我正在尝试用一组学习数据(包括向右滑动、向左滑动和双击手势)来训练我的算法,然后使用学习数据中的相同示例来查看算法是否能正确识别手势。这些值只是示例,并非真实数据。

文档对于如何做到这一点的说明并不清晰,因为示例中使用的Decide方法只返回一个布尔值。我在文档中搜索了如何识别正确类的其他方法,但没有找到答案。

我找到的唯一线索是以下这行代码,但它返回的是0或1的整数值,而不是布尔值:

var res1 = ((IClassifier)svm.ToMulticlass()).Decide(sequences[0]);

有没有人能指导我如何正确识别手势?这是我第一次尝试机器学习和Accord.NET,所以这一切对我来说都是全新的。示例代码如下所示:

namespace DynamicTimeWarpingExample{    public class Program    {        public static void Main(string[] args)        {            double[][][] sequences =            {                new double[][] // 向左滑动                {                    new double[] { 1, 1, 1 },                     new double[] { 1, 2, 1 },                     new double[] { 1, 2, 2 },                     new double[] { 2, 2, 2 },                 },                new double[][] // 向右滑动                {                    new double[] { 1, 10, 6 },                     new double[] { 1, 5, 6 },                     new double[] { 6, 7, 1 },                 },                new double[][] // 双击                {                    new double[] { 8, 2, 5 },                     new double[] { 1, 50, 4 },                 }            };            int[] outputs =            {                    0,  // 向左滑动                    1,  // 向右滑动                    2  // 双击            };            var smo = new SequentialMinimalOptimization<DynamicTimeWarping, double[][]>()            {                Complexity = 1.5,                Kernel = new DynamicTimeWarping(alpha: 1, degree: 1)            };            var svm = smo.Learn(sequences, outputs);            bool[] predicted = svm.Decide(sequences);            double error = new ZeroOneLoss(outputs).Loss(predicted); // 错误将为0.0            var res1 = ((IClassifier<double[][], int>)svm.ToMulticlass()).Decide(sequences[0]); // 返回0            var res2 = ((IClassifier<double[][], int>)svm.ToMulticlass()).Decide(sequences[1]); // 返回1            var res3 = ((IClassifier<double[][], int>)svm.ToMulticlass()).Decide(sequences[2]); // 返回1        }    }}

***************** 新版本 *****************

public static void Main(string[] args){    double[][][] sequences =    {        new double[][] // 向左滑动        {            new double[] { 1, 1, 1 },            new double[] { 1, 2, 1 },            new double[] { 1, 2, 2 },            new double[] { 2, 2, 2 },        },        new double[][] // 向右滑动        {            new double[] { 1, 10, 6 },            new double[] { 1, 5, 6 },            new double[] { 6, 7, 1 },        },        new double[][] // 双击        {            new double[] { 8, 2, 5 },            new double[] { 1, 50, 4 },        }    };    int[] outputs =    {            0,  // 向左滑动            1,  // 向右滑动            2  // 双击    };    var teacher = new MulticlassSupportVectorLearning<DynamicTimeWarping, double[][]>()    {        // 配置学习算法使用SMO来训练每个二元类子问题的底层SVM。        Learner = (param) => new SequentialMinimalOptimization<DynamicTimeWarping, double[][]>        {            Complexity = 1.5,            Kernel = new DynamicTimeWarping(alpha: 1, degree: 1),            //UseKernelEstimation = true        }    };    // 学习机器    var machine = teacher.Learn(sequences, outputs);    // 为机器创建多类学习算法    var calibration = new MulticlassSupportVectorLearning<DynamicTimeWarping, double[][]>()    {        Model = machine, // 我们将从现有机器开始        // 配置学习算法使用Platt的校准        Learner = (param) => new ProbabilisticOutputCalibration<DynamicTimeWarping, double[][]>()        {            Model = param.Model // 从现有机器开始        }    };    // 配置并行执行选项    calibration.ParallelOptions.MaxDegreeOfParallelism = 1;    // 学习机器    calibration.Learn(sequences, outputs);    double decision1, decision2, decision3, decision4, decision5, decision6;    var res1 = machine.Probability(sequences[0], out decision1); // 决策0 - 概率0.78698604216159851 - 分数1    var res2 = machine.Probability(sequences[1], out decision2); // 决策1 - 概率0.67246889837875257 - 分数1    var res3 = machine.Probability(sequences[2], out decision3); // 决策2 - 概率0.78698604216159851 - 分数1    var newGesture1 = new double[][]    {        new double[] { 1, 1, 1 },        new double[] { 1, 2, 1 },        new double[] { 1, 2, 2 },        new double[] { 2, 2, 2 },    };    var newGesture2 = new double[][]    {        new double[] { 1, 10, 6 },        new double[] { 1, 5, 6 },        new double[] { 6, 7, 1 },    };    var newGesture3 = new double[][]    {        new double[] { 8, 2, 5 },        new double[] { 1, 50, 4 },    };    var res5 = machine.Score(newGesture1, out decision5); // 决策0 - 概率0.35577588944247057 - 分数0.051251948605637254    var res6 = machine.Score(newGesture2, out decision6); // 决策1 - 概率0.40733908994050544 - 分数0.19912250476931792    var res4 = machine.Score(newGesture3, out decision4); // 决策2 - 概率0.71853321355842836 - 分数0.816934034911964}

回答:

问题在于您正在为一个涉及多个类的问题创建一个二元分类器。

在您的情况下,不是这样做:

var smo = new SequentialMinimalOptimization<DynamicTimeWarping, double[][]>()      {    Complexity = 1.5,    Kernel = new DynamicTimeWarping(alpha: 1, degree: 1)};var svm = smo.Learn(sequences, outputs);

您应该将这个二元学习问题包装成多类学习,如下所示:

// 为机器创建多类学习算法var teacher = new MulticlassSupportVectorLearning<DynamicTimeWarping, double[][]>(){    // 配置学习算法使用SMO来训练每个二元类子问题的底层SVM。    Learner = (param) => new SequentialMinimalOptimization<DynamicTimeWarping, double[][]>    {        Complexity = 1.5,        Kernel = new DynamicTimeWarping(alpha: 1, degree: 1)    };}// 学习机器var svm = teacher.Learn(inputs, outputs);

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注