1. 程式人生 > 實用技巧 >使用 ML.NET 識別樂高顏色塊

使用 ML.NET 識別樂高顏色塊

每一個樂高迷都擁有很多的顏色塊,需要進行排序和按型別分揀,按照《Organizing your LEGO Bricks》或許有所幫助,但這不是一個簡單的任務,因為有很多顏色塊有非常微妙的差異。如果換作一個典型的程式設計師可以做什麼來解決這個問題呢?你猜對了 - 建立一個程式使用 ML.NET 來識別樂高的顏色塊。

首先,我們將建立一個控制檯應用並新增所需的包

> dotnet new console
> dotnet add package Microsoft.ML
> dotnet add package Microsoft.ML.Vision
> dotnet add package Microsoft.ML.ImageAnalytics
> dotnet add package SciSharp.TensorFlow.Redist

在專案資料夾的根目錄中,我將建立一個名為 pieces 的子資料夾,並在此資料夾中建立一些顏色分類的子資料夾,放置訓練集中的每種顏色的圖片。

使用時,我們需要定義輸入和輸出模型(分類器提供分類結果)。

public class ModelInput
{
    public string Label { get; set; }
    public string ImageSource { get; set; }
}
 
public class ModelOutput
{
    public
String PredictedLabel { get; set; } }

為了訓練模型,我們首先建立一個由目錄中的影象組成的輸入資料集,並將其作為標籤分配它們位於的目錄的名稱。在此之後,我們建立訓練管道,最後,使用資料進行訓練以建立模型。

static void TrainModel()
{
    // Create the input dataset
    var inputs = new List<ModelInput>();
    foreach (var subDir in Directory.GetDirectories(inputDataDirectoryPath))
    {
        
foreach (var file in Directory.GetFiles(subDir)) { inputs.Add(new ModelInput() { Label = subDir.Split("\\").Last(), ImageSource = file }); } } var trainingDataView = mlContext.Data.LoadFromEnumerable<ModelInput>(inputs); // Create training pipeline var dataProcessPipeline = mlContext.Transforms.Conversion.MapValueToKey("Label", "Label") .Append(mlContext.Transforms.LoadRawImageBytes("ImageSource_featurized", null, "ImageSource")) .Append(mlContext.Transforms.CopyColumns("Features", "ImageSource_featurized")); var trainer = mlContext.MulticlassClassification.Trainers.ImageClassification(new ImageClassificationTrainer.Options() { LabelColumnName = "Label", FeatureColumnName = "Features" }) .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "PredictedLabel")); IEstimator<ITransformer> trainingPipeline = dataProcessPipeline.Append(trainer); // Create the model mlModel = trainingPipeline.Fit(trainingDataView); }

現在,使用這個訓練模型,我們可以嘗試對一個新影象進行分類。通過為其中一個影象建立模型輸入,然後將它傳遞到使用分類器構建的模型建立的預測引擎。

static ModelOutput Classify(string filePath)
{
    // Create input to classify
    ModelInput input = new ModelInput() { ImageSource = filePath };
    // Load model and predict
    var predEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);
    return predEngine.Predict(input);
}

最後讓我們用4種不同的顏色來測試這一點。

static void Main()
{
    TrainModel();
 
    var result = Classify(Environment.CurrentDirectory + Path.DirectorySeparatorChar + "Black.jpg");
    Console.WriteLine($"Testing with black piece. Prediction: {result.PredictedLabel}.");
    result = Classify(Environment.CurrentDirectory + Path.DirectorySeparatorChar + "Blue.jpg");
    Console.WriteLine($"Testing with blue piece. Prediction: {result.PredictedLabel}.");
    result = Classify(Environment.CurrentDirectory + Path.DirectorySeparatorChar + "Green.jpg");
    Console.WriteLine($"Testing with green piece. Prediction: {result.PredictedLabel}.");
    result = Classify(Environment.CurrentDirectory + Path.DirectorySeparatorChar + "Yellow.jpg");
    Console.WriteLine($"Testing with yellow piece. Prediction: {result.PredictedLabel}.");
}

結果如圖所示。

4張圖片對了3個!略微有點令人失望。但這是一個很好的開始,因為它給了我們機會去深入,並試圖瞭解如何改進分類,使其更準確。也許它需要更多的訓練資料,也許有更好的分類演算法我們可以使用!

專案完整示例程式碼和訓練資料在GIthub上:https://github.com/BeanHsiang/Vainosamples/tree/master/CSharp/ML/LegoColorIdentifier