【问题标题】:Using an Accord.NET SVM for face recognition (MulticlassSupportVectorMachine)使用 Accord.NET SVM 进行人脸识别 (MulticlassSupportVectorMachine)
【发布时间】:2018-08-20 22:47:23
【问题描述】:

我正在使用 OpenFace Windows 二进制文件和 Accord .NET 创建 C# 版本的 this 基于 Python 的人脸识别系统。

OpenFace 完成了大部分工作,我只需要训练一个 SVM 以使用已知人脸作为输出类(以概率)对未知人脸进行分类。

在这种情况下,“人脸”是一个包含人脸测量值的 CSV 文件。理论上很简单。由于这似乎是 best done 与 one-vs-rest 方法,我正在尝试从 API 中的 MulticlassSupportVectorMachine example 工作。

但是,据我所知,该示例使用来自其训练数据的相同输入作为测试输入,因此我不确定训练结束和测试开始的确切位置,但我假设它位于调用 .Decide()

这就是我现在正在尝试的......

-创建几个简单的容器类

    public class Result
    {
        public int[] predictions;
        public double[][] scores;
        public double[][] probability;
        public double error;
        public double loss;
    }

    public class KnownFaces
    {
        public double[][] input;
        public int[] output;
    }

    public class UnknownFaces
    {
        public double[][] input;
    }`

获取已知面孔的编码

 // Load encoding from CSV
double[] aiden1Encoding = RecognizeFace.GetEncodingFromCSV(Application.StartupPath + @"\of\processed\aiden1.csv");
double[] aiden2Encoding = RecognizeFace.GetEncodingFromCSV(Application.StartupPath + @"\of\processed\aiden2.csv");
...
double[] kate1Encoding = RecognizeFace.GetEncodingFromCSV(Application.StartupPath + @"\of\processed\kate1.csv");
double[] kate2Encoding = RecognizeFace.GetEncodingFromCSV(Application.StartupPath + @"\of\processed\kate2.csv");
...
//... etc (about 20 pictures of each person)

获取未知面孔的编码

double[] who1Encoding = RecognizeFace.GetEncodingFromCSV(Application.StartupPath + @"\of\processed\who1.csv");
double[] who2Encoding = RecognizeFace.GetEncodingFromCSV(Application.StartupPath + @"\of\processed\who2.csv");
...

把这些都放在我的容器里

double[][] knownFacesFeatures = {
aiden1Encoding, aiden2Encoding, ... 
kate1Encoding, kate2Encoding, ...
};

double[][] unknownFacesFeatures = {
who1Encoding, who2Encoding ... 
};

RecognizeFace.KnownFaces knownFaces = new RecognizeFace.KnownFaces();
knownFaces.input = knownFacesFeatures;

RecognizeFace.UnknownFaces unknownFaces = new RecognizeFace.UnknownFaces();
unknownFaces.input = unknownFacesFeatures;

对已知人脸的输出进行分类

knownFaces.output = new int[]
    {
    0,0,0 ... // Aiden
    1,1,1 ...  // Kate
    ...
    };

得到结果:

RecognizeFace.Result r = RecognizeFace.RecognizeFaces(knownFaces, unknownFaces);

...

public static Result RecognizeFaces(KnownFaces knownFaces, UnknownFaces unknownFaces)
        {
            Result toReturn = new Result();

            // Create the multi-class learning algorithm for the machine
            var teacher = new MulticlassSupportVectorLearning<Gaussian>()
            {
                // Configure the learning algorithm to use SMO to train the
                //  underlying SVMs in each of the binary class subproblems.
                Learner = (param) => new SequentialMinimalOptimization<Gaussian>()
                {
                    // Estimate a suitable guess for the Gaussian kernel's parameters.
                    // This estimate can serve as a starting point for a grid search.
                    UseKernelEstimation = true
                }
            };
            // Learn a machine
            var machine = teacher.Learn(knownFaces.input, knownFaces.output);


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

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



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

            // Learn a machine
            calibration.Learn(knownFaces.input, knownFaces.output);

            // Obtain class predictions for each sample
            int[] predicted = machine.Decide(unknownFaces.input);
            toReturn.predictions = predicted;

            // Get class scores for each sample
            double[][] scores = machine.Scores(unknownFaces.input);
            toReturn.scores = scores;

            // Get log-likelihoods (should be same as scores)
            double[][] logl = machine.LogLikelihoods(unknownFaces.input);

            // Get probability for each sample
            double[][] prob = machine.Probabilities(unknownFaces.input);
            toReturn.probability = prob;

            //Compute classification error using mean accuracy (mAcc)
            //double error = new HammingLoss(knownFaces.output).Loss(predicted);
            //double loss = new CategoryCrossEntropyLoss(knownFaces.output).Loss(prob);
            //toReturn.error = error;
            //toReturn.loss = loss;

            return toReturn;

        }

问题是如果我取消注释错误/丢失行,我会得到一个异常,

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Accord.Math.Optimization.Losses.HammingLoss.Loss(Int32[] actual)
   at NETFaceRecognition.RecognizeFace.RecognizeFaces(KnownFaces knownFaces, UnknownFaces unknownFaces) 

如果我把它们排除在外,代码就会运行......并且不起作用。如果我迭代 int[] 预测,我会得到完全错误的结果(通常):

Unknown Person #1's class: 2 Expected: 3 (Lena)
Unknown Person #2's class: 2 Expected: 3 (Lena)
Unknown Person #3's class: 2 Expected: 2 (James)
Unknown Person #4's class: 2 Expected: 2 (James)
Unknown Person #5's class: 3 Expected: (Unknown person, incorrect result expected)
Unknown Person #6's class: 0 Expected: 3 (Lena)
Unknown Person #7's class: 1 Expected: 2 (James)
Unknown Person #8's class: 3 Expected: 1 (Kate)

我的问题的要点是:我是否正确地实现了这个类,我的问题存在于我的数据输入的某个地方,还是我误解了一些重要的东西? TIA

【问题讨论】:

    标签: c# svm face-recognition accord.net


    【解决方案1】:

    我很确定您会收到错误消息,因为尺寸不匹配。此外,我认为您在这里计算的逻辑错误会因不适当的数据集而丢失。您在 knownFaces 上学习并通过 unknownFaces 进行预测。

    double error = new HammingLoss(knownFaces.output).Loss(predicted);
    

    您可能需要对训练部分未使用的数据的已知部分进行交叉验证。

    做一些这样的想法:

    double error = new HammingLoss(knownFacesForPredicted.output).Loss(predicted);
    

    【讨论】:

      猜你喜欢
      • 2014-05-04
      • 2021-07-27
      • 2014-04-15
      • 2021-03-12
      • 2014-01-20
      • 2012-11-01
      • 2012-12-10
      • 2014-05-21
      • 2019-04-29
      相关资源
      最近更新 更多