2017-01-27 3 views
0

이 주제에 대해 새로운 것을 알고 싶습니다. 내가하려고하는 것은 다른 매개 변수 (다른 종류의 이미지 서명)가있는 동일한 데이터 세트에 대해 많은 SVM을 학습 한 다음 각 SVM을 예측하고 주로 발견 된 클래스를 허용합니다.예상대로 SVM을 작동시키지 못합니다.

SVM 이미지 교육에 대한 많은 사람들의 코드를 읽으려고했으나 잘못된 코드를 내 코드에 적용하지 못했습니다. 내가 시도한 것은 언제나 그렇습니다. 예측은 항상 0을 반환합니다.

도움이나 힌트를 보내 주시면 감사하겠습니다.

internal class SVMClassifier 
    { 
     Dictionary<int, string> classIndex_name; 
     List<SVM> svms; 

     internal void Train(string trainFolder) 
     { 
      this.classIndex_name = new Dictionary<int, string>(); 
      Dictionary<int, List<Mat>> class_mats = getMats(trainFolder, this.classIndex_name); 
      this.svms = new List<SVM>(); 


      Mat samples; Mat responses; 
      getTrainingData(class_mats, out samples, out responses); 
      svms.Add(trainSVM(samples, responses)); 
      svms.Add(trainSVM(samples, responses, SVM.SvmType.CSvc, SVM.SvmKernelType.Linear, 0d, 0d, 10d, TermCritType.Iter | TermCritType.Eps, 1000, 0.000001d, 0d, 0d)); 
      svms.Add(trainSVM(samples, responses, SVM.SvmType.CSvc, SVM.SvmKernelType.Rbf, 100d, 100d, 1d, TermCritType.Iter | TermCritType.Eps, 1000, 0.000001d, 0.1d, 0.5d)); 

      samples.Dispose(); responses.Dispose(); 

      foreach (Mat mat in class_mats.Values.SelectMany((a) => a)) 
       mat.Dispose(); 
     } 
     private static Dictionary<int, List<Mat>> getMats(string trainFolder, Dictionary<int, string> classIndex_name) 
     { 
      Dictionary<int, List<Mat>> class_mats = new Dictionary<int, List<Mat>>(); 
      DirectoryInfo diTrain = new DirectoryInfo(trainFolder); 
      int i = 0; 
      foreach (var di in diTrain.GetDirectories())//classes are according to the directories 
      { 
       var dirName = di.Name; 
       classIndex_name[i] = dirName; 
       var fileNames = di.GetFiles().Select((a) => a.FullName).ToList(); 
       fileNames.Sort(new Dece.Misc.NumericSuffixFileFullNameComparer()); 
       class_mats[i] = fileNames.Select((a) => getMat(a, true)).ToList(); 
       i++; 
      } 
      return class_mats; 
     } 

     private static SVM trainSVM(Mat samples, Mat responses, 
      SVM.SvmType? svm_Type = null, SVM.SvmKernelType? svm_KernelType = null, double? gamma = null, double? degree = null, double? c = null, 
      TermCritType? criteriaType = null, int? criteriaMaxCount = null, double? criteriaEps = null, double? p = null, double? nu=null) 
     { 
      SVM svm = new SVM(); 
      if (svm_Type != null) svm.Type = (SVM.SvmType)svm_Type; 
      if (svm_KernelType != null) svm.SetKernel((SVM.SvmKernelType)svm_KernelType); 
      if (gamma != null) svm.Gamma = (double)gamma; 
      if (degree != null) svm.Degree = (double)degree; 
      if (c != null) svm.C = (double)c; 

      if ((criteriaType != null) || (criteriaMaxCount != null) || (criteriaEps != null)) 
      { 
       var t = new MCvTermCriteria((int)criteriaMaxCount, (double)criteriaEps); 
       if (criteriaType != null) t.Type = (TermCritType)criteriaType; 
       svm.TermCriteria = t; 
      } 


      if (p != null) svm.P = (double)p; 
      if (nu != null) svm.Nu = (double)nu; 

      if (!svm.Train(samples, DataLayoutType.RowSample, responses)) 
       throw new Exception(); 
      return svm; 
     } 

     private static void getTrainingData(Dictionary<int, List<Mat>> class_mats, out Mat samples, out Mat responses) 
     { 
      samples = null; 
      List<int> lstResp = new List<int>(); 
      foreach (int cls in class_mats.Keys) 
      { 
       int count = 0; 
       foreach (Mat mat in class_mats[cls]) 
        using (var desc = mat.Reshape(0, 1)) 
        { 
         if (samples == null) 
          samples = new Mat(desc.Cols, 0, desc.Depth, 1); 
         samples.PushBack(desc); 
         count += desc.Rows; 
        } 
       for (int i = 0; i < count; i++) 
        lstResp.Add(cls); 
      } 

      //responses = new Mat(new Size(lstResp.Count, 1), DepthType.Cv32S, 1); 
      //for (int i = 0; i < lstResp.Count; i++) 
      // responses.SetValue(0, i, lstResp[i]); 

      responses = new Mat(new Size(1, lstResp.Count), DepthType.Cv32S, 1); 
      for (int i = 0; i < lstResp.Count; i++) 
       responses.SetValue(i, 0, lstResp[i]); 

      if (samples.Depth != DepthType.Cv32F) 
       samples.ConvertTo(samples, DepthType.Cv32F); 

      CvInvoke.Normalize(samples, samples, -1, 1, NormType.MinMax); 
     } 

     internal void Detect(IEnumerable<string> fileNames, Action<ShapeInfo> detected) 
     { 
      foreach (var fn in fileNames) 
       using (Mat mat = getMat(fn, false)) 
       { 
        { 
         using (var samples = mat.Reshape(0, 1)) 
         { 
          if (samples.Depth != DepthType.Cv32F) 
           samples.ConvertTo(samples, DepthType.Cv32F); 
          CvInvoke.Normalize(samples, samples, -1, 1, NormType.MinMax); 
          foreach (var svm in this.svms) 
          { 
           Mat res = new Mat(); 
           float p0 = svm.Predict(samples, res, 0); 
           float p1 = svm.Predict(samples, res, 1); 
           float p2 = svm.Predict(samples, res, 2); 
           float p3 = svm.Predict(samples, res, 3); 
           float p4 = svm.Predict(samples, res, 4); 
           float p = svm.Predict(samples, res); 

           foreach (var val in toIEnumerable(p0, p1, p2, p3, p4, p)) 
            if (val != 0f) 
            { 
             System.Windows.Forms.MessageBox.Show("never enters here :("); 
            } 
          } 
         } 
        } 
       } 
     } 

     private static Mat getMat(string fn, bool train) 
     { 
      var mat = new Mat(fn, ImreadModes.Grayscale); 
      mat.Resize(new Size(128, 128)); 
      return mat; 
     } 
     private static IEnumerable<T> toIEnumerable<T>(params T[] items) 
     { 
      if (items != null) 
       foreach (var item in items) 
        yield return item; 
     } 

    } 

Mat.SetValue 확장자는 here에서 가져옵니다.

이 사이트의 형식에 대해 부탁드립니다. 그렇지 않은 경우이 질문을 닫아도 지울 수 있지만 문제는 없습니다. 나는 어떻게 우리가 이미지를 가진 svm을 훈련시켜야하는지 이해하려고 노력하고있다.

답변

0

예 바보입니다. 문제는 Mat to Predict 함수를 비우는 것입니다. 대신 null을 시도했을 때 클래스 예측을 시작했습니다. (나는 아직도 이유를 알지 못한다.)

분류 문제는 나를 바보처럼 느끼게한다. 내가 svm을 어떻게 사용하고 있는지, 어떤 일을 할 수 있을지에 대한 의견은 모두 잘해야한다.

 internal void Detect(IEnumerable<string> fileNames, Action<ShapeInfo> detected) 
     { 
      foreach (var fn in fileNames) 
       using (Mat mat = getMat(fn, false)) 
       { 
        { 
         using (var samples = mat.Reshape(0, 1)) 
         { 
          if (samples.Depth != DepthType.Cv32F) 
           samples.ConvertTo(samples, DepthType.Cv32F); 
          CvInvoke.Normalize(samples, samples, -1, 1, NormType.MinMax); 
          foreach (var svm in this.svms) 
          { 
           float p = svm.Predict(samples, null); 

          } 
         } 
        } 
       } 
     } 
관련 문제