Quickstart: Een objectdetectieproject maken met de Custom Vision-clientbibliotheek

Ga aan de slag met de Custom Vision-clientbibliotheek voor .NET. Volg deze stappen om het pakket te installeren en de voorbeeldcode uit te proberen voor het bouwen van een objectdetectiemodel. U maakt een project, voegt tags toe, traint het project op voorbeeldafbeeldingen en gebruikt de voorspellingseindpunt-URL van het project om het programmatisch te testen. Gebruik dit voorbeeld als sjabloon voor het bouwen van uw eigen app voor afbeeldingsherkenning.

Opmerking

Als u een objectdetectiemodel wilt bouwen en trainen zonder code te schrijven, raadpleegt u in plaats daarvan de richtlijnen op basis van de browser .

Referentiedocumentatie | Bibliotheekbroncode (training)(voorspelling) | Pakket (NuGet) (training)(voorspelling)Voorbeelden

Voorwaarden

Omgevingsvariabelen maken

In dit voorbeeld schrijft u uw inloggegevens naar omgevingsvariabelen op de lokale computer die de toepassing uitvoert.

Ga naar de Azure-portal. Als de Custom Vision-resources die u hebt gemaakt in de sectie Vereisten zijn geïmplementeerd, selecteert u de knop Ga naar resource onder Volgende stappen. U vindt uw sleutels en eindpunten op de pagina's Sleutels en eindpunten van de resources onder Resourcebeheer. U moet de sleutels voor uw trainingsresource en voorspellingsresource ophalen, samen met de API-eindpunten.

U vindt de id van de voorspellingsresource op het tabblad Properties in de Azure-portal, vermeld als Resource-id.

Tip

U gebruikt https://www.customvision.ai ook om deze waarden op te halen. Nadat u zich hebt aangemeld, selecteert u het pictogram Instellingen rechtsboven. Op de pagina's Instellingen kunt u alle sleutels, resource-id's en eindpunten weergeven.

Als u de omgevingsvariabelen wilt instellen, opent u een consolevenster en volgt u de instructies voor uw besturingssysteem en ontwikkelomgeving.

  • Als u de VISION_TRAINING KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-training-key> een van de sleutels voor uw trainingsresource.
  • Stel de VISION_TRAINING_ENDPOINT omgevingsvariabele in door <your-training-endpoint> te vervangen door het eindpunt voor uw trainingsresource.
  • Als u de VISION_PREDICTION_KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-prediction-key> een van de sleutels voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_ENDPOINT omgevingsvariabele wilt instellen, vervangt u het <your-prediction-endpoint> eindpunt voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_RESOURCE_ID omgevingsvariabele wilt instellen, vervangt u deze door <your-resource-id> de resource-id voor uw voorspellingsresource.

Belangrijk

We raden Microsoft Entra ID-authenticatie aan met beheerde identiteiten voor Azure-resources om te voorkomen dat referenties worden opgeslagen bij uw toepassingen die in de cloud draaien.

Gebruik API-sleutels met voorzichtigheid. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar. Als u API-sleutels gebruikt, slaat u deze veilig op in Azure Key Vault, draait u de sleutels regelmatig en beperkt u de toegang tot Azure Key Vault met behulp van op rollen gebaseerd toegangsbeheer en netwerktoegangsbeperkingen. Zie API-sleutels met Azure Key Vault voor meer informatie over het veilig gebruiken van API-sleutels in uw apps.

Zie Authenticate requests to Azure AI-services voor meer informatie over beveiliging van AI-services.

setx VISION_TRAINING_KEY <your-training-key>
setx VISION_TRAINING_ENDPOINT <your-training-endpoint>
setx VISION_PREDICTION_KEY <your-prediction-key>
setx VISION_PREDICTION_ENDPOINT <your-prediction-endpoint>
setx VISION_PREDICTION_RESOURCE_ID <your-resource-id>

Nadat u de omgevingsvariabelen hebt toegevoegd, moet u mogelijk alle actieve programma's die de omgevingsvariabelen lezen opnieuw opstarten, inclusief het consolevenster.

Instellen

Een nieuwe C#-toepassing maken

Maak met Visual Studio een nieuwe .NET Core-toepassing.

De clientbibliotheek installeren

Nadat u een nieuw project hebt gemaakt, installeert u de clientbibliotheek door met de rechtermuisknop op de projectoplossing te klikken in de Solution Explorer en Beheer nuGet-pakketten te selecteren. Selecteer in het pakketbeheer dat wordt geopend BrowseInclude prerelease en zoek naar Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training en Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Selecteer de nieuwste versie en installeer vervolgens.

Tip

Wilt u het hele quickstart-codebestand tegelijk weergeven? U vindt deze op GitHub, die de codevoorbeelden in deze quickstart bevat.

Open in de projectmap het bestand program.cs en voeg de volgende using instructies toe:

using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction;
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training;
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;

Maak in de hoofdmethode van de toepassing variabelen waarmee de sleutels en het eindpunt van uw resource worden opgehaald uit omgevingsvariabelen. U declareert ook enkele basisobjecten die later moeten worden gebruikt.

    string trainingEndpoint = Environment.GetEnvironmentVariable("VISION_TRAINING_ENDPOINT");

    string trainingKey = Environment.GetEnvironmentVariable("VISION_TRAINING_KEY");
    string predictionEndpoint = Environment.GetEnvironmentVariable("VISION_PREDICTION_ENDPOINT");
    string predictionKey = Environment.GetEnvironmentVariable("VISION_PREDICTION_KEY");

    private static Iteration iteration;
    private static string publishedModelName = "CustomODModel";

Voeg in de main-methode van de toepassing aanroepen toe voor de methoden die in deze quickstart worden gebruikt. U gaat deze later implementeren.

CustomVisionTrainingClient trainingApi = AuthenticateTraining(trainingEndpoint, trainingKey);
CustomVisionPredictionClient predictionApi = AuthenticatePrediction(predictionEndpoint, predictionKey);

Project project = CreateProject(trainingApi);
AddTags(trainingApi, project);
UploadImages(trainingApi, project);
TrainProject(trainingApi, project);
PublishIteration(trainingApi, project);
TestIteration(predictionApi, project);

De client verifiëren

Initialiseer in een nieuwe methode trainings- en voorspellingsclients met behulp van uw eindpunt en sleutels.

private CustomVisionTrainingClient AuthenticateTraining(string endpoint, string trainingKey, string predictionKey)
{
    // Create the Api, passing in the training key
    CustomVisionTrainingClient trainingApi = new CustomVisionTrainingClient(new Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.ApiKeyServiceClientCredentials(trainingKey))
    {
        Endpoint = endpoint
    };
    return trainingApi;
}
private CustomVisionPredictionClient AuthenticatePrediction(string endpoint, string predictionKey)
{
    // Create a prediction endpoint, passing in the obtained prediction key
    CustomVisionPredictionClient predictionApi = new CustomVisionPredictionClient(new Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction.ApiKeyServiceClientCredentials(predictionKey))
    {
        Endpoint = endpoint
    };
    return predictionApi;
}

Een nieuw Custom Vision-project maken

Met deze volgende methode maakt u een objectdetectieproject. Het gemaakte project wordt weergegeven op de Custom Vision-website. Zie de methode CreateProject om andere opties op te geven wanneer u uw project maakt (uitgelegd in de handleiding een detectorwebportal bouwen).

private Project CreateProject(CustomVisionTrainingClient trainingApi)
{
    // Find the object detection domain
    var domains = trainingApi.GetDomains();
    var objDetectionDomain = domains.FirstOrDefault(d => d.Type == "ObjectDetection");

    // Create a new project
    Console.WriteLine("Creating new project:");
    project = trainingApi.CreateProject("My New Project", null, objDetectionDomain.Id);

    return project;
}

Tags toevoegen aan het project

Met deze methode worden de tags gedefinieerd waarop u het model gaat trainen.

private void AddTags(CustomVisionTrainingClient trainingApi, Project project)
{
    // Make two tags in the new project
    var forkTag = trainingApi.CreateTag(project.Id, "fork");
    var scissorsTag = trainingApi.CreateTag(project.Id, "scissors");
}

Afbeeldingen uploaden en taggen

Download eerst de voorbeeldafbeeldingen voor dit project. Sla de inhoud van de map sample Images op uw lokale apparaat op.

Wanneer u afbeeldingen tagt in objectdetectieprojecten, moet u de regio van elk gelabeld object opgeven met behulp van genormaliseerde coördinaten. De volgende code koppelt elk van de voorbeeldafbeeldingen aan de getagde regio.

private void UploadImages(CustomVisionTrainingClient trainingApi, Project project)
{
    Dictionary<string, double[]> fileToRegionMap = new Dictionary<string, double[]>()
    {
        // FileName, Left, Top, Width, Height
        {"scissors_1", new double[] { 0.4007353, 0.194068655, 0.259803921, 0.6617647 } },
        {"scissors_2", new double[] { 0.426470578, 0.185898721, 0.172794119, 0.5539216 } },
        {"scissors_3", new double[] { 0.289215684, 0.259428144, 0.403186262, 0.421568632 } },
        {"scissors_4", new double[] { 0.343137264, 0.105833367, 0.332107842, 0.8055556 } },
        {"scissors_5", new double[] { 0.3125, 0.09766343, 0.435049027, 0.71405226 } },
        {"scissors_6", new double[] { 0.379901975, 0.24308826, 0.32107842, 0.5718954 } },
        {"scissors_7", new double[] { 0.341911763, 0.20714055, 0.3137255, 0.6356209 } },
        {"scissors_8", new double[] { 0.231617644, 0.08459154, 0.504901946, 0.8480392 } },
        {"scissors_9", new double[] { 0.170343131, 0.332957536, 0.767156839, 0.403594762 } },
        {"scissors_10", new double[] { 0.204656869, 0.120539248, 0.5245098, 0.743464053 } },
        {"scissors_11", new double[] { 0.05514706, 0.159754932, 0.799019635, 0.730392158 } },
        {"scissors_12", new double[] { 0.265931368, 0.169558853, 0.5061275, 0.606209159 } },
        {"scissors_13", new double[] { 0.241421565, 0.184264734, 0.448529422, 0.6830065 } },
        {"scissors_14", new double[] { 0.05759804, 0.05027781, 0.75, 0.882352948 } },
        {"scissors_15", new double[] { 0.191176474, 0.169558853, 0.6936275, 0.6748366 } },
        {"scissors_16", new double[] { 0.1004902, 0.279036, 0.6911765, 0.477124184 } },
        {"scissors_17", new double[] { 0.2720588, 0.131977156, 0.4987745, 0.6911765 } },
        {"scissors_18", new double[] { 0.180147052, 0.112369314, 0.6262255, 0.6666667 } },
        {"scissors_19", new double[] { 0.333333343, 0.0274019931, 0.443627447, 0.852941155 } },
        {"scissors_20", new double[] { 0.158088237, 0.04047389, 0.6691176, 0.843137264 } },
        {"fork_1", new double[] { 0.145833328, 0.3509314, 0.5894608, 0.238562092 } },
        {"fork_2", new double[] { 0.294117659, 0.216944471, 0.534313738, 0.5980392 } },
        {"fork_3", new double[] { 0.09191177, 0.0682516545, 0.757352948, 0.6143791 } },
        {"fork_4", new double[] { 0.254901975, 0.185898721, 0.5232843, 0.594771266 } },
        {"fork_5", new double[] { 0.2365196, 0.128709182, 0.5845588, 0.71405226 } },
        {"fork_6", new double[] { 0.115196079, 0.133611143, 0.676470637, 0.6993464 } },
        {"fork_7", new double[] { 0.164215669, 0.31008172, 0.767156839, 0.410130739 } },
        {"fork_8", new double[] { 0.118872553, 0.318251669, 0.817401946, 0.225490168 } },
        {"fork_9", new double[] { 0.18259804, 0.2136765, 0.6335784, 0.643790841 } },
        {"fork_10", new double[] { 0.05269608, 0.282303959, 0.8088235, 0.452614367 } },
        {"fork_11", new double[] { 0.05759804, 0.0894935, 0.9007353, 0.3251634 } },
        {"fork_12", new double[] { 0.3345588, 0.07315363, 0.375, 0.9150327 } },
        {"fork_13", new double[] { 0.269607842, 0.194068655, 0.4093137, 0.6732026 } },
        {"fork_14", new double[] { 0.143382356, 0.218578458, 0.7977941, 0.295751631 } },
        {"fork_15", new double[] { 0.19240196, 0.0633497, 0.5710784, 0.8398692 } },
        {"fork_16", new double[] { 0.140931368, 0.480016381, 0.6838235, 0.240196079 } },
        {"fork_17", new double[] { 0.305147052, 0.2512582, 0.4791667, 0.5408496 } },
        {"fork_18", new double[] { 0.234068632, 0.445702642, 0.6127451, 0.344771236 } },
        {"fork_19", new double[] { 0.219362751, 0.141781077, 0.5919118, 0.6683006 } },
        {"fork_20", new double[] { 0.180147052, 0.239820287, 0.6887255, 0.235294119 } }
    };

Opmerking

Als u voor uw eigen projecten geen hulpprogramma voor klikken en slepen hebt om de coördinaten van regio's te markeren, kunt u de webgebruikersinterface op de Custom Vision-website gebruiken. In dit voorbeeld zijn de coördinaten al opgegeven.

Vervolgens wordt deze kaart met koppelingen gebruikt om elke voorbeeldafbeelding te uploaden met de bijbehorende regiocoördinaten. U kunt maximaal 64 afbeeldingen uploaden in één batch. Mogelijk moet u de imagePath waarde wijzigen zodat deze verwijst naar de juiste maplocaties.

    // Add all images for fork
    var imagePath = Path.Combine("Images", "fork");
    var imageFileEntries = new List<ImageFileCreateEntry>();
    foreach (var fileName in Directory.EnumerateFiles(imagePath))
    {
        var region = fileToRegionMap[Path.GetFileNameWithoutExtension(fileName)];
        imageFileEntries.Add(new ImageFileCreateEntry(fileName, File.ReadAllBytes(fileName), null, new List<Region>(new Region[] { new Region(forkTag.Id, region[0], region[1], region[2], region[3]) })));
    }
    trainingApi.CreateImagesFromFiles(project.Id, new ImageFileCreateBatch(imageFileEntries));

    // Add all images for scissors
    imagePath = Path.Combine("Images", "scissors");
    imageFileEntries = new List<ImageFileCreateEntry>();
    foreach (var fileName in Directory.EnumerateFiles(imagePath))
    {
        var region = fileToRegionMap[Path.GetFileNameWithoutExtension(fileName)];
        imageFileEntries.Add(new ImageFileCreateEntry(fileName, File.ReadAllBytes(fileName), null, new List<Region>(new Region[] { new Region(scissorsTag.Id, region[0], region[1], region[2], region[3]) })));
    }
    trainingApi.CreateImagesFromFiles(project.Id, new ImageFileCreateBatch(imageFileEntries));
}

Op dit moment hebt u alle voorbeeldafbeeldingen geüpload en elke afbeelding (vork of schaar) getagd met een bijbehorende pixelrechthoek.

Het project trainen

Met deze methode maakt u de eerste trainingsiteratie in het project. Er wordt een query uitgevoerd op de service totdat de training is voltooid.

private void TrainProject(CustomVisionTrainingClient trainingApi, Project project)
{

    // Now there are images with tags start training the project
    Console.WriteLine("\tTraining");
    iteration = trainingApi.TrainProject(project.Id);

    // The returned iteration will be in progress, and can be queried periodically to see when it has completed
    while (iteration.Status == "Training")
    {
        Thread.Sleep(1000);

        // Re-query the iteration to get its updated status
        iteration = trainingApi.GetIteration(project.Id, iteration.Id);
    }
}

Tip

Trainen met geselecteerde tags

U kunt eventueel alleen trainen op een subset van uw toegepaste tags. U kunt dit doen als u nog niet genoeg van bepaalde tags hebt toegepast, maar u wel genoeg van anderen hebt. Gebruik in de aanroep TrainProject de parameter trainingParameters . Maak een TrainingParameters en stel de eigenschap SelectedTags in op een lijst met id's van de tags die u wilt gebruiken. Het model traint om alleen de tags in die lijst te herkennen.

De huidige iteratie publiceren

Met deze methode wordt de huidige iteratie van het model beschikbaar voor het uitvoeren van query's. U kunt de modelnaam gebruiken als verwijzing om voorspellingsaanvragen te verzenden. U moet uw eigen waarde invoeren voor predictionResourceId. U vindt de voorspellingsresource-id op het tabblad Properties van de resource in de Azure-portal, vermeld als Resource-id.

private void PublishIteration(CustomVisionTrainingClient trainingApi, Project project)
{

    // The iteration is now trained. Publish it to the prediction end point.
    var predictionResourceId = Environment.GetEnvironmentVariable("VISION_PREDICTION_RESOURCE_ID");
    trainingApi.PublishIteration(project.Id, iteration.Id, publishedModelName, predictionResourceId);
    Console.WriteLine("Done!\n");
}

Het voorspellingseindpunt testen

Met deze methode wordt de testafbeelding geladen, wordt het modeleindpunt opgevraagd en worden voorspellingsgegevens naar de console uitgevoerd.

private void TestIteration(CustomVisionPredictionClient predictionApi, Project project)
{

    // Make a prediction against the new project
    Console.WriteLine("Making a prediction:");
    var imageFile = Path.Combine("Images", "test", "test_image.jpg");
    using (var stream = File.OpenRead(imageFile))
    {
        var result = predictionApi.DetectImage(project.Id, publishedModelName, stream);

        // Loop over each prediction and write out the results
        foreach (var c in result.Predictions)
        {
            Console.WriteLine($"\t{c.TagName}: {c.Probability:P1} [ {c.BoundingBox.Left}, {c.BoundingBox.Top}, {c.BoundingBox.Width}, {c.BoundingBox.Height} ]");
        }
    }
    Console.ReadKey();
}

De toepassing uitvoeren

Voer de toepassing uit door boven aan het IDE-venster op de knop Foutopsporing te klikken.

Terwijl de toepassing wordt uitgevoerd, moet er een consolevenster worden geopend en de volgende uitvoer worden geschreven:

Creating new project:
        Training
Done!

Making a prediction:
        fork: 98.2% [ 0.111609578, 0.184719115, 0.6607002, 0.6637112 ]
        scissors: 1.2% [ 0.112389535, 0.119195729, 0.658031344, 0.7023591 ]

Vervolgens kunt u controleren of de testafbeelding (gevonden in Afbeeldingen/Test/) op de juiste wijze is gelabeld en of de detectieregio juist is. Op dit moment kunt u op elke willekeurige toets drukken om de toepassing af te sluiten.

Resources opschonen

Als u uw eigen objectdetectieproject wilt implementeren (of in plaats daarvan een afbeeldingsclassificatieproject wilt proberen), kunt u het detectieproject voor fork/schaar uit dit voorbeeld verwijderen. Met een gratis abonnement kunt u twee Custom Vision-projecten uitvoeren.

Ga op de website Custom Vision naar Projects en selecteer de prullenbak onder Mijn nieuwe Project.

Schermopname van een paneel met het label Mijn nieuwe Project met een prullenbakpictogram.

Volgende stappen

Nu hebt u elke stap van het objectdetectieproces in code uitgevoerd. In dit voorbeeld wordt één trainingsiteratie uitgevoerd, maar vaak moet u uw model meerdere keren trainen en testen om het nauwkeuriger te maken. De volgende handleiding gaat over afbeeldingsclassificatie, maar de principes zijn vergelijkbaar met objectdetectie.

Deze handleiding bevat instructies en voorbeeldcode om u te helpen aan de slag te gaan met de Custom Vision-clientbibliotheek voor Go om een objectdetectiemodel te bouwen. U maakt een project, voegt tags toe, traint het project en gebruikt de voorspellingseindpunt-URL van het project om het programmatisch te testen. Gebruik dit voorbeeld als sjabloon voor het bouwen van uw eigen app voor afbeeldingsherkenning.

Opmerking

Als u een objectdetectiemodel wilt bouwen en trainen zonder code te schrijven, raadpleegt u in plaats daarvan de richtlijnen op basis van de browser .

Referentiedocumentatie (training)(voorspelling)

Voorwaarden

Omgevingsvariabelen maken

In dit voorbeeld schrijft u uw inloggegevens naar omgevingsvariabelen op de lokale computer die de toepassing uitvoert.

Ga naar de Azure-portal. Als de Custom Vision-resources die u hebt gemaakt in de sectie Vereisten zijn geïmplementeerd, selecteert u de knop Ga naar resource onder Volgende stappen. U vindt uw sleutels en eindpunten op de pagina's Sleutels en eindpunten van de resources onder Resourcebeheer. U moet de sleutels voor uw trainingsresource en voorspellingsresource ophalen, samen met de API-eindpunten.

U vindt de id van de voorspellingsresource op het tabblad Properties in de Azure-portal, vermeld als Resource-id.

Tip

U gebruikt https://www.customvision.ai ook om deze waarden op te halen. Nadat u zich hebt aangemeld, selecteert u het pictogram Instellingen rechtsboven. Op de pagina's Instellingen kunt u alle sleutels, resource-id's en eindpunten weergeven.

Als u de omgevingsvariabelen wilt instellen, opent u een consolevenster en volgt u de instructies voor uw besturingssysteem en ontwikkelomgeving.

  • Als u de VISION_TRAINING KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-training-key> een van de sleutels voor uw trainingsresource.
  • Stel de VISION_TRAINING_ENDPOINT omgevingsvariabele in door <your-training-endpoint> te vervangen door het eindpunt voor uw trainingsresource.
  • Als u de VISION_PREDICTION_KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-prediction-key> een van de sleutels voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_ENDPOINT omgevingsvariabele wilt instellen, vervangt u het <your-prediction-endpoint> eindpunt voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_RESOURCE_ID omgevingsvariabele wilt instellen, vervangt u deze door <your-resource-id> de resource-id voor uw voorspellingsresource.

Belangrijk

We raden Microsoft Entra ID-authenticatie aan met beheerde identiteiten voor Azure-resources om te voorkomen dat referenties worden opgeslagen bij uw toepassingen die in de cloud draaien.

Gebruik API-sleutels met voorzichtigheid. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar. Als u API-sleutels gebruikt, slaat u deze veilig op in Azure Key Vault, draait u de sleutels regelmatig en beperkt u de toegang tot Azure Key Vault met behulp van op rollen gebaseerd toegangsbeheer en netwerktoegangsbeperkingen. Zie API-sleutels met Azure Key Vault voor meer informatie over het veilig gebruiken van API-sleutels in uw apps.

Zie Authenticate requests to Azure AI-services voor meer informatie over beveiliging van AI-services.

setx VISION_TRAINING_KEY <your-training-key>
setx VISION_TRAINING_ENDPOINT <your-training-endpoint>
setx VISION_PREDICTION_KEY <your-prediction-key>
setx VISION_PREDICTION_ENDPOINT <your-prediction-endpoint>
setx VISION_PREDICTION_RESOURCE_ID <your-resource-id>

Nadat u de omgevingsvariabelen hebt toegevoegd, moet u mogelijk alle actieve programma's die de omgevingsvariabelen lezen opnieuw opstarten, inclusief het consolevenster.

Instellen

De Custom Vision-clientbibliotheek installeren

Als u een app voor afbeeldingsanalyse wilt schrijven met Custom Vision voor Go, hebt u de Clientbibliotheek van de Custom Vision-service nodig. Voer de volgende opdracht uit in PowerShell:

go get -u github.com/Azure/azure-sdk-for-go/...

Als u gebruik maakt van dep binnen uw opslagplaats, voer dan het volgende uit:

dep ensure -add github.com/Azure/azure-sdk-for-go

De voorbeeldafbeeldingen ophalen

In dit voorbeeld worden de afbeeldingen van de Foundry Tools Python SDK Samples repository op GitHub gebruikt. Kloon of download deze opslagplaats naar uw ontwikkelomgeving. Onthoud de maplocatie voor een latere stap.

Het Custom Vision-project maken

Maak een nieuw bestand met de naam sample.go in de projectmap van uw voorkeur en open het in de code-editor van uw voorkeur.

Voeg de volgende code toe aan uw script om een nieuw Custom Vision-serviceproject te maken.

Zie de methode CreateProject om andere opties op te geven wanneer u uw project maakt (uitgelegd in de handleiding een detectorwebportal bouwen).

import(
    "context"
    "bytes"
    "fmt"
    "io/ioutil"
    "path"
    "log"
    "time"
    "github.com/Azure/azure-sdk-for-go/services/cognitiveservices/v3.0/customvision/training"
    "github.com/Azure/azure-sdk-for-go/services/cognitiveservices/v3.0/customvision/prediction"
)

// retrieve environment variables:
var (
    training_key string = os.Getenv("VISION_TRAINING_KEY")
    prediction_key string = os.Getenv("VISION_PREDICTION_KEY")
    prediction_resource_id = os.Getenv("VISION_PREDICTION_RESOURCE_ID")
    endpoint string = os.Getenv("VISION_ENDPOINT")
   
    project_name string = "Go Sample OD Project"
    iteration_publish_name = "detectModel"
    sampleDataDirectory = "<path to sample images>"
)

func main() {
    fmt.Println("Creating project...")

    ctx = context.Background()

    trainer := training.New(training_key, endpoint)

    var objectDetectDomain training.Domain
    domains, _ := trainer.GetDomains(ctx)

    for _, domain := range *domains.Value {
        fmt.Println(domain, domain.Type)
        if domain.Type == "ObjectDetection" && *domain.Name == "General" {
            objectDetectDomain = domain
            break
        }
    }
    fmt.Println("Creating project...")
    project, _ := trainer.CreateProject(ctx, project_name, "", objectDetectDomain.ID, "")

Tags maken in het project

Als u classificatietags wilt maken voor uw project, voegt u de volgende code toe aan het einde van sample.go:

# Make two tags in the new project
forkTag, _ := trainer.CreateTag(ctx, *project.ID, "fork", "A fork", string(training.Regular))
scissorsTag, _ := trainer.CreateTag(ctx, *project.ID, "scissors", "Pair of scissors", string(training.Regular))

Afbeeldingen uploaden en taggen

Wanneer u afbeeldingen tagt in objectdetectieprojecten, moet u de regio van elk gelabeld object opgeven met behulp van genormaliseerde coördinaten.

Opmerking

Als u geen hulpprogramma voor klikken en slepen hebt om de coördinaten van regio's te markeren, kunt u de webgebruikersinterface op Customvision.ai gebruiken. In dit voorbeeld zijn de coördinaten al opgegeven.

Als u de afbeeldingen, tags en regio's aan het project wilt toevoegen, voegt u de volgende code in na het maken van de tag. In deze zelfstudie zijn de regio's inline vastgelegd. De regio's geven het begrenzingsvak op in genormaliseerde coördinaten en de coördinaten worden weergegeven in de volgorde: links, boven, breedte, hoogte.

forkImageRegions := map[string][4]float64{
    "fork_1.jpg": [4]float64{ 0.145833328, 0.3509314, 0.5894608, 0.238562092 },
    "fork_2.jpg": [4]float64{ 0.294117659, 0.216944471, 0.534313738, 0.5980392 },
    "fork_3.jpg": [4]float64{ 0.09191177, 0.0682516545, 0.757352948, 0.6143791 },
    "fork_4.jpg": [4]float64{ 0.254901975, 0.185898721, 0.5232843, 0.594771266 },
    "fork_5.jpg": [4]float64{ 0.2365196, 0.128709182, 0.5845588, 0.71405226 },
    "fork_6.jpg": [4]float64{ 0.115196079, 0.133611143, 0.676470637, 0.6993464 },
    "fork_7.jpg": [4]float64{ 0.164215669, 0.31008172, 0.767156839, 0.410130739 },
    "fork_8.jpg": [4]float64{ 0.118872553, 0.318251669, 0.817401946, 0.225490168 },
    "fork_9.jpg": [4]float64{ 0.18259804, 0.2136765, 0.6335784, 0.643790841 },
    "fork_10.jpg": [4]float64{ 0.05269608, 0.282303959, 0.8088235, 0.452614367 },
    "fork_11.jpg": [4]float64{ 0.05759804, 0.0894935, 0.9007353, 0.3251634 },
    "fork_12.jpg": [4]float64{ 0.3345588, 0.07315363, 0.375, 0.9150327 },
    "fork_13.jpg": [4]float64{ 0.269607842, 0.194068655, 0.4093137, 0.6732026 },
    "fork_14.jpg": [4]float64{ 0.143382356, 0.218578458, 0.7977941, 0.295751631 },
    "fork_15.jpg": [4]float64{ 0.19240196, 0.0633497, 0.5710784, 0.8398692 },
    "fork_16.jpg": [4]float64{ 0.140931368, 0.480016381, 0.6838235, 0.240196079 },
    "fork_17.jpg": [4]float64{ 0.305147052, 0.2512582, 0.4791667, 0.5408496 },
    "fork_18.jpg": [4]float64{ 0.234068632, 0.445702642, 0.6127451, 0.344771236 },
    "fork_19.jpg": [4]float64{ 0.219362751, 0.141781077, 0.5919118, 0.6683006 },
    "fork_20.jpg": [4]float64{ 0.180147052, 0.239820287, 0.6887255, 0.235294119 },
}

scissorsImageRegions := map[string][4]float64{
    "scissors_1.jpg": [4]float64{ 0.4007353, 0.194068655, 0.259803921, 0.6617647 },
    "scissors_2.jpg": [4]float64{ 0.426470578, 0.185898721, 0.172794119, 0.5539216 },
    "scissors_3.jpg": [4]float64{ 0.289215684, 0.259428144, 0.403186262, 0.421568632 },
    "scissors_4.jpg": [4]float64{ 0.343137264, 0.105833367, 0.332107842, 0.8055556 },
    "scissors_5.jpg": [4]float64{ 0.3125, 0.09766343, 0.435049027, 0.71405226 },
    "scissors_6.jpg": [4]float64{ 0.379901975, 0.24308826, 0.32107842, 0.5718954 },
    "scissors_7.jpg": [4]float64{ 0.341911763, 0.20714055, 0.3137255, 0.6356209 },
    "scissors_8.jpg": [4]float64{ 0.231617644, 0.08459154, 0.504901946, 0.8480392 },
    "scissors_9.jpg": [4]float64{ 0.170343131, 0.332957536, 0.767156839, 0.403594762 },
    "scissors_10.jpg": [4]float64{ 0.204656869, 0.120539248, 0.5245098, 0.743464053 },
    "scissors_11.jpg": [4]float64{ 0.05514706, 0.159754932, 0.799019635, 0.730392158 },
    "scissors_12.jpg": [4]float64{ 0.265931368, 0.169558853, 0.5061275, 0.606209159 },
    "scissors_13.jpg": [4]float64{ 0.241421565, 0.184264734, 0.448529422, 0.6830065 },
    "scissors_14.jpg": [4]float64{ 0.05759804, 0.05027781, 0.75, 0.882352948 },
    "scissors_15.jpg": [4]float64{ 0.191176474, 0.169558853, 0.6936275, 0.6748366 },
    "scissors_16.jpg": [4]float64{ 0.1004902, 0.279036, 0.6911765, 0.477124184 },
    "scissors_17.jpg": [4]float64{ 0.2720588, 0.131977156, 0.4987745, 0.6911765 },
    "scissors_18.jpg": [4]float64{ 0.180147052, 0.112369314, 0.6262255, 0.6666667 },
    "scissors_19.jpg": [4]float64{ 0.333333343, 0.0274019931, 0.443627447, 0.852941155 },
    "scissors_20.jpg": [4]float64{ 0.158088237, 0.04047389, 0.6691176, 0.843137264 },
}

Gebruik vervolgens deze kaart met koppelingen om elke voorbeeldafbeelding te uploaden met de bijbehorende regiocoördinaten (u kunt maximaal 64 afbeeldingen in één batch uploaden). Voeg de volgende code toe.

Opmerking

U moet het pad naar de afbeeldingen wijzigen op basis van waar u het project Foundry Tools Go SDK Samples eerder hebt gedownload.

// Go through the data table above and create the images
fmt.Println("Adding images...")
var fork_images []training.ImageFileCreateEntry
for file, region := range forkImageRegions {
    imageFile, _ := ioutil.ReadFile(path.Join(sampleDataDirectory, "fork", file))

    regiontest := forkImageRegions[file]
    imageRegion := training.Region{
        TagID:  forkTag.ID,
        Left:   &regiontest[0],
        Top:    &regiontest[1],
        Width:  &regiontest[2],
        Height: &regiontest[3],
    }
    var fileName string = file

    fork_images = append(fork_images, training.ImageFileCreateEntry{
        Name:     &fileName,
        Contents: &imageFile,
        Regions:  &[]training.Region{imageRegion}
    })
}
    
fork_batch, _ := trainer.CreateImagesFromFiles(ctx, *project.ID, training.ImageFileCreateBatch{ 
    Images: &fork_images,
})

if (!*fork_batch.IsBatchSuccessful) {
    fmt.Println("Batch upload failed.")
}

var scissor_images []training.ImageFileCreateEntry
for file, region := range scissorsImageRegions {
    imageFile, _ := ioutil.ReadFile(path.Join(sampleDataDirectory, "scissors", file))

    imageRegion := training.Region { 
        TagID:scissorsTag.ID,
        Left:&region[0],
        Top:&region[1],
        Width:&region[2],
        Height:&region[3],
    }

    scissor_images = append(scissor_images, training.ImageFileCreateEntry {
        Name: &file,
        Contents: &imageFile,
        Regions: &[]training.Region{ imageRegion },
    })
}
    
scissor_batch, _ := trainer.CreateImagesFromFiles(ctx, *project.ID, training.ImageFileCreateBatch{ 
    Images: &scissor_images,
})
    
if (!*scissor_batch.IsBatchSuccessful) {
    fmt.Println("Batch upload failed.")
}     

Het project trainen en publiceren

Met deze code maakt u de eerste iteratie van het voorspellingsmodel en publiceert u die iteratie vervolgens naar het voorspellingseindpunt. De naam die aan de gepubliceerde iteratie wordt gegeven, kan worden gebruikt om voorspellingsaanvragen te verzenden. Een iteratie is pas beschikbaar in het voorspellingseindpunt nadat het is gepubliceerd.

iteration, _ := trainer.TrainProject(ctx, *project.ID)
fmt.Println("Training status:", *iteration.Status)
for {
    if *iteration.Status != "Training" {
        break
    }
    time.Sleep(5 * time.Second)
    iteration, _ = trainer.GetIteration(ctx, *project.ID, *iteration.ID)
    fmt.Println("Training status:", *iteration.Status)
}

trainer.PublishIteration(ctx, *project.ID, *iteration.ID, iteration_publish_name, prediction_resource_id))

Het voorspellingseindpunt gebruiken

Als u een afbeelding naar het voorspellingseindpunt wilt verzenden en de voorspelling wilt ophalen, voegt u de volgende code toe aan het einde van het bestand:

    fmt.Println("Predicting...")
    predictor := prediction.New(prediction_key, endpoint)

    testImageData, _ := ioutil.ReadFile(path.Join(sampleDataDirectory, "Test", "test_od_image.jpg"))
    results, _ := predictor.DetectImage(ctx, *project.ID, iteration_publish_name, ioutil.NopCloser(bytes.NewReader(testImageData)), "")

    for _, prediction := range *results.Predictions    {
        boundingBox := *prediction.BoundingBox

        fmt.Printf("\t%s: %.2f%% (%.2f, %.2f, %.2f, %.2f)", 
            *prediction.TagName,
            *prediction.Probability * 100,
            *boundingBox.Left,
            *boundingBox.Top,
            *boundingBox.Width,
            *boundingBox.Height)
        fmt.Println("")
    }
}

De toepassing uitvoeren

Voer sample.go uit.

go run sample.go

De uitvoer van de toepassing moet worden weergegeven in de console. Vervolgens kunt u controleren of de testafbeelding (gevonden in samples/vision/images/Test) op de juiste wijze is gelabeld en of de detectieregio juist is.

Resources opschonen

Als u uw eigen objectdetectieproject wilt implementeren (of in plaats daarvan een afbeeldingsclassificatieproject wilt proberen), kunt u het detectieproject voor fork/schaar uit dit voorbeeld verwijderen. Met een gratis abonnement kunt u twee Custom Vision-projecten uitvoeren.

Ga op de website Custom Vision naar Projects en selecteer de prullenbak onder Mijn nieuwe Project.

Schermopname van een paneel met het label Mijn nieuwe Project met een prullenbakpictogram.

Volgende stappen

Nu hebt u elke stap van het objectdetectieproces in code uitgevoerd. In dit voorbeeld wordt één trainingsiteratie uitgevoerd, maar vaak moet u uw model meerdere keren trainen en testen om het nauwkeuriger te maken. De volgende handleiding gaat over afbeeldingsclassificatie, maar de principes zijn vergelijkbaar met objectdetectie.

Ga aan de slag met de Custom Vision-clientbibliotheek voor Java om een objectdetectiemodel te bouwen. Volg deze stappen om het pakket te installeren en de voorbeeldcode voor basistaken uit te proberen. Gebruik dit voorbeeld als sjabloon voor het bouwen van uw eigen app voor afbeeldingsherkenning.

Opmerking

Als u een objectdetectiemodel wilt bouwen en trainen zonder code te schrijven, raadpleegt u in plaats daarvan de richtlijnen op basis van de browser .

documentatie Referentiedocumentatie | Broncode van bibliotheek (training)(voorspelling)| Artefact (Maven) (training)(voorspelling) | Voorbeelden

Voorwaarden

Omgevingsvariabelen maken

In dit voorbeeld schrijft u uw inloggegevens naar omgevingsvariabelen op de lokale computer die de toepassing uitvoert.

Ga naar de Azure-portal. Als de Custom Vision-resources die u hebt gemaakt in de sectie Vereisten zijn geïmplementeerd, selecteert u de knop Ga naar resource onder Volgende stappen. U vindt uw sleutels en eindpunten op de pagina's Sleutels en eindpunten van de resources onder Resourcebeheer. U moet de sleutels voor uw trainingsresource en voorspellingsresource ophalen, samen met de API-eindpunten.

U vindt de id van de voorspellingsresource op het tabblad Properties in de Azure-portal, vermeld als Resource-id.

Tip

U gebruikt https://www.customvision.ai ook om deze waarden op te halen. Nadat u zich hebt aangemeld, selecteert u het pictogram Instellingen rechtsboven. Op de pagina's Instellingen kunt u alle sleutels, resource-id's en eindpunten weergeven.

Als u de omgevingsvariabelen wilt instellen, opent u een consolevenster en volgt u de instructies voor uw besturingssysteem en ontwikkelomgeving.

  • Als u de VISION_TRAINING KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-training-key> een van de sleutels voor uw trainingsresource.
  • Stel de VISION_TRAINING_ENDPOINT omgevingsvariabele in door <your-training-endpoint> te vervangen door het eindpunt voor uw trainingsresource.
  • Als u de VISION_PREDICTION_KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-prediction-key> een van de sleutels voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_ENDPOINT omgevingsvariabele wilt instellen, vervangt u het <your-prediction-endpoint> eindpunt voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_RESOURCE_ID omgevingsvariabele wilt instellen, vervangt u deze door <your-resource-id> de resource-id voor uw voorspellingsresource.

Belangrijk

We raden Microsoft Entra ID-authenticatie aan met beheerde identiteiten voor Azure-resources om te voorkomen dat referenties worden opgeslagen bij uw toepassingen die in de cloud draaien.

Gebruik API-sleutels met voorzichtigheid. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar. Als u API-sleutels gebruikt, slaat u deze veilig op in Azure Key Vault, draait u de sleutels regelmatig en beperkt u de toegang tot Azure Key Vault met behulp van op rollen gebaseerd toegangsbeheer en netwerktoegangsbeperkingen. Zie API-sleutels met Azure Key Vault voor meer informatie over het veilig gebruiken van API-sleutels in uw apps.

Zie Authenticate requests to Azure AI-services voor meer informatie over beveiliging van AI-services.

setx VISION_TRAINING_KEY <your-training-key>
setx VISION_TRAINING_ENDPOINT <your-training-endpoint>
setx VISION_PREDICTION_KEY <your-prediction-key>
setx VISION_PREDICTION_ENDPOINT <your-prediction-endpoint>
setx VISION_PREDICTION_RESOURCE_ID <your-resource-id>

Nadat u de omgevingsvariabelen hebt toegevoegd, moet u mogelijk alle actieve programma's die de omgevingsvariabelen lezen opnieuw opstarten, inclusief het consolevenster.

Instellen

Een nieuw Gradle-project maken

Maak in een consolevenster (zoals cmd, PowerShell of Bash) een nieuwe map voor uw app en navigeer ernaartoe.

mkdir myapp && cd myapp

Voer de gradle init opdracht uit vanuit uw werkmap. Met deze opdracht maakt u essentiële buildbestanden voor Gradle, waaronder build.gradle.kts, die tijdens runtime wordt gebruikt om uw toepassing te maken en te configureren.

gradle init --type basic

Wanneer u wordt gevraagd om een DSL te kiezen, selecteert u Kotlin.

De clientbibliotheek installeren

Zoek build.gradle.kts en open deze met uw favoriete IDE of teksteditor. Kopieer vervolgens de volgende buildconfiguratie. Deze configuratie definieert het project als een Java-toepassing waarvan het toegangspunt de klasse CustomVisionQuickstart is. De Custom Vision-bibliotheken worden geïmporteerd.

plugins {
    java
    application
}
application { 
    mainClassName = "CustomVisionQuickstart"
}
repositories {
    mavenCentral()
}
dependencies {
    compile(group = "com.azure", name = "azure-cognitiveservices-customvision-training", version = "1.1.0-preview.2")
    compile(group = "com.azure", name = "azure-cognitiveservices-customvision-prediction", version = "1.1.0-preview.2")
}

Een Java-bestand maken

Voer vanuit uw werkmap de volgende opdracht uit om een projectbronmap te maken:

mkdir -p src/main/java

Navigeer naar de nieuwe map en maak een bestand met de naam CustomVisionQuickstart.java. Open deze in uw favoriete editor of IDE en voeg de volgende import instructies toe:

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import com.google.common.io.ByteStreams;

import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Classifier;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Domain;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.DomainType;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.ImageFileCreateBatch;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.ImageFileCreateEntry;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Iteration;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Project;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Region;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.TrainProjectOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.CustomVisionTrainingClient;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.Trainings;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.CustomVisionTrainingManager;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.models.ImagePrediction;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.models.Prediction;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.CustomVisionPredictionClient;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.CustomVisionPredictionManager;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Tag;

Tip

Wilt u het hele quickstart-codebestand tegelijk weergeven? U vindt deze op GitHub, die de codevoorbeelden in deze quickstart bevat.

Maak in de klasse CustomVisionQuickstart van de toepassing variabelen waarmee de sleutels en het eindpunt van uw resource worden opgehaald uit omgevingsvariabelen.

// retrieve environment variables
final static String trainingApiKey = System.getenv("VISION_TRAINING_KEY");
final static String trainingEndpoint = System.getenv("VISION_TRAINING_ENDPOINT");
final static String predictionApiKey = System.getenv("VISION_PREDICTION_KEY");
final static String predictionEndpoint = System.getenv("VISION_PREDICTION_ENDPOINT");
final static String predictionResourceId = System.getenv("VISION_PREDICTION_RESOURCE_ID");

Voeg in de hoofdmethode van de toepassing aanroepen toe voor de methoden die in deze quickstart worden gebruikt. U definieert deze later.

Project projectOD = createProjectOD(trainClient);
addTagsOD(trainClient, projectOD);
uploadImagesOD(trainClient, projectOD);
trainProjectOD(trainClient, projectOD);
publishIterationOD(trainClient, project);
testProjectOD(predictor, projectOD);

Objectmodel

De volgende klassen en interfaces verwerken enkele van de belangrijkste functies van de Custom Vision-Java-clientbibliotheek.

Naam Beschrijving
CustomVisionTrainingClient Deze klasse verwerkt het maken, trainen en publiceren van uw modellen.
CustomVisionPredictionClient Deze klasse verwerkt de query's van uw modellen voor voorspellingen voor objectdetectie.
ImagePrediction Deze klasse definieert een voorspelling van één object op één afbeelding. Het bevat eigenschappen voor de object-id en naam, de locatie van het omsluitende kader van het object en een nauwkeurigheidsscore.

Codevoorbeelden

Deze codefragmenten laten zien hoe u de volgende taken kunt uitvoeren met de Custom Vision-clientbibliotheek voor Java:

De client verifiëren

Initialiseer in je hoofdmethode de trainings- en voorspellingklanten met behulp van je eindpunt en sleutels.

// Authenticate
CustomVisionTrainingClient trainClient = CustomVisionTrainingManager
        .authenticate(trainingEndpoint, trainingApiKey)
        .withEndpoint(trainingEndpoint);
CustomVisionPredictionClient predictor = CustomVisionPredictionManager
        .authenticate(predictionEndpoint, predictionApiKey)
        .withEndpoint(predictionEndpoint);

Een nieuw Custom Vision-project maken

Met deze volgende methode maakt u een objectdetectieproject. Het gemaakte project wordt weergegeven op de Custom Vision-website die u eerder hebt bezocht. Zie de overbelasting van de methode CreateProject om andere opties op te geven wanneer u uw project maakt (uitgelegd in de handleiding een detectorwebportal bouwen).

public static Project createProjectOD(CustomVisionTrainingClient trainClient) {
    Trainings trainer = trainClient.trainings();

    // find the object detection domain to set the project type
    Domain objectDetectionDomain = null;
    List<Domain> domains = trainer.getDomains();
    for (final Domain domain : domains) {
        if (domain.type() == DomainType.OBJECT_DETECTION) {
            objectDetectionDomain = domain;
            break;
        }
    }

    if (objectDetectionDomain == null) {
        System.out.println("Unexpected result; no objects were detected.");
    }

    System.out.println("Creating project...");
    // create an object detection project
    Project project = trainer.createProject().withName("Sample Java OD Project")
            .withDescription("Sample OD Project").withDomainId(objectDetectionDomain.id())
            .withClassificationType(Classifier.MULTILABEL.toString()).execute();

    return project;
}

Tags toevoegen aan uw project

Met deze methode worden de tags gedefinieerd waarop u het model gaat trainen.

public static void addTagsOD(CustomVisionTrainingClient trainClient, Project project) {
    Trainings trainer = trainClient.trainings();
    // create fork tag
    Tag forkTag = trainer.createTag().withProjectId(project.id()).withName("fork").execute();

    // create scissors tag
    Tag scissorsTag = trainer.createTag().withProjectId(project.id()).withName("scissor").execute();
}

Afbeeldingen uploaden en taggen

Download eerst de voorbeeldafbeeldingen voor dit project. Sla de inhoud van de map sample Images op uw lokale apparaat op.

Opmerking

Hebt u een bredere set afbeeldingen nodig om uw training te voltooien? Met Trove, een Microsoft Garage-project, kunt u sets afbeeldingen verzamelen en aanschaffen voor trainingsdoeleinden. Zodra u uw afbeeldingen hebt verzameld, kunt u ze downloaden en vervolgens op de gebruikelijke manier importeren in uw Custom Vision-project. Ga naar de Trove-pagina voor meer informatie.

Wanneer u afbeeldingen tagt in objectdetectieprojecten, moet u de regio van elk gelabeld object opgeven met behulp van genormaliseerde coördinaten. De volgende code koppelt elk van de voorbeeldafbeeldingen aan de getagde regio.

Opmerking

Als u geen hulpprogramma voor klikken en slepen hebt om de coördinaten van regio's te markeren, kunt u de webgebruikersinterface op Customvision.ai gebruiken. In dit voorbeeld zijn de coördinaten al opgegeven.

public static void uploadImagesOD(CustomVisionTrainingClient trainClient, Project project) {
    // Mapping of filenames to their respective regions in the image. The
    // coordinates are specified
    // as left, top, width, height in normalized coordinates. I.e. (left is left in
    // pixels / width in pixels)

    // This is a hardcoded mapping of the files we'll upload along with the bounding
    // box of the object in the
    // image. The boudning box is specified as left, top, width, height in
    // normalized coordinates.
    // Normalized Left = Left / Width (in Pixels)
    // Normalized Top = Top / Height (in Pixels)
    // Normalized Bounding Box Width = (Right - Left) / Width (in Pixels)
    // Normalized Bounding Box Height = (Bottom - Top) / Height (in Pixels)
    HashMap<String, double[]> regionMap = new HashMap<String, double[]>();
    regionMap.put("scissors_1.jpg", new double[] { 0.4007353, 0.194068655, 0.259803921, 0.6617647 });
    regionMap.put("scissors_2.jpg", new double[] { 0.426470578, 0.185898721, 0.172794119, 0.5539216 });
    regionMap.put("scissors_3.jpg", new double[] { 0.289215684, 0.259428144, 0.403186262, 0.421568632 });
    regionMap.put("scissors_4.jpg", new double[] { 0.343137264, 0.105833367, 0.332107842, 0.8055556 });
    regionMap.put("scissors_5.jpg", new double[] { 0.3125, 0.09766343, 0.435049027, 0.71405226 });
    regionMap.put("scissors_6.jpg", new double[] { 0.379901975, 0.24308826, 0.32107842, 0.5718954 });
    regionMap.put("scissors_7.jpg", new double[] { 0.341911763, 0.20714055, 0.3137255, 0.6356209 });
    regionMap.put("scissors_8.jpg", new double[] { 0.231617644, 0.08459154, 0.504901946, 0.8480392 });
    regionMap.put("scissors_9.jpg", new double[] { 0.170343131, 0.332957536, 0.767156839, 0.403594762 });
    regionMap.put("scissors_10.jpg", new double[] { 0.204656869, 0.120539248, 0.5245098, 0.743464053 });
    regionMap.put("scissors_11.jpg", new double[] { 0.05514706, 0.159754932, 0.799019635, 0.730392158 });
    regionMap.put("scissors_12.jpg", new double[] { 0.265931368, 0.169558853, 0.5061275, 0.606209159 });
    regionMap.put("scissors_13.jpg", new double[] { 0.241421565, 0.184264734, 0.448529422, 0.6830065 });
    regionMap.put("scissors_14.jpg", new double[] { 0.05759804, 0.05027781, 0.75, 0.882352948 });
    regionMap.put("scissors_15.jpg", new double[] { 0.191176474, 0.169558853, 0.6936275, 0.6748366 });
    regionMap.put("scissors_16.jpg", new double[] { 0.1004902, 0.279036, 0.6911765, 0.477124184 });
    regionMap.put("scissors_17.jpg", new double[] { 0.2720588, 0.131977156, 0.4987745, 0.6911765 });
    regionMap.put("scissors_18.jpg", new double[] { 0.180147052, 0.112369314, 0.6262255, 0.6666667 });
    regionMap.put("scissors_19.jpg", new double[] { 0.333333343, 0.0274019931, 0.443627447, 0.852941155 });
    regionMap.put("scissors_20.jpg", new double[] { 0.158088237, 0.04047389, 0.6691176, 0.843137264 });
    regionMap.put("fork_1.jpg", new double[] { 0.145833328, 0.3509314, 0.5894608, 0.238562092 });
    regionMap.put("fork_2.jpg", new double[] { 0.294117659, 0.216944471, 0.534313738, 0.5980392 });
    regionMap.put("fork_3.jpg", new double[] { 0.09191177, 0.0682516545, 0.757352948, 0.6143791 });
    regionMap.put("fork_4.jpg", new double[] { 0.254901975, 0.185898721, 0.5232843, 0.594771266 });
    regionMap.put("fork_5.jpg", new double[] { 0.2365196, 0.128709182, 0.5845588, 0.71405226 });
    regionMap.put("fork_6.jpg", new double[] { 0.115196079, 0.133611143, 0.676470637, 0.6993464 });
    regionMap.put("fork_7.jpg", new double[] { 0.164215669, 0.31008172, 0.767156839, 0.410130739 });
    regionMap.put("fork_8.jpg", new double[] { 0.118872553, 0.318251669, 0.817401946, 0.225490168 });
    regionMap.put("fork_9.jpg", new double[] { 0.18259804, 0.2136765, 0.6335784, 0.643790841 });
    regionMap.put("fork_10.jpg", new double[] { 0.05269608, 0.282303959, 0.8088235, 0.452614367 });
    regionMap.put("fork_11.jpg", new double[] { 0.05759804, 0.0894935, 0.9007353, 0.3251634 });
    regionMap.put("fork_12.jpg", new double[] { 0.3345588, 0.07315363, 0.375, 0.9150327 });
    regionMap.put("fork_13.jpg", new double[] { 0.269607842, 0.194068655, 0.4093137, 0.6732026 });
    regionMap.put("fork_14.jpg", new double[] { 0.143382356, 0.218578458, 0.7977941, 0.295751631 });
    regionMap.put("fork_15.jpg", new double[] { 0.19240196, 0.0633497, 0.5710784, 0.8398692 });
    regionMap.put("fork_16.jpg", new double[] { 0.140931368, 0.480016381, 0.6838235, 0.240196079 });
    regionMap.put("fork_17.jpg", new double[] { 0.305147052, 0.2512582, 0.4791667, 0.5408496 });
    regionMap.put("fork_18.jpg", new double[] { 0.234068632, 0.445702642, 0.6127451, 0.344771236 });
    regionMap.put("fork_19.jpg", new double[] { 0.219362751, 0.141781077, 0.5919118, 0.6683006 });
    regionMap.put("fork_20.jpg", new double[] { 0.180147052, 0.239820287, 0.6887255, 0.235294119 });

In het volgende codeblok worden de afbeeldingen aan het project toegevoegd. Je moet de argumenten van de GetImage oproepen wijzigen om te verwijzen naar de locaties van de fork- en schaar-mappen die je hebt gedownload.

    Trainings trainer = trainClient.trainings();

    System.out.println("Adding images...");
    for (int i = 1; i <= 20; i++) {
        String fileName = "fork_" + i + ".jpg";
        byte[] contents = GetImage("/fork", fileName);
        AddImageToProject(trainer, project, fileName, contents, forkTag.id(), regionMap.get(fileName));
    }

    for (int i = 1; i <= 20; i++) {
        String fileName = "scissors_" + i + ".jpg";
        byte[] contents = GetImage("/scissors", fileName);
        AddImageToProject(trainer, project, fileName, contents, scissorsTag.id(), regionMap.get(fileName));
    }
}

Het vorige codefragment maakt gebruik van twee helperfuncties waarmee de afbeeldingen als resourcestreams worden opgehaald en naar de service worden geüpload (u kunt maximaal 64 afbeeldingen in één batch uploaden). Definieer deze methoden.

private static void AddImageToProject(Trainings trainer, Project project, String fileName, byte[] contents,
        UUID tag, double[] regionValues) {
    System.out.println("Adding image: " + fileName);
    ImageFileCreateEntry file = new ImageFileCreateEntry().withName(fileName).withContents(contents);

    ImageFileCreateBatch batch = new ImageFileCreateBatch().withImages(Collections.singletonList(file));

    // If Optional region is specified, tack it on and place the tag there,
    // otherwise
    // add it to the batch.
    if (regionValues != null) {
        Region region = new Region().withTagId(tag).withLeft(regionValues[0]).withTop(regionValues[1])
                .withWidth(regionValues[2]).withHeight(regionValues[3]);
        file = file.withRegions(Collections.singletonList(region));
    } else {
        batch = batch.withTagIds(Collections.singletonList(tag));
    }

    trainer.createImagesFromFiles(project.id(), batch);
}

private static byte[] GetImage(String folder, String fileName) {
    try {
        return ByteStreams.toByteArray(CustomVisionSamples.class.getResourceAsStream(folder + "/" + fileName));
    } catch (Exception e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
    return null;
}

Het project trainen

Met deze methode maakt u de eerste trainingsiteratie in het project. Er wordt een query uitgevoerd op de service totdat de training is voltooid.

public static String trainProjectOD(CustomVisionTrainingClient trainClient, Project project) {
    Trainings trainer = trainClient.trainings();
    System.out.println("Training...");
    Iteration iteration = trainer.trainProject(project.id(), new TrainProjectOptionalParameter());

    while (iteration.status().equals("Training")) {
        System.out.println("Training Status: " + iteration.status());
        Thread.sleep(5000);
        iteration = trainer.getIteration(project.id(), iteration.id());
    }
    System.out.println("Training Status: " + iteration.status());
}

De huidige iteratie publiceren

Met deze methode wordt de huidige iteratie van het model beschikbaar voor het uitvoeren van query's. U kunt de modelnaam gebruiken als verwijzing om voorspellingsaanvragen te verzenden. U moet uw eigen waarde invoeren voor predictionResourceId. U vindt de voorspellingsresource-id op het tabblad Properties van de resource in de Azure-portal, vermeld als Resource-id.

public static String publishIterationOD(CustomVisionTrainingClient trainClient, Project project) {
    Trainings trainer = trainClient.trainings();

    // The iteration is now trained. Publish it to the prediction endpoint.
    String publishedModelName = "myModel";
    String predictionID = "<your-prediction-resource-ID>";
    trainer.publishIteration(project.id(), iteration.id(), publishedModelName, predictionID);
    return publishedModelName;
}

Het voorspellingseindpunt testen

Met deze methode wordt de testafbeelding geladen, wordt het modeleindpunt opgevraagd en worden voorspellingsgegevens naar de console uitgevoerd.

public static void testProjectOD(CustomVisionPredictionClient predictor, Project project) {

    // load test image
    byte[] testImage = GetImage("/ObjectTest", "test_image.jpg");

    // predict
    ImagePrediction results = predictor.predictions().detectImage().withProjectId(project.id())
            .withPublishedName(publishedModelName).withImageData(testImage).execute();

    for (Prediction prediction : results.predictions()) {
        System.out.println(String.format("\t%s: %.2f%% at: %.2f, %.2f, %.2f, %.2f", prediction.tagName(),
                prediction.probability() * 100.0f, prediction.boundingBox().left(), prediction.boundingBox().top(),
                prediction.boundingBox().width(), prediction.boundingBox().height()));
    }
}

De toepassing uitvoeren

U kunt de app bouwen met:

gradle build

Voer de toepassing uit met de gradle run opdracht:

gradle run

Resources opschonen

Als u een Azure AI-services-abonnement wilt opschonen en verwijderen, kunt u de resource of resourcegroep verwijderen. Als u de resourcegroep verwijdert, worden ook alle andere resources verwijderd die eraan zijn gekoppeld.

Als u uw eigen objectdetectieproject wilt implementeren (of in plaats daarvan een afbeeldingsclassificatieproject wilt proberen), kunt u het detectieproject voor fork/schaar uit dit voorbeeld verwijderen. Met een gratis abonnement kunt u twee Custom Vision-projecten uitvoeren.

Ga op de website Custom Vision naar Projects en selecteer de prullenbak onder Mijn nieuwe Project.

Schermopname van een paneel met het label Mijn nieuwe Project met een prullenbakpictogram.

Volgende stappen

Nu hebt u elke stap van het objectdetectieproces in code uitgevoerd. In dit voorbeeld wordt één trainingsiteratie uitgevoerd, maar vaak moet u uw model meerdere keren trainen en testen om het nauwkeuriger te maken. De volgende handleiding gaat over afbeeldingsclassificatie, maar de principes zijn vergelijkbaar met objectdetectie.

  • Wat is Custom Vision?
  • De broncode voor dit voorbeeld vindt u op GitHub

Deze handleiding bevat instructies en voorbeeldcode om u te helpen aan de slag te gaan met de Custom Vision-clientbibliotheek voor Node.js om een objectdetectiemodel te bouwen. U maakt een project, voegt tags toe, traint het project en gebruikt de voorspellingseindpunt-URL van het project om het programmatisch te testen. Gebruik dit voorbeeld als sjabloon voor het bouwen van uw eigen app voor afbeeldingsherkenning.

Opmerking

Als u een objectdetectiemodel wilt bouwen en trainen zonder code te schrijven, raadpleegt u in plaats daarvan de richtlijnen op basis van de browser .

Referentiedocumentatie (training)(voorspelling) | Pakket (npm) (training)(voorspelling) | Voorbeelden

Voorwaarden

  • Azure-abonnement - Gratis een abonnement maken
  • De huidige versie van Node.js
  • Zodra u uw Azure-abonnement hebt, maakt u een Custom Vision-resource in de Azure-portal om een trainings- en voorspellingsresource te maken.
    • U kunt de gratis prijscategorie (F0) gebruiken om de service uit te proberen en later een upgrade uit te voeren naar een betaalde laag voor productie.

Omgevingsvariabelen maken

In dit voorbeeld schrijft u uw inloggegevens naar omgevingsvariabelen op de lokale computer die de toepassing uitvoert.

Ga naar de Azure-portal. Als de Custom Vision-resources die u hebt gemaakt in de sectie Vereisten zijn geïmplementeerd, selecteert u de knop Ga naar resource onder Volgende stappen. U vindt uw sleutels en eindpunten op de pagina's Sleutels en eindpunten van de resources onder Resourcebeheer. U moet de sleutels voor uw trainingsresource en voorspellingsresource ophalen, samen met de API-eindpunten.

U vindt de id van de voorspellingsresource op het tabblad Properties in de Azure-portal, vermeld als Resource-id.

Tip

U gebruikt https://www.customvision.ai ook om deze waarden op te halen. Nadat u zich hebt aangemeld, selecteert u het pictogram Instellingen rechtsboven. Op de pagina's Instellingen kunt u alle sleutels, resource-id's en eindpunten weergeven.

Als u de omgevingsvariabelen wilt instellen, opent u een consolevenster en volgt u de instructies voor uw besturingssysteem en ontwikkelomgeving.

  • Als u de VISION_TRAINING KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-training-key> een van de sleutels voor uw trainingsresource.
  • Stel de VISION_TRAINING_ENDPOINT omgevingsvariabele in door <your-training-endpoint> te vervangen door het eindpunt voor uw trainingsresource.
  • Als u de VISION_PREDICTION_KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-prediction-key> een van de sleutels voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_ENDPOINT omgevingsvariabele wilt instellen, vervangt u het <your-prediction-endpoint> eindpunt voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_RESOURCE_ID omgevingsvariabele wilt instellen, vervangt u deze door <your-resource-id> de resource-id voor uw voorspellingsresource.

Belangrijk

We raden Microsoft Entra ID-authenticatie aan met beheerde identiteiten voor Azure-resources om te voorkomen dat referenties worden opgeslagen bij uw toepassingen die in de cloud draaien.

Gebruik API-sleutels met voorzichtigheid. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar. Als u API-sleutels gebruikt, slaat u deze veilig op in Azure Key Vault, draait u de sleutels regelmatig en beperkt u de toegang tot Azure Key Vault met behulp van op rollen gebaseerd toegangsbeheer en netwerktoegangsbeperkingen. Zie API-sleutels met Azure Key Vault voor meer informatie over het veilig gebruiken van API-sleutels in uw apps.

Zie Authenticate requests to Azure AI-services voor meer informatie over beveiliging van AI-services.

setx VISION_TRAINING_KEY <your-training-key>
setx VISION_TRAINING_ENDPOINT <your-training-endpoint>
setx VISION_PREDICTION_KEY <your-prediction-key>
setx VISION_PREDICTION_ENDPOINT <your-prediction-endpoint>
setx VISION_PREDICTION_RESOURCE_ID <your-resource-id>

Nadat u de omgevingsvariabelen hebt toegevoegd, moet u mogelijk alle actieve programma's die de omgevingsvariabelen lezen opnieuw opstarten, inclusief het consolevenster.

Instellen

Een nieuwe Node.js-toepassing maken

Maak in een consolevenster (zoals cmd, PowerShell of Bash) een nieuwe map voor uw app en navigeer ernaartoe.

mkdir myapp && cd myapp

Voer de npm init opdracht uit om een knooppunttoepassing met een package.json bestand te maken.

npm init

De clientbibliotheek installeren

Als u een app voor afbeeldingsanalyse wilt schrijven met Custom Vision voor Node.js, hebt u de Npm-pakketten van Custom Vision nodig. Voer de volgende opdracht uit in PowerShell om ze te installeren:

npm install @azure/cognitiveservices-customvision-training
npm install @azure/cognitiveservices-customvision-prediction

Het package.json-bestand van uw app wordt bijgewerkt met de afhankelijkheden.

Maak een bestand met de naam index.js en importeer de volgende bibliotheken:

const util = require('util');
const fs = require('fs');
const TrainingApi = require("@azure/cognitiveservices-customvision-training");
const PredictionApi = require("@azure/cognitiveservices-customvision-prediction");
const msRest = require("@azure/ms-rest-js");

Tip

Wilt u het hele quickstart-codebestand tegelijk weergeven? U vindt deze op GitHub, die de codevoorbeelden in deze quickstart bevat.

Maak variabelen voor het Azure eindpunt en sleutels van uw resource.

// retrieve environment variables
const trainingKey = process.env["VISION_TRAINING_KEY"];
const trainingEndpoint = process.env["VISION_TRAINING_ENDPOINT"];

const predictionKey = process.env["VISION_PREDICTION_KEY"];
const predictionResourceId = process.env["VISION_PREDICTION_RESOURCE_ID"];
const predictionEndpoint = process.env["VISION_PREDICTION_ENDPOINT"];

Voeg ook velden toe voor uw projectnaam en een time-outparameter voor asynchrone aanroepen.

const publishIterationName = "detectModel";
const setTimeoutPromise = util.promisify(setTimeout);

Objectmodel

Naam Beschrijving
TrainingAPIClient Deze klasse verwerkt het maken, trainen en publiceren van uw modellen.
PredictionAPIClient Deze klasse verwerkt de query's van uw modellen voor voorspellingen voor objectdetectie.
Voorspelling Deze interface definieert één voorspelling op één afbeelding. Het bevat eigenschappen voor de object-id en naam en een betrouwbaarheidsscore.

Codevoorbeelden

Deze codefragmenten laten zien hoe u de volgende taken kunt uitvoeren met de Custom Vision-clientbibliotheek voor JavaScript:

De client verifiëren

Instantieer clientobjecten met uw eindpunt en sleutel. Maak een ApiKeyCredentials-object met uw sleutel en gebruik het met uw eindpunt om een TrainingAPIClient - en PredictionAPIClient-object te maken.

const credentials = new msRest.ApiKeyCredentials({ inHeader: { "Training-key": trainingKey } });
const trainer = new TrainingApi.TrainingAPIClient(credentials, trainingEndpoint);
const predictor_credentials = new msRest.ApiKeyCredentials({ inHeader: { "Prediction-key": predictionKey } });
const predictor = new PredictionApi.PredictionAPIClient(predictor_credentials, predictionEndpoint);

Helperfunctie toevoegen

Voeg de volgende functie toe om meerdere asynchrone aanroepen te maken. Je zult dit later gebruiken.

const credentials = new msRest.ApiKeyCredentials({ inHeader: { "Training-key": trainingKey } });
const trainer = new TrainingApi.TrainingAPIClient(credentials, trainingEndpoint);
const predictor_credentials = new msRest.ApiKeyCredentials({ inHeader: { "Prediction-key": predictionKey } });
const predictor = new PredictionApi.PredictionAPIClient(predictor_credentials, predictionEndpoint);

Een nieuw Custom Vision-project maken

Start een nieuwe functie die al uw Custom Vision-functie-aanroepen bevat. Voeg de volgende code toe om een nieuw Custom Vision-serviceproject te maken.

(async () => {
    console.log("Creating project...");
    const domains = await trainer.getDomains()
    const objDetectDomain = domains.find(domain => domain.type === "ObjectDetection");
    const sampleProject = await trainer.createProject("Sample Obj Detection Project", { domainId: objDetectDomain.id });

Tags toevoegen aan het project

Als u classificatietags wilt maken voor uw project, voegt u de volgende code toe aan uw functie:

const forkTag = await trainer.createTag(sampleProject.id, "Fork");
const scissorsTag = await trainer.createTag(sampleProject.id, "Scissors");

Afbeeldingen uploaden en taggen

Download eerst de voorbeeldafbeeldingen voor dit project. Sla de inhoud van de map sample Images op uw lokale apparaat op.

Als u de voorbeeldafbeeldingen aan het project wilt toevoegen, voegt u de volgende code in na het maken van de tag. Met deze code wordt elke afbeelding met de bijbehorende tag geüpload. Wanneer u afbeeldingen tagt in objectdetectieprojecten, moet u de regio van elk gelabeld object opgeven met behulp van genormaliseerde coördinaten. Voor deze zelfstudie worden de regio's inline vastgelegd met de code. De regio's geven het begrenzingsvak op in genormaliseerde coördinaten en de coördinaten worden weergegeven in de volgorde: links, boven, breedte, hoogte. U kunt maximaal 64 afbeeldingen uploaden in één batch.

const sampleDataRoot = "Images";

const forkImageRegions = {
    "fork_1.jpg": [0.145833328, 0.3509314, 0.5894608, 0.238562092],
    "fork_2.jpg": [0.294117659, 0.216944471, 0.534313738, 0.5980392],
    "fork_3.jpg": [0.09191177, 0.0682516545, 0.757352948, 0.6143791],
    "fork_4.jpg": [0.254901975, 0.185898721, 0.5232843, 0.594771266],
    "fork_5.jpg": [0.2365196, 0.128709182, 0.5845588, 0.71405226],
    "fork_6.jpg": [0.115196079, 0.133611143, 0.676470637, 0.6993464],
    "fork_7.jpg": [0.164215669, 0.31008172, 0.767156839, 0.410130739],
    "fork_8.jpg": [0.118872553, 0.318251669, 0.817401946, 0.225490168],
    "fork_9.jpg": [0.18259804, 0.2136765, 0.6335784, 0.643790841],
    "fork_10.jpg": [0.05269608, 0.282303959, 0.8088235, 0.452614367],
    "fork_11.jpg": [0.05759804, 0.0894935, 0.9007353, 0.3251634],
    "fork_12.jpg": [0.3345588, 0.07315363, 0.375, 0.9150327],
    "fork_13.jpg": [0.269607842, 0.194068655, 0.4093137, 0.6732026],
    "fork_14.jpg": [0.143382356, 0.218578458, 0.7977941, 0.295751631],
    "fork_15.jpg": [0.19240196, 0.0633497, 0.5710784, 0.8398692],
    "fork_16.jpg": [0.140931368, 0.480016381, 0.6838235, 0.240196079],
    "fork_17.jpg": [0.305147052, 0.2512582, 0.4791667, 0.5408496],
    "fork_18.jpg": [0.234068632, 0.445702642, 0.6127451, 0.344771236],
    "fork_19.jpg": [0.219362751, 0.141781077, 0.5919118, 0.6683006],
    "fork_20.jpg": [0.180147052, 0.239820287, 0.6887255, 0.235294119]
};

const scissorsImageRegions = {
    "scissors_1.jpg": [0.4007353, 0.194068655, 0.259803921, 0.6617647],
    "scissors_2.jpg": [0.426470578, 0.185898721, 0.172794119, 0.5539216],
    "scissors_3.jpg": [0.289215684, 0.259428144, 0.403186262, 0.421568632],
    "scissors_4.jpg": [0.343137264, 0.105833367, 0.332107842, 0.8055556],
    "scissors_5.jpg": [0.3125, 0.09766343, 0.435049027, 0.71405226],
    "scissors_6.jpg": [0.379901975, 0.24308826, 0.32107842, 0.5718954],
    "scissors_7.jpg": [0.341911763, 0.20714055, 0.3137255, 0.6356209],
    "scissors_8.jpg": [0.231617644, 0.08459154, 0.504901946, 0.8480392],
    "scissors_9.jpg": [0.170343131, 0.332957536, 0.767156839, 0.403594762],
    "scissors_10.jpg": [0.204656869, 0.120539248, 0.5245098, 0.743464053],
    "scissors_11.jpg": [0.05514706, 0.159754932, 0.799019635, 0.730392158],
    "scissors_12.jpg": [0.265931368, 0.169558853, 0.5061275, 0.606209159],
    "scissors_13.jpg": [0.241421565, 0.184264734, 0.448529422, 0.6830065],
    "scissors_14.jpg": [0.05759804, 0.05027781, 0.75, 0.882352948],
    "scissors_15.jpg": [0.191176474, 0.169558853, 0.6936275, 0.6748366],
    "scissors_16.jpg": [0.1004902, 0.279036, 0.6911765, 0.477124184],
    "scissors_17.jpg": [0.2720588, 0.131977156, 0.4987745, 0.6911765],
    "scissors_18.jpg": [0.180147052, 0.112369314, 0.6262255, 0.6666667],
    "scissors_19.jpg": [0.333333343, 0.0274019931, 0.443627447, 0.852941155],
    "scissors_20.jpg": [0.158088237, 0.04047389, 0.6691176, 0.843137264]
};

console.log("Adding images...");
let fileUploadPromises = [];

const forkDir = `${sampleDataRoot}/fork`;
const forkFiles = fs.readdirSync(forkDir);

await asyncForEach(forkFiles, async (file) => {
    const region = { tagId: forkTag.id, left: forkImageRegions[file][0], top: forkImageRegions[file][1], width: forkImageRegions[file][2], height: forkImageRegions[file][3] };
    const entry = { name: file, contents: fs.readFileSync(`${forkDir}/${file}`), regions: [region] };
    const batch = { images: [entry] };
    // Wait one second to accommodate rate limit.
    await setTimeoutPromise(1000, null);
    fileUploadPromises.push(trainer.createImagesFromFiles(sampleProject.id, batch));
});

const scissorsDir = `${sampleDataRoot}/scissors`;
const scissorsFiles = fs.readdirSync(scissorsDir);

await asyncForEach(scissorsFiles, async (file) => {
    const region = { tagId: scissorsTag.id, left: scissorsImageRegions[file][0], top: scissorsImageRegions[file][1], width: scissorsImageRegions[file][2], height: scissorsImageRegions[file][3] };
    const entry = { name: file, contents: fs.readFileSync(`${scissorsDir}/${file}`), regions: [region] };
    const batch = { images: [entry] };
    // Wait one second to accommodate rate limit.
    await setTimeoutPromise(1000, null);
    fileUploadPromises.push(trainer.createImagesFromFiles(sampleProject.id, batch));
});

await Promise.all(fileUploadPromises);

Belangrijk

U moet het pad naar de afbeeldingen (sampleDataRoot) wijzigen op basis van de locatie waar u de Foundry Tools Python SDK Samples-repository hebt gedownload.

Opmerking

Als u geen hulpprogramma voor klikken en slepen hebt om de coördinaten van regio's te markeren, kunt u de webgebruikersinterface op Customvision.ai gebruiken. In dit voorbeeld zijn de coördinaten al opgegeven.

Het project trainen

Met deze code wordt de eerste iteratie van het voorspellingsmodel gemaakt.

console.log("Training...");
let trainingIteration = await trainer.trainProject(sampleProject.id);

// Wait for training to complete
console.log("Training started...");
while (trainingIteration.status == "Training") {
    console.log("Training status: " + trainingIteration.status);
    // wait for ten seconds
    await setTimeoutPromise(10000, null);
    trainingIteration = await trainer.getIteration(sampleProject.id, trainingIteration.id)
}
console.log("Training status: " + trainingIteration.status);

De huidige iteratie publiceren

Met deze code wordt de getrainde iteratie naar het voorspellingseindpunt gepubliceerd. De naam die aan de gepubliceerde iteratie wordt gegeven, kan worden gebruikt om voorspellingsaanvragen te verzenden. Een iteratie is pas beschikbaar in het voorspellingseindpunt als het is gepubliceerd.

// Publish the iteration to the end point
await trainer.publishIteration(sampleProject.id, trainingIteration.id, publishIterationName, predictionResourceId);    

Het voorspellingseindpunt testen

Als u een afbeelding naar het voorspellingseindpunt wilt verzenden en de voorspelling wilt ophalen, voegt u de volgende code toe aan uw functie.

const testFile = fs.readFileSync(`${sampleDataRoot}/test/test_image.jpg`);
const results = await predictor.detectImage(sampleProject.id, publishIterationName, testFile)

// Show results
console.log("Results:");
results.predictions.forEach(predictedResult => {
    console.log(`\t ${predictedResult.tagName}: ${(predictedResult.probability * 100.0).toFixed(2)}% ${predictedResult.boundingBox.left},${predictedResult.boundingBox.top},${predictedResult.boundingBox.width},${predictedResult.boundingBox.height}`);
});

Sluit vervolgens uw Custom Vision-functie en roep deze aan.

})()

De toepassing uitvoeren

Voer de toepassing uit met de node opdracht in uw quickstart-bestand.

node index.js

De uitvoer van de toepassing moet worden weergegeven in de console. Vervolgens kunt u controleren of de testafbeelding (gevonden in <sampleDataRoot>/Test/) op de juiste wijze is gelabeld en of de detectieregio juist is. U kunt ook teruggaan naar de Custom Vision-website en de huidige status van uw zojuist gemaakte project bekijken.

Resources opschonen

Als u uw eigen objectdetectieproject wilt implementeren (of in plaats daarvan een afbeeldingsclassificatieproject wilt proberen), kunt u het detectieproject voor fork/schaar uit dit voorbeeld verwijderen. Met een gratis abonnement kunt u twee Custom Vision-projecten uitvoeren.

Ga op de website Custom Vision naar Projects en selecteer de prullenbak onder Mijn nieuwe Project.

Schermopname van een paneel met het label Mijn nieuwe Project met een prullenbakpictogram.

Volgende stappen

Nu hebt u elke stap van het objectdetectieproces in code uitgevoerd. In dit voorbeeld wordt één trainingsiteratie uitgevoerd, maar vaak moet u uw model meerdere keren trainen en testen om het nauwkeuriger te maken. De volgende handleiding gaat over afbeeldingsclassificatie, maar de principes zijn vergelijkbaar met objectdetectie.

Ga aan de slag met de Custom Vision-clientbibliotheek voor Python. Volg deze stappen om het pakket te installeren en de voorbeeldcode uit te proberen voor het bouwen van een objectdetectiemodel. U maakt een project, voegt tags toe, traint het project en gebruikt de voorspellingseindpunt-URL van het project om het programmatisch te testen. Gebruik dit voorbeeld als sjabloon voor het bouwen van uw eigen app voor afbeeldingsherkenning.

Opmerking

Als u een objectdetectiemodel wilt bouwen en trainen zonder code te schrijven, raadpleegt u in plaats daarvan de richtlijnen op basis van de browser .

Referentiedocumentatie | Library-broncode | Package (PyPI) | Voorbeelden

Voorwaarden

  • Azure-abonnement - Gratis een abonnement maken
  • Python 3.x
    • De installatie van uw Python moet pip bevatten. U kunt controleren of pip is geïnstalleerd door op de opdrachtregel uit te voeren pip --version . Installeer pip door de nieuwste versie van Python te installeren.
  • Zodra u uw Azure-abonnement hebt, maak een Custom Vision-resource in de Azure-portal om een trainings- en voorspellingsresource te maken.
    • U kunt de gratis prijscategorie (F0) gebruiken om de service uit te proberen en later een upgrade uit te voeren naar een betaalde laag voor productie.

Omgevingsvariabelen maken

In dit voorbeeld schrijft u uw inloggegevens naar omgevingsvariabelen op de lokale computer die de toepassing uitvoert.

Ga naar de Azure-portal. Als de Custom Vision-resources die u hebt gemaakt in de sectie Vereisten zijn geïmplementeerd, selecteert u de knop Ga naar resource onder Volgende stappen. U vindt uw sleutels en eindpunten op de pagina's Sleutels en eindpunten van de resources onder Resourcebeheer. U moet de sleutels voor uw trainingsresource en voorspellingsresource ophalen, samen met de API-eindpunten.

U vindt de id van de voorspellingsresource op het tabblad Properties in de Azure-portal, vermeld als Resource-id.

Tip

U gebruikt https://www.customvision.ai ook om deze waarden op te halen. Nadat u zich hebt aangemeld, selecteert u het pictogram Instellingen rechtsboven. Op de pagina's Instellingen kunt u alle sleutels, resource-id's en eindpunten weergeven.

Als u de omgevingsvariabelen wilt instellen, opent u een consolevenster en volgt u de instructies voor uw besturingssysteem en ontwikkelomgeving.

  • Als u de VISION_TRAINING KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-training-key> een van de sleutels voor uw trainingsresource.
  • Stel de VISION_TRAINING_ENDPOINT omgevingsvariabele in door <your-training-endpoint> te vervangen door het eindpunt voor uw trainingsresource.
  • Als u de VISION_PREDICTION_KEY omgevingsvariabele wilt instellen, vervangt u deze door <your-prediction-key> een van de sleutels voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_ENDPOINT omgevingsvariabele wilt instellen, vervangt u het <your-prediction-endpoint> eindpunt voor uw voorspellingsresource.
  • Als u de VISION_PREDICTION_RESOURCE_ID omgevingsvariabele wilt instellen, vervangt u deze door <your-resource-id> de resource-id voor uw voorspellingsresource.

Belangrijk

We raden Microsoft Entra ID-authenticatie aan met beheerde identiteiten voor Azure-resources om te voorkomen dat referenties worden opgeslagen bij uw toepassingen die in de cloud draaien.

Gebruik API-sleutels met voorzichtigheid. Neem de API-sleutel niet rechtstreeks in uw code op en plaats deze nooit openbaar. Als u API-sleutels gebruikt, slaat u deze veilig op in Azure Key Vault, draait u de sleutels regelmatig en beperkt u de toegang tot Azure Key Vault met behulp van op rollen gebaseerd toegangsbeheer en netwerktoegangsbeperkingen. Zie API-sleutels met Azure Key Vault voor meer informatie over het veilig gebruiken van API-sleutels in uw apps.

Zie Authenticate requests to Azure AI-services voor meer informatie over beveiliging van AI-services.

setx VISION_TRAINING_KEY <your-training-key>
setx VISION_TRAINING_ENDPOINT <your-training-endpoint>
setx VISION_PREDICTION_KEY <your-prediction-key>
setx VISION_PREDICTION_ENDPOINT <your-prediction-endpoint>
setx VISION_PREDICTION_RESOURCE_ID <your-resource-id>

Nadat u de omgevingsvariabelen hebt toegevoegd, moet u mogelijk alle actieve programma's die de omgevingsvariabelen lezen opnieuw opstarten, inclusief het consolevenster.

Instellen

De clientbibliotheek installeren

Als u een app voor afbeeldingsanalyse wilt schrijven met Custom Vision voor Python, hebt u de Custom Vision-clientbibliotheek nodig. Nadat u Python hebt geïnstalleerd, voert u de volgende opdracht uit in PowerShell of een consolevenster:

pip install azure-cognitiveservices-vision-customvision

Een nieuwe Python-toepassing maken

Maak een nieuw Python-bestand en importeer de volgende bibliotheken.

from azure.cognitiveservices.vision.customvision.training import CustomVisionTrainingClient
from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient
from azure.cognitiveservices.vision.customvision.training.models import ImageFileCreateBatch, ImageFileCreateEntry, Region
from msrest.authentication import ApiKeyCredentials
import os, time, uuid

Tip

Wilt u het hele quickstart-codebestand tegelijk weergeven? U vindt deze op GitHub, die de codevoorbeelden in deze quickstart bevat.

Maak variabelen voor het Azure eindpunt en sleutels van uw resource.

# Replace with vprediction_endpointalid values
ENDPOINT = os.environ["VISION_TRAINING_ENDPOINT"]
prediction_endpoint = os.environ["VISION_PREDICTION_ENDPOINT"]
training_key = os.environ["VISION_TRAINING_KEY"]
prediction_key = os.environ["VISION_PREDICTION_KEY"]
prediction_resource_id = os.environ["VISION_PREDICTION_RESOURCE_ID"]

Objectmodel

Naam Beschrijving
CustomVisionTrainingClient Deze klasse verwerkt het maken, trainen en publiceren van uw modellen.
CustomVisionPredictionClient Deze klasse verwerkt de query's van uw modellen voor voorspellingen voor objectdetectie.
ImagePrediction Deze klasse definieert een voorspelling van één object op één afbeelding. Het bevat eigenschappen voor de object-id en naam, de locatie van het omsluitende kader van het object en een nauwkeurigheidsscore.

Codevoorbeelden

Deze codefragmenten laten zien hoe u het volgende kunt doen met de Custom Vision-clientbibliotheek voor Python:

De client verifiëren

Instantieer een trainings- en voorspellingsclient met uw eindpunt en sleutels. Maak ApiKeyServiceClientCredentials-objecten met uw sleutels en gebruik deze met uw eindpunt om een CustomVisionTrainingClient- en CustomVisionPredictionClient-object te maken.

credentials = ApiKeyCredentials(in_headers={"Training-key": training_key})
trainer = CustomVisionTrainingClient(ENDPOINT, credentials)
prediction_credentials = ApiKeyCredentials(in_headers={"Prediction-key": prediction_key})
predictor = CustomVisionPredictionClient(prediction_endpoint, prediction_credentials)

Een nieuw Custom Vision-project maken

Voeg de volgende code toe aan uw script om een nieuw Custom Vision-serviceproject te maken.

Zie de methode create_project om andere opties op te geven wanneer u uw project maakt (uitgelegd in de handleiding een detectorwebportal bouwen).

publish_iteration_name = "detectModel"

# Find the object detection domain
obj_detection_domain = next(domain for domain in trainer.get_domains() if domain.type == "ObjectDetection" and domain.name == "General")

# Create a new project
print ("Creating project...")
# Use uuid to avoid project name collisions.
project = trainer.create_project(str(uuid.uuid4()), domain_id=obj_detection_domain.id)

Tags toevoegen aan het project

Als u objecttags in uw project wilt maken, voegt u de volgende code toe:

# Make two tags in the new project
fork_tag = trainer.create_tag(project.id, "fork")
scissors_tag = trainer.create_tag(project.id, "scissors")

Afbeeldingen uploaden en taggen

Download eerst de voorbeeldafbeeldingen voor dit project. Sla de inhoud van de map sample Images op uw lokale apparaat op.

Wanneer u afbeeldingen tagt in objectdetectieprojecten, moet u de regio van elk gelabeld object opgeven met behulp van genormaliseerde coördinaten. De volgende code koppelt elk van de voorbeeldafbeeldingen aan de getagde regio. De regio's geven het begrenzingsvak op in genormaliseerde coördinaten en de coördinaten worden weergegeven in de volgorde: links, boven, breedte, hoogte.

fork_image_regions = {
    "fork_1": [ 0.145833328, 0.3509314, 0.5894608, 0.238562092 ],
    "fork_2": [ 0.294117659, 0.216944471, 0.534313738, 0.5980392 ],
    "fork_3": [ 0.09191177, 0.0682516545, 0.757352948, 0.6143791 ],
    "fork_4": [ 0.254901975, 0.185898721, 0.5232843, 0.594771266 ],
    "fork_5": [ 0.2365196, 0.128709182, 0.5845588, 0.71405226 ],
    "fork_6": [ 0.115196079, 0.133611143, 0.676470637, 0.6993464 ],
    "fork_7": [ 0.164215669, 0.31008172, 0.767156839, 0.410130739 ],
    "fork_8": [ 0.118872553, 0.318251669, 0.817401946, 0.225490168 ],
    "fork_9": [ 0.18259804, 0.2136765, 0.6335784, 0.643790841 ],
    "fork_10": [ 0.05269608, 0.282303959, 0.8088235, 0.452614367 ],
    "fork_11": [ 0.05759804, 0.0894935, 0.9007353, 0.3251634 ],
    "fork_12": [ 0.3345588, 0.07315363, 0.375, 0.9150327 ],
    "fork_13": [ 0.269607842, 0.194068655, 0.4093137, 0.6732026 ],
    "fork_14": [ 0.143382356, 0.218578458, 0.7977941, 0.295751631 ],
    "fork_15": [ 0.19240196, 0.0633497, 0.5710784, 0.8398692 ],
    "fork_16": [ 0.140931368, 0.480016381, 0.6838235, 0.240196079 ],
    "fork_17": [ 0.305147052, 0.2512582, 0.4791667, 0.5408496 ],
    "fork_18": [ 0.234068632, 0.445702642, 0.6127451, 0.344771236 ],
    "fork_19": [ 0.219362751, 0.141781077, 0.5919118, 0.6683006 ],
    "fork_20": [ 0.180147052, 0.239820287, 0.6887255, 0.235294119 ]
}

scissors_image_regions = {
    "scissors_1": [ 0.4007353, 0.194068655, 0.259803921, 0.6617647 ],
    "scissors_2": [ 0.426470578, 0.185898721, 0.172794119, 0.5539216 ],
    "scissors_3": [ 0.289215684, 0.259428144, 0.403186262, 0.421568632 ],
    "scissors_4": [ 0.343137264, 0.105833367, 0.332107842, 0.8055556 ],
    "scissors_5": [ 0.3125, 0.09766343, 0.435049027, 0.71405226 ],
    "scissors_6": [ 0.379901975, 0.24308826, 0.32107842, 0.5718954 ],
    "scissors_7": [ 0.341911763, 0.20714055, 0.3137255, 0.6356209 ],
    "scissors_8": [ 0.231617644, 0.08459154, 0.504901946, 0.8480392 ],
    "scissors_9": [ 0.170343131, 0.332957536, 0.767156839, 0.403594762 ],
    "scissors_10": [ 0.204656869, 0.120539248, 0.5245098, 0.743464053 ],
    "scissors_11": [ 0.05514706, 0.159754932, 0.799019635, 0.730392158 ],
    "scissors_12": [ 0.265931368, 0.169558853, 0.5061275, 0.606209159 ],
    "scissors_13": [ 0.241421565, 0.184264734, 0.448529422, 0.6830065 ],
    "scissors_14": [ 0.05759804, 0.05027781, 0.75, 0.882352948 ],
    "scissors_15": [ 0.191176474, 0.169558853, 0.6936275, 0.6748366 ],
    "scissors_16": [ 0.1004902, 0.279036, 0.6911765, 0.477124184 ],
    "scissors_17": [ 0.2720588, 0.131977156, 0.4987745, 0.6911765 ],
    "scissors_18": [ 0.180147052, 0.112369314, 0.6262255, 0.6666667 ],
    "scissors_19": [ 0.333333343, 0.0274019931, 0.443627447, 0.852941155 ],
    "scissors_20": [ 0.158088237, 0.04047389, 0.6691176, 0.843137264 ]
}

Opmerking

Als u geen hulpprogramma voor klikken en slepen hebt om de coördinaten van regio's te markeren, kunt u de webgebruikersinterface op Customvision.ai gebruiken. In dit voorbeeld zijn de coördinaten al opgegeven.

Gebruik vervolgens deze kaart met koppelingen om elke voorbeeldafbeelding te uploaden met de bijbehorende regiocoördinaten (u kunt maximaal 64 afbeeldingen in één batch uploaden). Voeg de volgende code toe.

base_image_location = os.path.join (os.path.dirname(__file__), "Images")

# Go through the data table above and create the images
print ("Adding images...")
tagged_images_with_regions = []

for file_name in fork_image_regions.keys():
    x,y,w,h = fork_image_regions[file_name]
    regions = [ Region(tag_id=fork_tag.id, left=x,top=y,width=w,height=h) ]

    with open(os.path.join (base_image_location, "fork", file_name + ".jpg"), mode="rb") as image_contents:
        tagged_images_with_regions.append(ImageFileCreateEntry(name=file_name, contents=image_contents.read(), regions=regions))

for file_name in scissors_image_regions.keys():
    x,y,w,h = scissors_image_regions[file_name]
    regions = [ Region(tag_id=scissors_tag.id, left=x,top=y,width=w,height=h) ]

    with open(os.path.join (base_image_location, "scissors", file_name + ".jpg"), mode="rb") as image_contents:
        tagged_images_with_regions.append(ImageFileCreateEntry(name=file_name, contents=image_contents.read(), regions=regions))

upload_result = trainer.create_images_from_files(project.id, ImageFileCreateBatch(images=tagged_images_with_regions))
if not upload_result.is_batch_successful:
    print("Image batch upload failed.")
    for image in upload_result.images:
        print("Image status: ", image.status)
    exit(-1)

Opmerking

U moet het pad naar de afbeeldingen aanpassen op basis van waar u eerder de repository 'Foundry Tools Python SDK Samples' hebt gedownload.

Het project trainen

Met deze code wordt de eerste iteratie van het voorspellingsmodel gemaakt.

print ("Training...")
iteration = trainer.train_project(project.id)
while (iteration.status != "Completed"):
    iteration = trainer.get_iteration(project.id, iteration.id)
    print ("Training status: " + iteration.status)
    time.sleep(1)

Tip

Trainen met geselecteerde tags

U kunt eventueel alleen trainen op een subset van uw toegepaste tags. U kunt dit doen als u nog niet genoeg van bepaalde tags hebt toegepast, maar u wel genoeg van anderen hebt. Stel in de train_project aanroep de optionele parameter selected_tags in op een lijst met de id-tekenreeksen van de tags die u wilt gebruiken. Het model traint om alleen de tags in die lijst te herkennen.

De huidige iteratie publiceren

Een iteratie is pas beschikbaar in het voorspellingseindpunt als het is gepubliceerd. Met de volgende code wordt de huidige iteratie van het model beschikbaar voor het uitvoeren van query's.

# The iteration is now trained. Publish it to the project endpoint
trainer.publish_iteration(project.id, iteration.id, publish_iteration_name, prediction_resource_id)
print ("Done!")

Het voorspellingseindpunt testen

Als u een afbeelding naar het voorspellingseindpunt wilt verzenden en de voorspelling wilt ophalen, voegt u de volgende code toe aan het einde van het bestand:

# Now there is a trained endpoint that can be used to make a prediction

# Open the sample image and get back the prediction results.
with open(os.path.join (base_image_location, "test", "test_image.jpg"), mode="rb") as test_data:
    results = predictor.detect_image(project.id, publish_iteration_name, test_data)

# Display the results.    
for prediction in results.predictions:
    print("\t" + prediction.tag_name + ": {0:.2f}% bbox.left = {1:.2f}, bbox.top = {2:.2f}, bbox.width = {3:.2f}, bbox.height = {4:.2f}".format(prediction.probability * 100, prediction.bounding_box.left, prediction.bounding_box.top, prediction.bounding_box.width, prediction.bounding_box.height))

De toepassing uitvoeren

Voer CustomVisionQuickstart.py uit.

python CustomVisionQuickstart.py

De uitvoer van de toepassing moet worden weergegeven in de console. Vervolgens kunt u controleren of de testafbeelding (gevonden in <base_image_location>/images/Test) op de juiste wijze is gelabeld en of de detectieregio juist is. U kunt ook teruggaan naar de Custom Vision-website en de huidige status van uw zojuist gemaakte project bekijken.

Resources opschonen

Als u uw eigen objectdetectieproject wilt implementeren (of in plaats daarvan een afbeeldingsclassificatieproject wilt proberen), kunt u het detectieproject voor fork/schaar uit dit voorbeeld verwijderen. Met een gratis abonnement kunt u twee Custom Vision-projecten uitvoeren.

Ga op de website Custom Vision naar Projects en selecteer de prullenbak onder Mijn nieuwe Project.

Schermopname van een paneel met het label Mijn nieuwe Project met een prullenbakpictogram.

Volgende stappen

Nu hebt u elke stap van het objectdetectieproces in code uitgevoerd. In dit voorbeeld wordt één trainingsiteratie uitgevoerd, maar vaak moet u uw model meerdere keren trainen en testen om het nauwkeuriger te maken. De volgende handleiding gaat over afbeeldingsclassificatie, maar de principes zijn vergelijkbaar met objectdetectie.