2017-04-06 28 views
1

我正在开发一个需要进行手势识别的项目。 寻找一种方法来做到这一点,我遇到了动态时间扭曲。 要尝试这个想法,并且由于我的项目使用C#,我决定尝试使用Accord.NET。 我在我的项目尝试这样做之前,我创建了一个干净的项目,并修改于Accord.NET的文档的例子,可以在这里找到:使用Accord.NET使用DynamicTimeWarping获取类标签

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

那么,我想现在的权利,是用一组学习数据(包括手势向右滑动,向左滑动和双击)组成的算法进行训练,然后在学习数据中使用相同的示例来查看算法是否识别正确的手势。价值只是一个例子,而不是真正的交易。

关于如何执行此操作,文档不是很清楚,因为示例中使用的Decide方法仅返回布尔值。 我已经搜索了文档以找出正确的类的方法,但无济于事。

我发现的唯一的事情就是下面的线,但它返回的是不是一个布尔值0或1的一个int值,:

VAR RES1 =((IClassifier)svm.ToMulticlass() ).Decide(序列[0]);

任何人都可以在正确的方向上指出我如何正确识别手势? 这是我第一次尝试机器学习和Accord.NET,所以这对我来说绝对是新的。 示例代码可以在下面找到。

namespace DynamicTimeWarpingExample 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 

      double[][][] sequences = 
      { 
       new double[][] // Swipe left 
       { 
        new double[] { 1, 1, 1 }, 
        new double[] { 1, 2, 1 }, 
        new double[] { 1, 2, 2 }, 
        new double[] { 2, 2, 2 }, 
       }, 

       new double[][] // Swipe right 
       { 
        new double[] { 1, 10, 6 }, 
        new double[] { 1, 5, 6 }, 
        new double[] { 6, 7, 1 }, 
       }, 

       new double[][] // Double tap 
       { 
        new double[] { 8, 2, 5 }, 
        new double[] { 1, 50, 4 }, 
       } 
      }; 


      int[] outputs = 
      { 
        0, // Swipe left 
        1, // Swipe right 
        2 // Double tap 
      }; 

      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); // error will be 0.0 

      var res1 = ((IClassifier<double[][], int>)svm.ToMulticlass()).Decide(sequences[0]); // returns 0 

      var res2 = ((IClassifier<double[][], int>)svm.ToMulticlass()).Decide(sequences[1]); // returns 1 

      var res3 = ((IClassifier<double[][], int>)svm.ToMulticlass()).Decide(sequences[2]); // returns 1 
     } 
    } 
} 

*****************新版*****************

public static void Main(string[] args) 
{ 
    double[][][] sequences = 
    { 
     new double[][] // Swipe left 
     { 
      new double[] { 1, 1, 1 }, 
      new double[] { 1, 2, 1 }, 
      new double[] { 1, 2, 2 }, 
      new double[] { 2, 2, 2 }, 
     }, 

     new double[][] // Swipe right 
     { 
      new double[] { 1, 10, 6 }, 
      new double[] { 1, 5, 6 }, 
      new double[] { 6, 7, 1 }, 
     }, 

     new double[][] // Double tap 
     { 
      new double[] { 8, 2, 5 }, 
      new double[] { 1, 50, 4 }, 
     } 
    }; 


    int[] outputs = 
    { 
      0, // Swipe left 
      1, // Swipe right 
      2 // Double tap 
    }; 

    var teacher = new MulticlassSupportVectorLearning<DynamicTimeWarping, double[][]>() 
    { 
     // Configure the learning algorithm to use SMO to train the 
     // underlying SVMs in each of the binary class subproblems. 
     Learner = (param) => new SequentialMinimalOptimization<DynamicTimeWarping, double[][]> 
     { 
      Complexity = 1.5, 
      Kernel = new DynamicTimeWarping(alpha: 1, degree: 1), 
      //UseKernelEstimation = true 
     } 
    }; 

    // Learn a machine 
    var machine = teacher.Learn(sequences, outputs); 

    // Create the multi-class learning algorithm for the machine 
    var calibration = new MulticlassSupportVectorLearning<DynamicTimeWarping, double[][]>() 
    { 
     Model = machine, // We will start with an existing machine 

     // Configure the learning algorithm to use Platt's calibration 
     Learner = (param) => new ProbabilisticOutputCalibration<DynamicTimeWarping, double[][]>() 
     { 
      Model = param.Model // Start with an existing machine 
     } 
    }; 

    // Configure parallel execution options 
    calibration.ParallelOptions.MaxDegreeOfParallelism = 1; 

    // Learn a machine 
    calibration.Learn(sequences, outputs); 

    double decision1, decision2, decision3, decision4, decision5, decision6; 


    var res1 = machine.Probability(sequences[0], out decision1); // decision 0 - Probability 0.78698604216159851 - Score 1 
    var res2 = machine.Probability(sequences[1], out decision2); // decision 1 - Probability 0.67246889837875257 - Score 1 
    var res3 = machine.Probability(sequences[2], out decision3); // decision 2 - Probability 0.78698604216159851 - Score 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); // decision 0 - Probability 0.35577588944247057 - Score 0.051251948605637254 
    var res6 = machine.Score(newGesture2, out decision6); // decision 1 - Probability 0.40733908994050544 - Score 0.19912250476931792 
    var res4 = machine.Score(newGesture3, out decision4); // decision 2 - Probability 0.71853321355842836 - Score 0.816934034911964 
} 
+0

多类学习看看[这](HTTPS ://github.com/accord-net/framework/tree/master/Samples/MachineLearning/Gestures%20(支持向量机))。 – jsanalytics

+0

谢谢你指出这一点给我。 – Andre

+0

不客气。 – jsanalytics

回答

1

问题是你正在为一个实际涉及多个类的问题创建一个二元分类器。

在你的情况,而不是做:

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

var svm = smo.Learn(sequences, outputs); 

你会想换这个二进制学习问题到使用

// Create the multi-class learning algorithm for the machine 
var teacher = new MulticlassSupportVectorLearning<DynamicTimeWarping, double[][]>() 
{ 
    // Configure the learning algorithm to use SMO to train the 
    // underlying SVMs in each of the binary class subproblems. 
    Learner = (param) => new SequentialMinimalOptimization<DynamicTimeWarping, double[][]> 
    { 
     Complexity = 1.5, 
     Kernel = new DynamicTimeWarping(alpha: 1, degree: 1) 
    }; 
} 

// Learn a machine 
var svm = teacher.Learn(inputs, outputs); 
+0

感谢您对Cesar的回应,来自Accord.Net的创建者本人:) 这不可能在更好的时间到来。 本周我会试一试,并将其标记为接受的答案,如果它有效。 – Andre

+0

这是正确的解决方案。 必须改变的另一行是: bool [] predicted = svm.Decide(sequences); 对此: int [] predicted = svm.Decide(sequences); – Andre

+0

嗨,再次塞瑟,只是一个简单的问题。 比方说,我有一个触摸板,我想拒绝偶然的手势。 有没有办法知道决定的“确定性”? 例如在kNN分类有可能通过使对计算方法的变量,以得到这样的: VAR computedExerciseClass = knn.Compute(输入,出确定性); 使用类似的方法,如果确定性高于某个阈值,我可以接受Decide方法的结果。 – Andre