Jak nauczyć sieć neuronową rozpoznawania obrazów z ML.NET
Chcesz nauczyć sieć neuronową, by rozpoznawała obrazy? Zobacz, jak zrobić to w ML.NET. Dzięki procesowi trenowania sieć będzie w stanie automatycznie klasyfikować obrazy. Rozróżni, czy na zdjęciu jest np. pies, czy kot. Ale nie tylko. Machine learning pozwolił rozwiązać problemy automatycznego klasyfikowania obrazów i jest powszechnie wykorzystywany w biznesie.
Jak działa ML.NET?
ML.NET jest biblioteką wspierającą uczenie maszynowe w środowisku Visual Studio w językach C# i F#.
Machine Learning polega na nauczeniu modelu sieci neuronowej przez proces trenowania (tj. wskazania sieci przykładów z zaszeregowaniem do odpowiedniej grupy odpowiedzi).
Dzięki wytrenowaniu sieć jest w stanie kwalifikować (szacować), jakiego typu jest dany obraz.
Przykład:
- W procesie uczenia, jako dane wejściowe ML.NET otrzymuje obraz wraz z informacją, czy jest to pies, czy kot.
- Sieć analizuje obrazy i sama decyduje, jakie cechy obrazu świadczą o tym, czy na obrazie jest pies, czy kot.
- Wyuczona sieć jest modelem sieci, który można powtórnie wykorzystać do rozróżnienia zdjęć innych niż podane w przykładach.
- Sieć przy podaniu obrazów innych niż te wykorzystane w procesie uczenia się, wskazuje, jakiej klasy jest obraz tzn. czy jest to kot, czy pies.
Z jakich bloków składa się podstawowa ścieżka aplikacji ML.NET?
- Przygotowanie danych wejściowych w odpowiedniej strukturze znanej dla silnika ML.NET.
- Uczenie się sieci przez przykłady.
- Proces predykcji wyników klasyfikacji przez podanie wyuczonemu modelowi do oszacowania danych innych niż przykładowe.
Czym jest i jak użyć Model Builder dla ML.NET?
Model Builder jest nakładką w Visual Studio do budowania modeli ML poprzez kreator.
Zobacz, jak krok po kroku zbudować model ML:
1. Uruchom Model Builder na projekcie kliknij prawy przycisk myszy i wybierz Add -> Machine Learning Model.
2. W oknie poniżej wybierz scenariusz, który Cię interesuje.
3. Po wybraniu scenariusza klasyfikacji obrazów (Image Classification Local ML), wybierz lokalne środowisko trenowania modelu:
4. Po kliknięciu następnego kroku "Data", wybierz katalog z przykładami do trenowania.
Uwaga!!! Drzewo katalogów musi być przygotowane, jak w przykładzie po prawej stronie tj. obrazy z danej klasy muszą być umieszczony w tym samym podkatalogu o nazwie klasy.
5. Następny krok to uczenie modelu rozpoznawania obrazów – w tym przypadku psów i kotów.
6. Podczas procesu uczenia w Output zobaczysz, w jaki sposób przebiega profilowanie modelu.
7. Proces trenowania trwa dłuższą chwilę, po zakończeniu otrzymasz wynik z wybranym modelem i jakością jego działania.
Dodatkowo kod c# zostanie wygenerowany do 2 projektów (ML.ConsoleApp i ML.Model), których opis znajdziesz poniżej.
8. Jeśli chcesz sprawdzić jakość wyuczenia sieci eksperymentalnie, wybierz obraz, który nie był podany w przykładach. Przejdź do kroku „Evaluate” i wybierz obraz.
Wyuczona sieć zdecyduje, jakiej klasy jest obraz oraz poda, jakie jest prawdopodobieństwo, że odpowiedź jest poprawna.
9. W ostatnim kroku dołącz wygenerowany kod do aktualnego rozwiązania (Solution w Visual Studio) poprzez kliknięcie Code, a następnie Add Projects. Kreator pokaże następne kroki, które możesz wykonać.
Jakie rzeczywiste case'y można rozwiązać dzięki ML.NET?
Deep Learning (podzbiór ML) pozwolił rozwiązać problemy automatycznego klasyfikowania obrazów. Dziś jest wykorzystywany do wielu celów, także w biznesie. Pozwala m.in. rozpoznawać typ dokumentu poprzez identyfikację layoutu, rozpoznawać, czy na dokumencie jest pismo odręczne, weryfikować, czy na obrazie jest dowód osobisty.
Lista modeli, które zostały wyuczone z modelu TensorFlow wstępnie wytrenowanego do klasyfikowania obrazu:
- model klasyfikujący, czy na obrazie znajduje się dokument dowodu osobistego (używany na potrzeby rozpoznawania danych wrażliwych),
- model, który na podstawie obrazu skanu dokumentu, kwalifikuje typ dokumentu w ramach skończonej listy formularzy dostępnych w banku (używany na potrzeby wybrania właściwej ścieżki procesowania w systemie obiegu korespondencji),
- model klasyfikujący, czy na obrazie znajdują się dane wpisane pismem odręcznym, czy wyłącznie maszynowo i ewentualnie podpisy/data/miejscowość (używany na potrzeby decyzji, czy dokument może być skutecznie ocr'owany).
Przykłady kodu procesów trenowania modelu i wykorzystania wytrenowanego modelu w predykcji obrazów:
ścieżka trenowania:
// Initialize our user-defined progress handler that AutoML will
// invoke after each model it produces and evaluates.
var progressHandler = new MulticlassExperimentProgressHandler();
// Run an AutoML multiclass classification experiment
LogMessage("=============== Running AutoML experiment ===============\n");
LogMessage($"Running AutoML multiclass classification experiment for at most {TRAINING_EXPERIMENT_TIME} seconds...\n");
ExperimentResult<MulticlassClassificationMetrics> experimentResult = mlContext.Auto()
.CreateMulticlassClassificationExperiment(TRAINING_EXPERIMENT_TIME)
.Execute(trainData: trainData, labelColumnName: "Label", progressHandler: progressHandler);
// Print top models found by AutoML
PrintTopModels(experimentResult);
// Select the best model and print metrics
RunDetail<MulticlassClassificationMetrics> bestRun = experimentResult.BestRun;
ITransformer trainedModel = bestRun.Model;
LogMessage($"Saving model to {TRAINING_MODEL_PATH_NAME}");
// Save/persist the trained model to a .ZIP file
RenameFileIfExists(TRAINING_MODEL_PATH_NAME);
mlContext.Model.Save(trainedModel, trainData.Schema, TRAINING_MODEL_PATH_NAME);
LogMessage($"The model is saved to {TRAINING_MODEL_PATH_NAME}");
ścieżki klasyfikacji:
var engineInputData = GenerateEngineInputData(testImagesMapping);
var predictions = new List<Prediction>();
var allModelClasses = GetAllClassesFromModel(PredictionEngine.Value.OutputSchema);
LogMessage($"\n\nPrediction started at: {DateTime.Now.ToString(dateTimeFormatLog)}");
LogMessage("Using model to make predictions -- Comparing actual Label with predicted Label from sample data...\n\n");
foreach (var sampleData in engineInputData)
{
var predictionResult = Predict(sampleData);
var indexOfClassByName = allModelClasses.FirstOrDefault(x => x.Value == predictionResult.Prediction).Key;
var scoreForSpecificFile = predictionResult.Score[indexOfClassByName];
LogMessage($"Image: {sampleData.ImageSource} | Predicted class: {predictionResult.Prediction.ToUpper()} | Score: {scoreForSpecificFile}");
LogMessage($"Scores for classes: [{ String.Join(" ; ", predictionResult.Score)}]");
predictions.Add(new Prediction()
{
Path = sampleData.ImageSource,
PredictedLabel = predictionResult.Prediction,
Score = predictionResult.Score
});
}
LogMessage($"Prediction ended at: {DateTime.Now.ToString(dateTimeFormatLog)}");
ClearTemporaryFilesClassification(inputFilesPath);
var predictionsAboveMinScore = GetPredictionsAboveMinScore(predictions, MINIMUM_SCORE);
CopyResultToFolderAssociatedWithClass(inputFilesPath, predictionsAboveMinScore, testImagesMapping);
LogMessage("================= End of classification process =================");
private static Lazy<PredictionEngine<ModelInput, ModelOutput>> PredictionEngine = new Lazy<PredictionEngine<ModelInput, ModelOutput>>(CreatePredictionEngine);
// For more info on consuming ML.NET models, visit https://aka.ms/mlnet-consume
// Method for consuming model in your app
public static ModelOutput Predict(ModelInput input)
{
ModelOutput result = PredictionEngine.Value.Predict(input);
return result;
}
public static PredictionEngine<ModelInput, ModelOutput> CreatePredictionEngine()
{
// Create new MLContext
MLContext mlContext = new MLContext();
// Load model & create prediction engine
string modelPath = TRAINING_MODEL_PATH_NAME;
ITransformer mlModel = mlContext.Model.Load(modelPath, out var modelInputSchema);
var predEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);
return predEngine;
}
Przydatne linki:
- ML.NET dokumentacja na MSDN;
- ML.NET framework;
- LearnML.NET.
Przykłady wykorzystania
- ML.NET;
- ML.NET tutorial'e;
- Oficjalny kanał na YT;
- Kanał YT z różnymi tutorialami ML.NET.