时间:2021-05-04 10:49:47 | 栏目:.NET代码 | 点击:次
在文章中,我们将对输入到机器学习模型中的数据集进行预处理。
这里我们将对一个硬币数据集进行预处理,以便以后在监督学习模型中进行训练。在机器学习中预处理数据集通常涉及以下任务:
这个例子我们将使用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,表示我们将要用来训练机器学习模型的数据集。这里我们有以下字段:
这是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);
}
}
下面是每个方法的说明:
在本系列中,我们将使用https://cvl.tuwien.ac.at/research/cvl-databases/coin-image-dataset/上的硬币图像数据集。
要加载数据集,我们可以在控制台应用程序的主类中包含以下内容:
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经验的读者准备的。