Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            ImageUnderstandingConfig config = ImageUnderstandingConfig.ImportSettings();

            Console.WriteLine("Feature Generation: [" + config.featureGeneratorMethod + "]");
            Console.WriteLine("Classification:     [" + config.classifierMethod + "]\n");
            Console.WriteLine("SoftNormalization:  [" + config.UseSoftNormalization + "]\n");

            // some parameters
            string path          = config.path;
            int    foldCount     = config.FoldCount;
            int    testFoldCount = config.TestFoldCount;

            string[] restrictTo = config.RestrictTo;
            string[] ignoreTags = config.IgnoreTags;

            // get all images
            List <TaggedImage>       images     = new List <TaggedImage>();
            Dictionary <string, int> tagIndices = new Dictionary <string, int>();

            foreach (string folderPath in Directory.GetDirectories(path))
            {
                foreach (string imagePath in Directory.GetFiles(folderPath))
                {
                    TaggedImage image = new TaggedImage(imagePath);

                    if (ignoreTags.Contains(image.Tag) || (restrictTo.Length != 0 && !restrictTo.Contains(image.Tag)))
                    {
                        continue;
                    }

                    images.Add(image);

                    if (!tagIndices.ContainsKey(image.Tag))
                    {
                        tagIndices.Add(image.Tag, tagIndices.Count);
                    }
                }
            }

            Console.WriteLine("starting feature vector generation [" + config.featureGeneratorMethod + "]\n");

            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // FEATURE GENERATOR                                                                              //
            ////////////////////////////////////////////////////////////////////////////////////////////////////

            FeatureGenerator <TaggedImage, float> featureGenerator;

            switch (config.featureGeneratorMethod)
            {
            case ImageUnderstandingConfig.FeatureGeneratorMethod.HOG:
                featureGenerator = new HOGFeatureGenerator();
                break;

            case ImageUnderstandingConfig.FeatureGeneratorMethod.SIFT:
                featureGenerator = new SIFTFeatureGenerator();
                break;

            case ImageUnderstandingConfig.FeatureGeneratorMethod.Random:
                featureGenerator = new RandomFeatureGenerator();
                break;

            case ImageUnderstandingConfig.FeatureGeneratorMethod.Unity:
                featureGenerator = new UnityFeatureGenerator();
                break;

            default:
                throw new Exception("Unknown Feature Generator Method");
            }

            featureGenerator.InitializeViaConfig(config);


            string tag = "";

            foreach (TaggedImage image in images)
            {
                if (tag != image.Tag)
                {
                    Console.WriteLine("generating feature vector: [" + image.Tag + "]");
                    tag = image.Tag;
                }
                image.FeatureVector = featureGenerator.GetFeatureVector(image);
            }

            featureGenerator.Dispose();

            if (config.UseSoftNormalization)
            {
                SoftNormalizeFeatureVectors(images);
            }

            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // FOLD ORGANIZER                                                                                 //
            ////////////////////////////////////////////////////////////////////////////////////////////////////
            FoldOrganizer <TaggedImage, string> foldOrganizer = new FoldOrganizer <TaggedImage, string>(images, foldCount, testFoldCount);

            ////////////////////////////////////////////////////////////////////////////////////////////////////
            // CONFUSION MATRIX                                                                               //
            ////////////////////////////////////////////////////////////////////////////////////////////////////
            Mat confusionMatrix = new Mat(tagIndices.Count, tagIndices.Count, DepthType.Cv32F, 1);

            // initialize with zeros
            for (int y = 0; y < confusionMatrix.Rows; ++y)
            {
                for (int x = 0; x < confusionMatrix.Cols; ++x)
                {
                    confusionMatrix.SetValue(x, y, 0F);
                }
            }

            Console.WriteLine("\nstarting Classification. [" + config.classifierMethod + "]");

            for (int iteration = 0; iteration < foldCount; ++iteration)
            {
                Console.WriteLine("\ncurrent iteration: " + iteration);

                Console.WriteLine("train classifier (" + iteration + ")");

                ////////////////////////////////////////////////////////////////////////////////////////////////////
                // CLASSIFIER                                                                                     //
                ////////////////////////////////////////////////////////////////////////////////////////////////////
                Classifier.Classifier <TaggedImage, string, float> classifier;

                switch (config.classifierMethod)
                {
                case ImageUnderstandingConfig.ClassifierMethod.KNearest:
                    classifier = new KNearestClassifier();
                    break;

                case ImageUnderstandingConfig.ClassifierMethod.Random:
                    classifier = new RandomClassifier <TaggedImage, string, float>();
                    break;

                case ImageUnderstandingConfig.ClassifierMethod.SingleResult:
                    classifier = new SingleResultClassifier();
                    break;

                case ImageUnderstandingConfig.ClassifierMethod.SVM:
                    classifier = new SVMClassifier();
                    break;

                default:
                    throw new Exception("Unknown Classifier Method");
                }
                classifier.InitializeViaConfig(config);

                classifier.Train(foldOrganizer.GetTrainingData(iteration));

                // evaluate Test set
                Console.WriteLine("testing (" + iteration + ")");

                List <TaggedImage> testSet = foldOrganizer.GetTestData(iteration);

                foreach (TaggedImage testDataSample in testSet)
                {
                    string evaluatedTag = classifier.Evaluate(testDataSample);

                    int indexOfRealTag      = tagIndices[testDataSample.Tag];
                    int indexOfEvaluatedTag = tagIndices[evaluatedTag];

                    float value = confusionMatrix.GetValue(indexOfRealTag, indexOfEvaluatedTag);
                    value += 1F / (float)foldOrganizer.GetTotalDataCount(testDataSample.Tag);

                    confusionMatrix.SetValue(indexOfRealTag, indexOfEvaluatedTag, value);
                }

                classifier.Dispose();

                foreach (KeyValuePair <string, int> tagIndexPair in tagIndices)
                {
                    float accuracy = confusionMatrix.GetValue(tagIndexPair.Value, tagIndexPair.Value);
                    Console.WriteLine("accuracy = " + string.Format("{0,12:#.0000}%", (accuracy * 100)) + ",\t " + tagIndexPair.Key);
                    //Console.WriteLine("accuracy = " + accuracy + ",\t " + tagIndexPair.Key);
                }
            }

            float        totalAccuracy = 0F;
            List <float> accuracies    = new List <float>();

            foreach (KeyValuePair <string, int> tagIndexPair in tagIndices)
            {
                accuracies.Add(confusionMatrix.GetValue(tagIndexPair.Value, tagIndexPair.Value));
                totalAccuracy += confusionMatrix.GetValue(tagIndexPair.Value, tagIndexPair.Value) / tagIndices.Count;
            }
            Console.WriteLine("total accuracy = " + string.Format("{0,12:#.0000}%", (totalAccuracy * 100)));
            Console.WriteLine("stdDeviation over all total accuracies = " + accuracies.ToArray().StdDeviation());


            for (int x = 0; x < tagIndices.Count; ++x)
            {
                for (int y = 0; y < tagIndices.Count; ++y)
                {
                    confusionMatrix.SetValue(x, y, (float)Math.Sqrt(Math.Sqrt(confusionMatrix.GetValue(x, y))));
                }
            }

            // perform Tests
            string s;

            Test.Test t = new Test.FoldOrganizer_Test();
            t.PerformTest(out s);
            Console.WriteLine(s);

            //visualize accuracy
            {
                String win1 = "Confusion Matrix"; //The name of the window
                CvInvoke.NamedWindow(win1);       //Create the window using the specific name

                int confusionMatrixScale = 5;

                Mat scaledConfusionMatrix = new Mat(confusionMatrix.Cols * confusionMatrixScale, confusionMatrix.Rows * confusionMatrixScale, confusionMatrix.Depth, confusionMatrix.NumberOfChannels);

                for (int y = 0; y < scaledConfusionMatrix.Rows; ++y)
                {
                    for (int x = 0; x < scaledConfusionMatrix.Cols; ++x)
                    {
                        scaledConfusionMatrix.SetValue(x, y, (float)confusionMatrix.GetValue(x / confusionMatrixScale, y / confusionMatrixScale));
                    }
                }

                CvInvoke.Imshow(win1, scaledConfusionMatrix); //Show the image
                CvInvoke.WaitKey(0);                          //Wait for the key pressing event
                CvInvoke.DestroyWindow(win1);                 //Destroy the window if key is pressed
            }
        }
        public override bool PerformTest(out string message)
        {
            message = "";

            // generate test set
            Dictionary <char, int> letterCountBindings = new Dictionary <char, int>();

            letterCountBindings['K'] = 9;
            letterCountBindings['L'] = 3;
            letterCountBindings['M'] = 10;
            letterCountBindings['O'] = 40;
            letterCountBindings['P'] = 7;

            List <TagName> tagNames = new List <TagName>();

            foreach (KeyValuePair <char, int> letterCountBinding in letterCountBindings)
            {
                for (int i = 0; i < letterCountBinding.Value; ++i)
                {
                    tagNames.Add(new TagName(letterCountBinding.Key + " " + i));
                }
            }

            // initialize FoldOrganizer
            int foldCount     = 3;
            int testFoldCount = 1;

            FoldOrganizer <TagName, char> foldOrganizer = new FoldOrganizer <TagName, char>(tagNames, foldCount, testFoldCount);


            // run test cases
            int targetSampleCount = 0;

            foreach (KeyValuePair <char, int> letterCountBinding in letterCountBindings)
            {
                targetSampleCount += letterCountBinding.Value;
            }

            if (targetSampleCount != foldOrganizer.TotalDataSampleCount)
            {
                message = "FoldOrganizer claims to have total Sample Count of " + foldOrganizer.TotalDataSampleCount + ". But should be " + targetSampleCount;

                return(false);
            }

            for (int iteration = 0; iteration < foldCount; ++iteration)
            {
                List <TagName> trainingData = foldOrganizer.GetTrainingData(iteration);
                List <TagName> testData     = foldOrganizer.GetTestData(iteration);

                foreach (TagName tagName in tagNames)
                {
                    if (!(trainingData.Contains(tagName) ^ testData.Contains(tagName)))
                    {
                        if (trainingData.Contains(tagName) && testData.Contains(tagName))
                        {
                            message = tagName.Name + " is contained in training Set AND in test Set.";
                        }
                        else
                        {
                            message = tagName.Name + " is contained NEITHER in training Set NOR in test Set.";
                        }

                        return(false);
                    }
                }
            }

            return(true);
        }