乐趣区

关于图像识别:C中的深度学习二预处理识别硬币的数据集

在文章中,咱们将对输出到机器学习模型中的数据集进行预处理。

这里咱们将对一个硬币数据集进行预处理,以便当前在监督学习模型中进行训练。在机器学习中预处理数据集通常波及以下工作:

  1. 清理数据——通过对四周数据的平均值或应用其余策略来填补数据缺失或损坏造成的破绽。
  2. 标准数据——将数据缩放值标准化到一个规范范畴,通常是 0 到 1。具备宽泛值范畴的数据可能会导致不标准,因而咱们将所有数据都放在一个公共范畴内。
  3. 一种热编码标签——将数据集中对象的标签或类编码为 N 维二进制向量,其中 N 是类的总数。数组元素都被设置为 0,除了与对象的类绝对应的元素,它被设置为 1。这意味着在每个数组中都有一个值为 1 的元素。
  4. 将输出数据集分为训练集和验证集——训练集被用于训练模型,验证集是用于查看咱们的训练后果。

这个例子咱们将应用 Numpy.NET,它基本上是 Python 中风行的 Numpy 库的.NET 版本。

Numpy 是一个专一于解决矩阵的库。

为了实现咱们的数据集处理器,咱们在 PreProcessing 文件夹中创立 Utils 类和 DataSet 类。Utils 类合并了一个动态 Normalize 办法,如下所示:

public class Utils
   {public static NDarray Normalize(string path)
       {
           var colorMode = Settings.Channels == 3 ? "rgb" : "grayscale";
           var img = ImageUtil.LoadImg(path, color_mode: colorMode, target_size: (Settings.ImgWidth, Settings.ImgHeight));
           return ImageUtil.ImageToArray(img) / 255;
       }

   }

在这种办法中,咱们用给定的色彩模式 (RGB 或灰度) 加载图像,并将其调整为给定的宽度和高度。而后咱们返回蕴含图像的矩阵,每个元素除以 255。每个元素除以 255 是使它们标准化,因为图像中任何像素的值都在 0 到 255 之间,所以通过将它们除以 255,咱们确保了新的范畴是 0 到 1,包含 255。

咱们还在代码中应用了一个 Settings 类。该类蕴含用于跨应用程序应用的许多常量。另一个类 DataSet,示意咱们将要用来训练机器学习模型的数据集。这里咱们有以下字段:

  1. _pathToFolder—蕴含图像的文件夹的门路。
  2. _extList—要思考的文件扩展名列表。
  3. _labels—_pathToFolder 中图像的标签或类。
  4. _objs - 图像自身,示意为 Numpy.NDarray。
  5. _validationSplit—用于将总图像数划分为验证集和训练集的百分比,在本例中,百分比将定义验证集与总图像数之间的大小。
  6. NumberClasses- 数据集中惟一类的总数。
  7. TrainX - 训练数据,示意为 Numpy.NDarray。
  8. TrainY - 训练标签,示意为 Numpy.NDarray。
  9. ValidationX—验证数据,示意为 Numpy.NDarray。
  10. ValidationY- 验证标签,示意为 Numpy.NDarray。

这是 DataSet 类:

public class DataSet
    {
        private string _pathToFolder;
        private string[] _extList;
        private List<int> _labels;
        private List<NDarray> _objs;
        private double _validationSplit;
        public int NumberClasses {get; set;}
        public NDarray TrainX {get; set;}
        public NDarray ValidationX {get; set;}
        public NDarray TrainY {get; set;}
        public NDarray ValidationY {get; set;}

        public DataSet(string pathToFolder, string[] extList, int numberClasses, double validationSplit)
        {
            _pathToFolder = pathToFolder;
            _extList = extList;
            NumberClasses = numberClasses;
            _labels = new List<int>();
            _objs = new List<NDarray>();
            _validationSplit = validationSplit;
        }

        public void LoadDataSet()
        {
            // Process the list of files found in the directory.
            string[] fileEntries = Directory.GetFiles(_pathToFolder);
            foreach (string fileName in fileEntries)
                if (IsRequiredExtFile(fileName))
                    ProcessFile(fileName);

            MapToClassRange();
            GetTrainValidationData();}

        private bool IsRequiredExtFile(string fileName)
        {foreach (var ext in _extList)
            {if (fileName.Contains("." + ext))
                {return true;}
            }

            return false;
        }

        private void MapToClassRange()
        {HashSet<int> uniqueLabels = _labels.ToHashSet();
            var uniqueLabelList = uniqueLabels.ToList();
            uniqueLabelList.Sort();

            _labels = _labels.Select(x => uniqueLabelList.IndexOf(x)).ToList();}

        private NDarray OneHotEncoding(List<int> labels)
        {var npLabels = np.array(labels.ToArray()).reshape(-1);
            return Util.ToCategorical(npLabels, num_classes: NumberClasses);
        }

        private void ProcessFile(string path)
        {_objs.Add(Utils.Normalize(path));
            ProcessLabel(Path.GetFileName(path));
        }

        private void ProcessLabel(string filename)
        {_labels.Add(int.Parse(ExtractClassFromFileName(filename)));
        }

        private string ExtractClassFromFileName(string filename)
        {return filename.Split('_')[0].Replace("class", "");
        }

        private void GetTrainValidationData()
        {var listIndices = Enumerable.Range(0, _labels.Count).ToList();
            var toValidate = _objs.Count * _validationSplit;
            var random = new Random();
            var xValResult = new List<NDarray>();
            var yValResult = new List<int>();
            var xTrainResult = new List<NDarray>();
            var yTrainResult = new List<int>();

            // Split validation data
            for (var i = 0; i < toValidate; i++)
            {var randomIndex = random.Next(0, listIndices.Count);
                var indexVal = listIndices[randomIndex];
                xValResult.Add(_objs[indexVal]);
                yValResult.Add(_labels[indexVal]);
                listIndices.RemoveAt(randomIndex);
            }

            // Split rest (training data)
            listIndices.ForEach(indexVal => 
            {xTrainResult.Add(_objs[indexVal]);
                yTrainResult.Add(_labels[indexVal]);
            });

            TrainY = OneHotEncoding(yTrainResult);
            ValidationY = OneHotEncoding(yValResult);
            TrainX = np.array(xTrainResult);
            ValidationX = np.array(xValResult);
        }
}

上面是每个办法的阐明:

  1. LoadDataSet()——类的主办法,咱们调用它来加载_pathToFolder 中的数据集。它调用上面列出的其余办法来实现此操作。
  2. IsRequiredExtFile(filename) – 查看给定文件是否蕴含至多一个应该为该数据集解决的扩展名(在_extList 中列出)。
  3. MapToClassRange() - 获取数据集中惟一标签的列表。
  4. ProcessFile(path) - 应用 Utils.Normalize 办法对图像进行规格化,并调用 ProcessLabel 办法。
  5. ProcessLabel(filename)——将 ExtractClassFromFileName 办法的后果增加为标签。
  6. ExtractClassFromFileName(filename) - 从图像的文件名中提取类。
  7. GetTrainValidationData()——将数据集划分为训练子数据集和验证子数据集。

在本系列中,咱们将应用 https://cvl.tuwien.ac.at/rese…。

要加载数据集,咱们能够在控制台应用程序的主类中蕴含以下内容:

var numberClasses = 60;
var fileExt = new string[] { ".png"};
var dataSetFilePath = @"C:/Users/arnal/Downloads/coin_dataset";
var dataSet = new PreProcessing.DataSet(dataSetFilePath, fileExt, numberClasses, 0.2);
dataSet.LoadDataSet();

咱们的数据当初能够输出到机器学习模型中。下一篇文章将介绍监督机器学习的基础知识,以及训练和验证阶段包含哪些内容。它是为没有 AI 教训的读者筹备的。

欢送关注我的公众号,如果你有喜爱的外文技术文章,能够通过公众号留言举荐给我。

退出移动版