Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Naučte se trénovat vlastní model hlubokého učení pomocí přenosového učení, předtrénovaného modelu TensorFlow a API pro klasifikaci obrázků ML.NET za účelem klasifikace obrázků betonových ploch jako prasklé nebo nezablokované.
V tomto kurzu se naučíte:
- Pochopení problému
- Další informace o rozhraní API pro klasifikaci obrázků ML.NET
- Vysvětlení předem natrénovaného modelu
- Použití přeneseného učení pro natrénování vlastního modelu klasifikace obrázků v TensorFlow
- Klasifikace obrázků pomocí vlastního modelu
Požadavky
Pochopení problému
Klasifikace obrázků je problém počítačového zpracování obrazu. Klasifikace obrázků přebírá obrázek jako vstup a kategorizuje ho do předepsané třídy. Modely klasifikace obrázků se běžně trénují pomocí hlubokého učení a neurálních sítí. Další informace najdete v tématu Hluboké učení vs. strojové učení.
Mezi scénáře, ve kterých je klasifikace obrázků užitečná, patří:
- Rozpoznávání obličeje
- Detekce emocí
- Lékařská diagnostika
- Detekce orientačních bodů
Tento kurz trénuje vlastní model klasifikace obrázků, který provádí automatizovanou vizuální kontrolu mostových palub za účelem identifikace struktur, které jsou poškozeny trhlinami.
rozhraní API pro klasifikaci obrázků ML.NET
ML.NET poskytuje různé způsoby klasifikace obrázků. Tento kurz používá výuku přenosu pomocí rozhraní API pro klasifikaci obrázků. Rozhraní API pro klasifikaci obrázků využívá TensorFlow.NET, což je knihovna nízké úrovně, která poskytuje vazby jazyka C# pro rozhraní API C++ TensorFlow.
Co je transferové učení?
Transfer learning využívá znalosti získané z řešení jednoho problému na jiný související problém.
Trénování modelu hlubokého učení od začátku vyžaduje nastavení několika parametrů, velké množství trénovacích dat s popiskem a obrovské množství výpočetních prostředků (stovky hodin GPU). Použití předem natrénovaného modelu spolu s transferovým učením umožňuje zástupce procesu trénování.
Proces trénování
Rozhraní API pro klasifikaci obrázků spustí proces trénování načtením předem natrénovaného modelu TensorFlow. Proces trénování se skládá ze dvou kroků:
- Fáze kritického bodu.
- Fáze trénování.
Fáze kritického bodu
Během fáze kritického bodu se načte sada trénovacích obrázků a hodnoty pixelů se použijí jako vstup nebo funkce pro ukotvené vrstvy předem natrénovaného modelu. Ukotvené vrstvy zahrnují všechny vrstvy v neurální síti až do předposlední vrstvy, která se neformálně označuje jako kritická vrstva. Tyto vrstvy se označují jako zablokované, protože na těchto vrstvách nedojde k žádnému trénování a operace jsou průchozí. Je to v těchto ukotvených vrstvách, kde se vypočítávají vzory nižší úrovně, které pomáhají modelu rozlišovat mezi různými třídami. Čím větší je počet vrstev, tím více je tento krok výpočetně náročný. Vzhledem k tomu, že se jedná o jednorázový výpočet, je možné výsledky uložit do mezipaměti a použít je v pozdějších spuštěních při experimentování s různými parametry.
Fáze trénování
Jakmile se vypočítá výstupní hodnoty z fáze kritického bodu, použijí se jako vstup k opětovnému trénování konečné vrstvy modelu. Tento proces je iterativní a spouští se tolikrát, kolikrát je určeno parametry modelu. Během každého spuštění se vyhodnotí ztráta a přesnost. Pak jsou provedeny příslušné úpravy, aby se model zlepšil s cílem minimalizovat ztrátu a maximalizovat přesnost. Po dokončení trénování jsou výstupem dva formáty modelu. Jednou z nich je .pb verze modelu a druhá je .zip ML.NET serializovaná verze modelu. Při práci v prostředích podporovaných ML.NET se doporučuje použít .zip verzi modelu. V prostředích, kde se ML.NET nepodporuje, ale máte možnost použít .pb verzi.
Vysvětlení předem natrénovaného modelu
Předtrénovaný model použitý v tomto kurzu je 101vrstvá varianta modelu Reziduální sítě (ResNet) v2. Původní model se vytrénuje tak, aby klasifikoval obrázky do tisíc kategorií. Model přebírá jako vstup obrázek o velikosti 224 x 224 a vypíše pravděpodobnosti třídy pro každou z tříd, na které je trénován. Část tohoto modelu se používá k trénování nového modelu pomocí vlastních obrázků k vytváření předpovědí mezi dvěma třídami.
Vytvoření konzolové aplikace
Teď, když máte obecný přehled o přenosu učení a rozhraní API pro klasifikaci obrázků, je čas vytvořit aplikaci.
Vytvořte konzolovou aplikaci jazyka C# s názvem "DeepLearning_ImageClassification_Binary". Klikněte na tlačítko Next.
Jako rozhraní zvolte .NET 8, které chcete použít, a pak vyberte Vytvořit.
Nainstalujte balíček NuGet Microsoft.ML:
Poznámka:
Tato ukázka používá nejnovější stabilní verzi uvedených balíčků NuGet, pokud není uvedeno jinak.
- V Průzkumníku řešení klikněte pravým tlačítkem na projekt a vyberte Spravovat balíčky NuGet.
- Jako zdroj balíčku zvolte nuget.org.
- Vyberte kartu Procházet.
- Zaškrtněte políčko Zahrnout předběžné verze .
- Vyhledejte Microsoft.ML.
- Vyberte tlačítko Instalovat.
- Pokud souhlasíte s licenčními podmínkami pro uvedené balíčky, vyberte tlačítko Přijmout.
- Opakujte tyto kroky pro balíčky NuGet Microsoft.ML.Vision, SciSharp.TensorFlow.Redist (verze 2.3.1) a Microsoft.ML.ImageAnalytics NuGet.
Příprava a pochopení dat
Poznámka:
Datové sady pro tento kurz jsou od Marca Maguirea, Sattara Dorafshana a Roberta J. Thomase, "SDNET2018: datová sada obrazů trhlin v betonu pro aplikace strojového učení" (2018). Projděte si všechny datové sady. Papír 48. https://digitalcommons.usu.edu/all_datasets/48
SDNET2018 je datová sada obrázků, která obsahuje poznámky pro prasklé a nelomené betonové konstrukce (mostové paluby, zdi a chodník).
Data jsou uspořádaná do tří podadresářů:
- D obsahuje obrázky mostovek
- P obsahuje obrázky chodníku
- W obsahuje obrázky zdí
Každý z těchto podadresářů obsahuje dva další podadresáře s předponou:
- C je předpona používaná pro prasklé povrchy.
- U je předpona použitá pro nezakryvné povrchy.
V tomto kurzu se používají pouze obrázky mostových palub.
- Stáhněte datovou sadu a rozbalte ji.
- Vytvořte v projektu adresář s názvem Assets a uložte soubory datové sady.
- Zkopírujte podadresáře CD a UD z nedávno rozbaleného adresáře do adresáře Assets .
Vytvoření vstupních a výstupních tříd
Otevřete soubor Program.cs a nahraďte stávající obsah následujícími
usingdirektivami:using Microsoft.ML; using Microsoft.ML.Vision; using static Microsoft.ML.DataOperationsCatalog;Vytvořte třídu s názvem
ImageData. Tato třída se používá k reprezentaci původně načtených dat.class ImageData { public string? ImagePath { get; set; } public string? Label { get; set; } }ImageDataobsahuje následující vlastnosti:-
ImagePathje plně kvalifikovaná cesta, kde je image uložená. -
Labelje kategorie, do které image patří. Jedná se o hodnotu, která se má předpovědět.
-
Vytvořte třídy pro vstupní a výstupní data.
ImageDataPod třídou definujte schéma vstupních dat v nové třídě s názvemModelInput.class ModelInput { public byte[]? Image { get; set; } public uint LabelAsKey { get; set; } public string? ImagePath { get; set; } public string? Label { get; set; } }ModelInputobsahuje následující vlastnosti:-
Imagebyte[]je reprezentace obrázku. Model očekává, že data obrázků budou pro trénování tohoto typu. -
LabelAsKeyje číselná reprezentaceLabel. -
ImagePathje plně kvalifikovaná cesta, kde je image uložená. -
Labelje kategorie, do které image patří. Jedná se o hodnotu, která se má předpovědět.
Pouze
ImageaLabelAsKeyslouží k trénování modelu a k vytváření předpovědí. VlastnostiImagePathaLabelvlastnosti jsou zachovány pro usnadnění přístupu k původnímu názvu a kategorii souboru obrázku.-
Pak pod
ModelInputtřídou definujte schéma výstupních dat v nové třídě s názvemModelOutput.class ModelOutput { public string? ImagePath { get; set; } public string? Label { get; set; } public string? PredictedLabel { get; set; } }ModelOutputobsahuje následující vlastnosti:-
ImagePathje plně kvalifikovaná cesta, kde je image uložená. -
Labelje původní kategorie, do které image patří. Jedná se o hodnotu, která se má předpovědět. -
PredictedLabelje hodnota predikovaná modelem.
ModelInputPodobně jako v případě, že se k předpovědím vyžaduje pouzePredictedLabelto, že obsahuje predikci provedenou modelem. VlastnostiImagePathaLabeljsou zachovány pro snadný přístup k původnímu názvu souboru obrázku a jeho kategorii.-
Definování cest a inicializace proměnných
usingDo direktiv přidejte následující kód:Definujte umístění prostředků.
Inicializace
mlContextproměnné pomocí nové instance MLContext.TŘÍDA MLContext je výchozím bodem pro všechny operace ML.NET a inicializace mlContext vytvoří nové ML.NET prostředí, které lze sdílet napříč objekty pracovního postupu vytváření modelu. Je to podobné, koncepčně,
DbContextv Entity Frameworku.
var projectDirectory = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../")); var assetsRelativePath = Path.Combine(projectDirectory, "Assets"); MLContext mlContext = new();
Načtení dat
Vytvoření metody nástroje pro načítání dat
Obrázky jsou uložené ve dvou podadresářích. Před načtením dat je potřeba je naformátovat do seznamu ImageData objektů. Uděláte to tak, že vytvoříte metodu LoadImagesFromDirectory :
static IEnumerable<ImageData> LoadImagesFromDirectory(string folder, bool useFolderNameAsLabel = true)
{
var files = Directory.GetFiles(folder, "*",
searchOption: SearchOption.AllDirectories);
foreach (var file in files)
{
if ((Path.GetExtension(file) != ".jpg") && (Path.GetExtension(file) != ".png"))
continue;
var label = Path.GetFileName(file);
if (useFolderNameAsLabel)
label = Directory.GetParent(file)?.Name;
else
{
for (int index = 0; index < label.Length; index++)
{
if (!char.IsLetter(label[index]))
{
label = label[..index];
break;
}
}
}
yield return new ImageData()
{
ImagePath = file,
Label = label
};
}
}
Metoda LoadImagesFromDirectory:
- Získá všechny cesty k souborům z podadresářů.
- Prochází jednotlivé soubory pomocí
foreachpříkazu a kontroluje, zda jsou podporovány přípony souborů. Rozhraní API pro klasifikaci obrázků podporuje formáty JPEG a PNG. - Získá popisek souboru.
useFolderNameAsLabelPokud je parametr nastaven natrue, nadřazený adresář, kde je soubor uložen, se použije jako popisek. Jinak očekává, že popisek bude předponou názvu souboru nebo samotného názvu souboru. - Vytvoří novou instanci .
ModelInput
Příprava dat
Přidejte následující kód za řádek, do kterého vytvoříte novou instanci MLContext.
IEnumerable<ImageData> images = LoadImagesFromDirectory(folder: assetsRelativePath, useFolderNameAsLabel: true);
IDataView imageData = mlContext.Data.LoadFromEnumerable(images);
IDataView shuffledData = mlContext.Data.ShuffleRows(imageData);
var preprocessingPipeline = mlContext.Transforms.Conversion.MapValueToKey(
inputColumnName: "Label",
outputColumnName: "LabelAsKey")
.Append(mlContext.Transforms.LoadRawImageBytes(
outputColumnName: "Image",
imageFolder: assetsRelativePath,
inputColumnName: "ImagePath"));
IDataView preProcessedData = preprocessingPipeline
.Fit(shuffledData)
.Transform(shuffledData);
TrainTestData trainSplit = mlContext.Data.TrainTestSplit(data: preProcessedData, testFraction: 0.3);
TrainTestData validationTestSplit = mlContext.Data.TrainTestSplit(trainSplit.TestSet);
IDataView trainSet = trainSplit.TrainSet;
IDataView validationSet = validationTestSplit.TrainSet;
IDataView testSet = validationTestSplit.TestSet;
Předchozí kód:
Zavolá nástrojovou metodu
LoadImagesFromDirectory, aby po inicializaci proměnnémlContextzískala seznam obrázků použitých pro trénování.Načte obrázky do
IDataViewmetody.LoadFromEnumerablePomocí metody prohazuje data
ShuffleRows. Data se načtou v pořadí, v jakém byla načtena z adresářů. Za účelem vyvážení se provede náhodné prohodí.Před trénováním provede určité předběžné zpracování dat. To se provádí, protože modely strojového učení očekávají, že vstup bude v číselném formátu. Kód předběžného zpracování vytvoří složený
EstimatorChainzMapValueToKeytěchto aLoadRawImageBytestransformací. TransformaceMapValueToKeypřebírá kategorickou hodnotu veLabelsloupci, převede ji na číselnouKeyTypehodnotu a uloží ji do nového sloupce s názvemLabelAsKey.LoadImagespřebírá hodnoty ze sloupceImagePathspolu s parametremimageFolderpro načtení obrázků pro trénink.Použije metodu
Fitk použití dat napreprocessingPipelineEstimatorChainnásledovanou metoduTransform, která vrátíIDataViewobsahující předem zpracovaná data.Rozdělí data na trénovací, ověřovací a testovací sady.
Pro trénování modelu je důležité mít trénovací datovou sadu i ověřovací datovou sadu. Model se vytrénuje v trénovací sadě. Jak dobře se predikce u nezoznaných dat měří výkonem oproti ověřovací sadě. Na základě výsledků tohoto výkonu model provádí úpravy toho, co se naučil při úsilí o zlepšení. Ověřovací sada může pocházet z rozdělení původní datové sady nebo z jiného zdroje, který už byl pro tento účel vyhrazen.
Ukázka kódu provádí dvě rozdělení. Nejprve se předzpracovaná data rozdělí a pro trénování se použije 70%, zatímco zbývajících 30% se použije k ověření. Poté je sada ověřování 30% dále rozdělena do ověřovacích a testovacích sad, kde se k ověření používá 90% a k testování se používá 10%.
Jedním ze způsobů, jak přemýšlet o účelu těchto datových oddílů, je přirovnání ke zkoušce. Při studiu zkoušky si prohlédnete poznámky, knihy nebo jiné zdroje informací, abyste získali přehled o konceptech, které jsou na zkoušce. To je to, k čemu je vlaková souprava určena. Pak si můžete udělat napodobenou zkoušku, abyste ověřili své znalosti. Tady se hodí ověřovací sada. Před provedením skutečné zkoušky chcete zkontrolovat, jestli máte dobrý přehled o konceptech. Na základě těchto výsledků si poznamenejte, co jste udělali špatně nebo čemu jste nerozuměli dobře a při přípravě na skutečnou zkoušku zapracujete změny. Nakonec si vezmi zkoušku. Toto je to, k čemu se testovací sada používá. Otázky na zkoušce jste ještě nikdy neviděli, a nyní využijte toho, co jste si osvojili během tréninku a validace, abyste své znalosti použili k dokončení úkolu.
Přiřadí oddíly jejich odpovídající hodnoty pro trénovací, ověřovací a testovací data.
Definování trénovacího kanálu
Trénování modelu se skládá ze dvou kroků. Nejprve se k trénování modelu používá rozhraní API pro klasifikaci obrázků. Potom se kódované popisky ve PredictedLabel sloupci převedou zpět na původní kategorickou hodnotu pomocí MapKeyToValue transformace.
var classifierOptions = new ImageClassificationTrainer.Options()
{
FeatureColumnName = "Image",
LabelColumnName = "LabelAsKey",
ValidationSet = validationSet,
Arch = ImageClassificationTrainer.Architecture.ResnetV2101,
MetricsCallback = (metrics) => Console.WriteLine(metrics),
TestOnTrainSet = false,
ReuseTrainSetBottleneckCachedValues = true,
ReuseValidationSetBottleneckCachedValues = true
};
var trainingPipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions)
.Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
ITransformer trainedModel = trainingPipeline.Fit(trainSet);
Předchozí kód:
Vytvoří novou proměnnou pro uložení sady povinných a volitelných parametrů pro objekt ImageClassificationTrainer. Má ImageClassificationTrainer několik volitelných parametrů:
-
FeatureColumnNameje sloupec, který se používá jako vstup pro model. -
LabelColumnNameje sloupec pro hodnotu, která se má předpovědět. -
ValidationSetIDataViewje obsahující ověřovací data. -
Archdefinuje, které z předem natrénovaných architektur modelu se mají použít. Tento kurz používá variantu s 101 vrstvami modelu ResNetv2. -
MetricsCallbackvytvoří vazbu funkce ke sledování průběhu trénování. -
TestOnTrainSetinformuje model, aby změřil výkon na trénovací sadě, pokud není k dispozici žádná ověřovací sada. -
ReuseTrainSetBottleneckCachedValuesříká modelu, jestli se mají v následujících spuštěních používat hodnoty uložené v mezipaměti z fáze kritického bodu. Fáze kritického bodu je jednorázová průchozí výpočet, který je výpočetně náročný při prvním provedení. Pokud se trénovací data nezmění a chcete experimentovat s jiným počtem epoch nebo velikostí dávky, použití hodnot uložených v mezipaměti výrazně zkracuje dobu potřebnou k trénování modelu. -
ReuseValidationSetBottleneckCachedValuesje podobnáReuseTrainSetBottleneckCachedValuesjenom tomu, že v tomto případě se jedná o ověřovací datovou sadu.
-
EstimatorChainDefinuje trénovací kanál, který se skládá zemapLabelEstimatorsouboru i ImageClassificationTrainerz .Použije metodu
Fitk trénování modelu.
Použijte model
Teď, když jste model vytrénovali, je čas ho použít ke klasifikaci obrázků.
Vytvořte novou metodu nástroje volanou OutputPrediction k zobrazení informací o predikci v konzole.
static void OutputPrediction(ModelOutput prediction)
{
string? imageName = Path.GetFileName(prediction.ImagePath);
Console.WriteLine($"Image: {imageName} | Actual Value: {prediction.Label} | Predicted Value: {prediction.PredictedLabel}");
}
Klasifikace jednoho obrázku
Vytvořte metodu volanou
ClassifySingleImagek vytvoření a výstupu jedné předpovědi obrázku.static void ClassifySingleImage(MLContext mlContext, IDataView data, ITransformer trainedModel) { PredictionEngine<ModelInput, ModelOutput> predictionEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(trainedModel); ModelInput image = mlContext.Data.CreateEnumerable<ModelInput>(data, reuseRowObject: true).First(); ModelOutput prediction = predictionEngine.Predict(image); Console.WriteLine("Classifying single image"); OutputPrediction(prediction); }Metoda
ClassifySingleImage:-
PredictionEngineVytvoří uvnitřClassifySingleImagemetody. Jedná sePredictionEngineo pohodlné rozhraní API, které umožňuje předávat a pak provádět predikci pro jednu instanci dat. - Pokud chcete získat přístup k jedné
ModelInputinstanci, převededataIDataViewnaIEnumerablepomocí metodyCreateEnumerablea pak získá první pozorování. - Použije metodu
Predictke klasifikaci obrázku. - Vypíše predikci do konzoly pomocí
OutputPredictionmetody.
-
Zavolejte
ClassifySingleImagepoté, co zavoláte metoduFitpomocí testovací sady obrázků.ClassifySingleImage(mlContext, testSet, trainedModel);
Klasifikace více obrázků
Vytvořte metodu volanou
ClassifyImagesk vytvoření a výstupu několika předpovědí obrázků.static void ClassifyImages(MLContext mlContext, IDataView data, ITransformer trainedModel) { IDataView predictionData = trainedModel.Transform(data); IEnumerable<ModelOutput> predictions = mlContext.Data.CreateEnumerable<ModelOutput>(predictionData, reuseRowObject: true).Take(10); Console.WriteLine("Classifying multiple images"); foreach (var prediction in predictions) { OutputPrediction(prediction); } }Metoda
ClassifyImages:- Pomocí metody vytvoří
IDataViewobsahující predikceTransform. - Aby bylo možné iterovat nad předpověďmi, převede
predictionDataIDataViewnaIEnumerablepomocí metodyCreateEnumerablea poté získá prvních 10 pozorování. - Iteruje a vypíše původní a předpovězené popisky předpovědí.
- Pomocí metody vytvoří
Volání
ClassifyImagespo voláníClassifySingleImage()metody pomocí testovací sady obrázků.ClassifyImages(mlContext, testSet, trainedModel);
Spuštění aplikace
Spusťte konzolovou aplikaci. Výstup by měl být podobný následujícímu výstupu.
Poznámka:
Může se zobrazit upozornění nebo zpracování zpráv; tyto zprávy byly z následujících výsledků odebrány, aby byly přehledné. Pro stručnost byl výstup zhuštěný.
Fáze kritického bodu
Pro název obrázku se nevytiskne žádná hodnota, protože obrázky se načtou byte[] jako název obrázku, takže se nezobrazí žádný název obrázku.
Phase: Bottleneck Computation, Dataset used: Train, Image Index: 279
Phase: Bottleneck Computation, Dataset used: Train, Image Index: 280
Phase: Bottleneck Computation, Dataset used: Validation, Image Index: 1
Phase: Bottleneck Computation, Dataset used: Validation, Image Index: 2
Fáze trénování
Phase: Training, Dataset used: Validation, Batch Processed Count: 6, Epoch: 21, Accuracy: 0.6797619
Phase: Training, Dataset used: Validation, Batch Processed Count: 6, Epoch: 22, Accuracy: 0.7642857
Phase: Training, Dataset used: Validation, Batch Processed Count: 6, Epoch: 23, Accuracy: 0.7916667
Klasifikace výstupu obrázků
Classifying single image
Image: 7001-220.jpg | Actual Value: UD | Predicted Value: UD
Classifying multiple images
Image: 7001-220.jpg | Actual Value: UD | Predicted Value: UD
Image: 7001-163.jpg | Actual Value: UD | Predicted Value: UD
Image: 7001-210.jpg | Actual Value: UD | Predicted Value: UD
Při kontrole 7001-220.jpg obrázku můžete ověřit, že není prasklý, jak model predikoval.
Gratulujeme! Teď jste úspěšně vytvořili model hlubokého učení pro klasifikaci obrázků.
Vylepšení modelu
Pokud s výsledky modelu nejste spokojení, můžete se pokusit zlepšit jeho výkon vyzkoušením některých z následujících přístupů:
- Další data: Čím více příkladů se model učí, tím lépe funguje. Stáhněte si úplnou datovou sadu SDNET2018 a použijte ji k trénmu.
- Rozšíření dat: Běžnou technikou přidání různých možností dat je rozšířit data pořízením obrázku a použitím různých transformací (otočení, překlopení, posun, oříznutí). Tím přidáte pestřejší příklady, ze které se model může učit.
- Trénujte delší dobu: Čím déle trénujete, tím více bude model vyladěný. Zvýšení počtu epoch může zlepšit výkon modelu.
- Experimentujte s hyper-parametry: Kromě parametrů použitých v tomto kurzu je možné další parametry ladit, aby se potenciálně zlepšil výkon. Změna rychlosti učení, která určuje velikost aktualizací provedených v modelu po každé epochě, může zvýšit výkon.
- Použijte jinou architekturu modelu: V závislosti na tom, jak vaše data vypadají, se model, který dokáže nejlépe naučit jeho funkce, se může lišit. Pokud nejste spokojení s výkonem modelu, zkuste změnit architekturu.
Další kroky
V tomto kurzu jste se dozvěděli, jak vytvořit vlastní model hlubokého učení pomocí transferového učení, předem natrénovaného modelu Klasifikace obrázků TensorFlow a rozhraní API pro klasifikaci ML.NET klasifikace obrázků za účelem klasifikace obrázků betonových povrchů jako prasklé nebo nezalomené.
Další informace najdete v dalším kurzu.