Snabbstart: Skapa ett objektidentifieringsprojekt med Custom Vision-klientbiblioteket

Kom igång med Custom Vision-klientbiblioteket för .NET. Följ de här stegen för att installera paketet och prova exempelkoden för att skapa en objektidentifieringsmodell. Du skapar ett projekt, lägger till taggar, tränar projektet på exempelbilder och använder projektets förutsägelseslutpunkts-URL för att testa det programmatiskt. Använd det här exemplet som en mall för att skapa en egen app för bildigenkänning.

Kommentar

Om du vill skapa och träna en objektidentifieringsmodell utan att skriva kod kan du läsa den webbläsarbaserade vägledningen i stället.

Referensdokumentation | Biblioteks källkod (träning)(förutsägelse) | Paket (NuGet) (träning)(förutsägelse) | Exempel

Förutsättningar

Skapa miljövariabler

I det här exemplet skriver du dina autentiseringsuppgifter till miljövariabler på den lokala dator som kör programmet.

Gå till Azure-portalen. Om de Custom Vision-resurser som du skapade i avsnittet Förutsättningar har distribuerats väljer du knappen Gå till resurs under Nästa steg. Du hittar dina nycklar och slutpunkter på resursernas nyckel- och slutpunktssidor under resurshantering. Du måste hämta nycklarna för både dina tränings- och förutsägelseresurser, tillsammans med API-slutpunkterna.

Du hittar resurs-ID:t för förutsägelse på fliken Egenskaper för förutsägelseresursen i Azure-portalen, som visas som Resurs-ID.

Dricks

Du använder https://www.customvision.ai/ också för att hämta dessa värden. När du har loggat in väljer du ikonen Inställningar längst upp till höger. På sidorna Inställning kan du visa alla nycklar, resurs-ID och slutpunkter.

Varning

Inkludera inte nyckeln direkt i koden och publicera den aldrig offentligt. Mer autentiseringsalternativ som Azure Key Vault finns i säkerhetsartikeln för Azure AI-tjänster.

Om du vill ange miljövariablerna öppnar du ett konsolfönster och följer anvisningarna för operativsystemet och utvecklingsmiljön.

  1. Om du vill ange VISION_TRAINING KEY miljövariabeln ersätter du your-training-key med en av nycklarna för träningsresursen.
  2. Om du vill ange VISION_TRAINING_ENDPOINT miljövariabeln ersätter your-training-endpoint du med slutpunkten för träningsresursen.
  3. Om du vill ange VISION_PREDICTION_KEY miljövariabeln ersätter du your-prediction-key med en av nycklarna för din förutsägelseresurs.
  4. Om du vill ange VISION_PREDICTION_ENDPOINT miljövariabeln ersätter du your-prediction-endpoint med slutpunkten för förutsägelseresursen.
  5. Om du vill ange VISION_PREDICTION_RESOURCE_ID miljövariabeln ersätter du your-resource-id med resurs-ID:t för din förutsägelseresurs.
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

När du har lagt till miljövariablerna kan du behöva starta om alla program som körs som läser miljövariablerna, inklusive konsolfönstret.

Konfigurera

Skapa ett nytt C#-program

Skapa ett nytt .NET Core-program med Hjälp av Visual Studio.

Installera klientbiblioteket

När du har skapat ett nytt projekt installerar du klientbiblioteket genom att högerklicka på projektlösningen i Solution Explorer och välja Hantera NuGet-paket. I pakethanteraren som öppnas väljer du Bläddra, markerar Inkludera förhandsversion och söker Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training efter och Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Välj den senaste versionen och sedan Installera.

Dricks

Vill du visa hela snabbstartskodfilen på en gång? Du hittar den på GitHub, som innehåller kodexemplen i den här snabbstarten.

Öppna filen program.cs från projektkatalogen och lägg till följande using direktiv:

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;

I programmets Main-metod skapar du variabler som hämtar resursens nycklar och slutpunkt från miljövariabler. Du deklarerar också några grundläggande objekt som ska användas senare.

    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";

I programmets Main-metod lägger du till anrop för de metoder som används i den här snabbstarten. Du kommer att implementera dessa senare.

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);

Autentisera klienten

I en ny metod instansierar du tränings- och förutsägelseklienter med hjälp av slutpunkten och nycklarna.

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;
}

Skapa ett nytt Custom Vision-projekt

Nästa metod skapar ett objektidentifieringsprojekt. Det skapade projektet visas på Custom Vision-webbplatsen. Se metoden CreateProject för att ange andra alternativ när du skapar projektet (förklaras i webbportalguiden skapa en detektor).

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;
}

Lägga till taggar till projektet

Den här metoden definierar de taggar som du ska träna modellen på.

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");
}

Ladda upp och tagga bilder

Ladda först ned exempelbilderna för det här projektet. Spara innehållet i exempelmappen Bilder på din lokala enhet.

När du taggar bilder i objektidentifieringsprojekt måste du bestämma region för varje taggat objekt med hjälp av normaliserade koordinater. Följande kod associerar var och en av exempelbilderna med dess taggade region.

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 } }
    };

Kommentar

För dina egna projekt kan du använda webbgränssnittet på Custom Vision-webbplatsen om du inte har något verktyg för att klicka och dra för att markera koordinaterna för regioner. I det här exemplet har koordinaterna redan angetts.

Den här mappningen av associationer används sedan för att ladda upp varje exempelbild med dess regionkoordinater. Du kan ladda upp upp till 64 bilder i en enda batch. Du kan behöva ändra värdet imagePath så att det pekar på rätt mappplatser.

    // 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));
}

Nu har du laddat upp alla exempelbilder och taggat var och en (förgrening eller sax) med en associerad pixelrektangel.

Träna projektet

Den här metoden skapar den första tränings-iterationen i projektet. Den frågar tjänsten tills träningen har slutförts.

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);
    }
}

Dricks

Träna med markerade taggar

Du kan också träna på endast en delmängd av dina tillämpade taggar. Du kanske vill göra detta om du inte har tillämpat tillräckligt många av vissa taggar ännu, men du har tillräckligt med andra. I TrainProject-anropet använder du parametern trainingParameters. Skapa en TrainingParameters och ange egenskapen SelectedTags till en lista med ID:er för de taggar som du vill använda. Modellen tränar för att endast identifiera taggarna i listan.

Publicera den aktuella iterationen

Den här metoden gör den aktuella iterationen av modellen tillgänglig för frågor. Du kan använda modellnamnet som referens för att skicka förutsägelsebegäranden. Du måste ange ett eget värde för predictionResourceId. Du hittar resurs-ID:t för förutsägelse på resursens egenskapsflik i Azure-portalen, som visas som resurs-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");
}

Testa förutsägelseslutpunkten

Den här metoden läser in testbilden, frågar modellslutpunkten och matar ut förutsägelsedata till konsolen.

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();
}

Kör appen

Kör programmet genom att klicka på felsökningsknappen överst i IDE-fönstret.

När programmet körs ska det öppna ett konsolfönster och skriva följande utdata:

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 ]

Du kan sedan kontrollera att testbilden (finns i Images/Test/) har taggats på rätt sätt och att regionidentifieringen är rätt. Nu kan du avsluta programmet genom att trycka på valfri tangent.

Rensa resurser

Om du vill implementera ett eget objektidentifieringsprojekt (eller prova ett projekt för bildklassificering istället) kan du vilja ta bort projektet för gaffel-/saxidentifiering (fork/scissors) från det här exemplet. En kostnadsfri prenumeration tillåter två Custom Vision-projekt.

Custom Vision-webbplatsen går du till Projects (Projekt) och väljer papperskorgen under My New Project (Mitt nya projekt).

Screenshot of a panel labeled My New Project with a trash can icon.

Nästa steg

Nu har du gjort varje steg i objektidentifieringsprocessen i koden. Det här exemplet kör en enda tränings iteration, men ofta måste du träna och testa din modell flera gånger för att göra den mer exakt. Följande guide behandlar bildklassificering, men principerna liknar dem som gäller för objektidentifiering.

Den här guiden innehåller instruktioner och exempelkod som hjälper dig att komma igång med hjälp av Custom Vision-klientbiblioteket för Go för att skapa en objektidentifieringsmodell. Du skapar ett projekt, lägger till taggar, tränar projektet och använder projektets förutsägelseslutpunkts-URL för att testa det programmatiskt. Använd det här exemplet som en mall för att skapa en egen app för bildigenkänning.

Kommentar

Om du vill skapa och träna en objektidentifieringsmodell utan att skriva kod kan du läsa den webbläsarbaserade vägledningen i stället.

Använd Custom Vision-klientbiblioteket för Gå till:

  • Skapa ett nytt Custom Vision-projekt
  • Lägga till taggar till projektet
  • Ladda upp och tagga bilder
  • Träna projektet
  • Publicera den aktuella iterationen
  • Testa förutsägelseslutpunkten

Referensdokumentation (träning)(förutsägelse)

Förutsättningar

  • Azure-prenumeration – Skapa en kostnadsfritt
  • Go 1.8+
  • När du har din Azure-prenumeration skapar du en Custom Vision-resurs i Azure-portalen för att skapa en tränings- och förutsägelseresurs.
    • Du kan använda den kostnadsfria prisnivån (F0) för att prova tjänsten och uppgradera senare till en betald nivå för produktion.

Skapa miljövariabler

I det här exemplet skriver du dina autentiseringsuppgifter till miljövariabler på den lokala dator som kör programmet.

Gå till Azure-portalen. Om de Custom Vision-resurser som du skapade i avsnittet Förutsättningar har distribuerats väljer du knappen Gå till resurs under Nästa steg. Du hittar dina nycklar och slutpunkter på resursernas nyckel- och slutpunktssidor under resurshantering. Du måste hämta nycklarna för både dina tränings- och förutsägelseresurser, tillsammans med API-slutpunkterna.

Du hittar resurs-ID:t för förutsägelse på fliken Egenskaper för förutsägelseresursen i Azure-portalen, som visas som Resurs-ID.

Dricks

Du använder https://www.customvision.ai/ också för att hämta dessa värden. När du har loggat in väljer du ikonen Inställningar längst upp till höger. På sidorna Inställning kan du visa alla nycklar, resurs-ID och slutpunkter.

Varning

Inkludera inte nyckeln direkt i koden och publicera den aldrig offentligt. Mer autentiseringsalternativ som Azure Key Vault finns i säkerhetsartikeln för Azure AI-tjänster.

Om du vill ange miljövariablerna öppnar du ett konsolfönster och följer anvisningarna för operativsystemet och utvecklingsmiljön.

  1. Om du vill ange VISION_TRAINING KEY miljövariabeln ersätter du your-training-key med en av nycklarna för träningsresursen.
  2. Om du vill ange VISION_TRAINING_ENDPOINT miljövariabeln ersätter your-training-endpoint du med slutpunkten för träningsresursen.
  3. Om du vill ange VISION_PREDICTION_KEY miljövariabeln ersätter du your-prediction-key med en av nycklarna för din förutsägelseresurs.
  4. Om du vill ange VISION_PREDICTION_ENDPOINT miljövariabeln ersätter du your-prediction-endpoint med slutpunkten för förutsägelseresursen.
  5. Om du vill ange VISION_PREDICTION_RESOURCE_ID miljövariabeln ersätter du your-resource-id med resurs-ID:t för din förutsägelseresurs.
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

När du har lagt till miljövariablerna kan du behöva starta om alla program som körs som läser miljövariablerna, inklusive konsolfönstret.

Konfigurera

Installera Custom Vision-klientbiblioteket

Om du vill skriva en bildanalysapp med Custom Vision for Go behöver du Custom Vision Service-klientbiblioteket. Kör följande kommando i PowerShell:

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

eller om du använder dep, inom din lagringsplatskörning:

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

Hämta exempelbilderna

I det här exemplet används avbildningarna från Azure AI-tjänsternas Python SDK-exempellagringsplats på GitHub. Klona eller ladda ned den här lagringsplatsen till din utvecklingsmiljö. Kom ihåg dess mappplats för ett senare steg.

Skapa Custom Vision-projektet

Skapa en ny fil med namnet sample.go i önskad projektkatalog och öppna den i önskad kodredigerare.

Lägg till följande kod i skriptet för att skapa ett nytt Custom Vision Service-projekt.

Se metoden CreateProject för att ange andra alternativ när du skapar projektet (förklaras i webbportalguiden skapa en detektor).

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, "")

Skapa taggar i projektet

Om du vill skapa klassificeringstaggar i projektet lägger du till följande kod i slutet av 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))

Ladda upp och tagga bilder

När du taggar bilder i objektidentifieringsprojekt måste du bestämma region för varje taggat objekt med hjälp av normaliserade koordinater.

Kommentar

Om du inte har något verktyg för att klicka och dra för att markera koordinaterna för regioner kan du använda webbgränssnittet på Customvision.ai. I det här exemplet har koordinaterna redan angetts.

För att lägga till bilder, taggar och regioner i projektet lägger du till följande kod efter att taggarna har skapats. Observera att regionerna i den här självstudien är hårdkodade infogade. Regionerna specificerar avgränsningsfältet i normaliserade koordinater, och koordinaterna anges i följande ordning: vänster, överst, bredd, höjd.

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 },
}

Använd sedan den här associationskartan för att ladda upp varje exempelbild med dess regionkoordinater (du kan ladda upp upp till 64 bilder i en enda batch). Lägg till följande kod:

Kommentar

Du måste ändra sökvägen till avbildningarna baserat på var du laddade ned Azure AI-tjänsterna Go SDK Samples-projektet tidigare.

// 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.")
}     

Träna och publicera projektet

Den här koden skapar den första iterationen av förutsägelsemodellen och publicerar sedan iterationen till förutsägelseslutpunkten. Namnet på den publicerade iterationen kan användas för att skicka förutsägelsebegäranden. En iteration är inte tillgänglig i förutsägelseslutpunkten förrän den har publicerats.

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))

Använda en förutsägelseslutpunkt

Om du vill skicka en bild till slutpunkten för förutsägelse och hämta förutsägelsen, lägger du till följande kod i slutet av filen:

    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("")
    }
}

Kör appen

Kör sample.go.

go run sample.go

Programmets utdata bör visas i konsolen. Du kan sedan kontrollera att testbilden (som finns i samples/vision/images/Test) har taggats på rätt sätt och att regionidentifieringen är korrekt.

Rensa resurser

Om du vill implementera ett eget objektidentifieringsprojekt (eller prova ett projekt för bildklassificering istället) kan du vilja ta bort projektet för gaffel-/saxidentifiering (fork/scissors) från det här exemplet. En kostnadsfri prenumeration tillåter två Custom Vision-projekt.

Custom Vision-webbplatsen går du till Projects (Projekt) och väljer papperskorgen under My New Project (Mitt nya projekt).

Screenshot of a panel labeled My New Project with a trash can icon.

Nästa steg

Nu har du gjort varje steg i objektidentifieringsprocessen i koden. Det här exemplet kör en enda tränings iteration, men ofta måste du träna och testa din modell flera gånger för att göra den mer exakt. Följande guide behandlar bildklassificering, men principerna liknar dem som gäller för objektidentifiering.

Kom igång med Custom Vision-klientbiblioteket för Java för att skapa en objektidentifieringsmodell. Följ de här stegen för att installera paketet och prova exempelkoden för grundläggande uppgifter. Använd det här exemplet som en mall för att skapa en egen app för bildigenkänning.

Kommentar

Om du vill skapa och träna en objektidentifieringsmodell utan att skriva kod kan du läsa den webbläsarbaserade vägledningen i stället.

Använd Custom Vision-klientbiblioteket för Java för att:

  • Skapa ett nytt Custom Vision-projekt
  • Lägga till taggar till projektet
  • Ladda upp och tagga bilder
  • Träna projektet
  • Publicera den aktuella iterationen
  • Testa förutsägelseslutpunkten

Referensdokumentation | Biblioteks källkod (träning)(förutsägelse)| Artefakt (Maven) (träning)(förutsägelse) | Exempel

Förutsättningar

Skapa miljövariabler

I det här exemplet skriver du dina autentiseringsuppgifter till miljövariabler på den lokala dator som kör programmet.

Gå till Azure-portalen. Om de Custom Vision-resurser som du skapade i avsnittet Förutsättningar har distribuerats väljer du knappen Gå till resurs under Nästa steg. Du hittar dina nycklar och slutpunkter på resursernas nyckel- och slutpunktssidor under resurshantering. Du måste hämta nycklarna för både dina tränings- och förutsägelseresurser, tillsammans med API-slutpunkterna.

Du hittar resurs-ID:t för förutsägelse på fliken Egenskaper för förutsägelseresursen i Azure-portalen, som visas som Resurs-ID.

Dricks

Du använder https://www.customvision.ai/ också för att hämta dessa värden. När du har loggat in väljer du ikonen Inställningar längst upp till höger. På sidorna Inställning kan du visa alla nycklar, resurs-ID och slutpunkter.

Varning

Inkludera inte nyckeln direkt i koden och publicera den aldrig offentligt. Mer autentiseringsalternativ som Azure Key Vault finns i säkerhetsartikeln för Azure AI-tjänster.

Om du vill ange miljövariablerna öppnar du ett konsolfönster och följer anvisningarna för operativsystemet och utvecklingsmiljön.

  1. Om du vill ange VISION_TRAINING KEY miljövariabeln ersätter du your-training-key med en av nycklarna för träningsresursen.
  2. Om du vill ange VISION_TRAINING_ENDPOINT miljövariabeln ersätter your-training-endpoint du med slutpunkten för träningsresursen.
  3. Om du vill ange VISION_PREDICTION_KEY miljövariabeln ersätter du your-prediction-key med en av nycklarna för din förutsägelseresurs.
  4. Om du vill ange VISION_PREDICTION_ENDPOINT miljövariabeln ersätter du your-prediction-endpoint med slutpunkten för förutsägelseresursen.
  5. Om du vill ange VISION_PREDICTION_RESOURCE_ID miljövariabeln ersätter du your-resource-id med resurs-ID:t för din förutsägelseresurs.
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

När du har lagt till miljövariablerna kan du behöva starta om alla program som körs som läser miljövariablerna, inklusive konsolfönstret.

Konfigurera

Skapa ett nytt Gradle-projekt

Skapa en ny katalog för din app i ett konsolfönster (till exempel cmd, PowerShell eller bash) och navigera till den.

mkdir myapp && cd myapp

Kör kommandot från arbetskatalogen gradle init . Det här kommandot skapar viktiga byggfiler för Gradle, inklusive build.gradle.kts, som används vid körning för att skapa och konfigurera ditt program.

gradle init --type basic

Välj en DSL när du uppmanas till det och välj Kotlin.

Installera klientbiblioteket

Leta upp build.gradle.kts och öppna det med önskad IDE eller textredigerare . Kopiera sedan i följande byggkonfiguration. Den här konfigurationen definierar projektet som ett Java-program vars startpunkt är klassen CustomVisionQuickstart. Den importerar Custom Vision-biblioteken.

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")
}

Skapa en Java-fil

Från arbetskatalogen kör du följande kommando för att skapa en projektkällmapp:

mkdir -p src/main/java

Gå till den nya mappen och skapa en fil med namnet CustomVisionQuickstart.java. Öppna den i önskad redigerare eller IDE och lägg till följande import instruktioner:

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;

Dricks

Vill du visa hela snabbstartskodfilen på en gång? Du hittar den på GitHub, som innehåller kodexemplen i den här snabbstarten.

I programmets CustomVisionQuickstart-klass skapar du variabler som hämtar resursens nycklar och slutpunkt från miljövariabler.

// 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");

I programmets huvudmetod lägger du till anrop för de metoder som används i den här snabbstarten. Du definierar dessa senare.

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

Objektmodell

Följande klasser och gränssnitt hanterar några av de viktigaste funktionerna i Custom Vision Java-klientbiblioteket.

Name beskrivning
CustomVisionTrainingClient Den här klassen hanterar skapande, träning och publicering av dina modeller.
CustomVisionPredictionClient Den här klassen hanterar frågor till dina modeller om förutsägelser för objektidentifiering.
ImagePrediction Den här klassen definierar en förutsägelse av ett enskilt objekt på en enda bild. Den innehåller egenskaper för objekt-ID och namn, objektets avgränsningsruta och en konfidenspoäng.

Kodexempel

De här kodfragmenten visar hur du utför följande uppgifter med Custom Vision-klientbiblioteket för Java:

Autentisera klienten

I huvudmetoden instansierar du tränings- och förutsägelseklienter med hjälp av slutpunkten och nycklarna.

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

Skapa ett nytt Custom Vision-projekt

Nästa metod skapar ett objektidentifieringsprojekt. Det skapade projektet visas på den Custom Vision-webbplats som du besökte tidigare. Se överlagringar av CreateProject-metoden för att ange andra alternativ när du skapar projektet (förklaras i webbportalguiden Skapa en detektor ).

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;
}

Lägga till taggar till projektet

Den här metoden definierar de taggar som du ska träna modellen på.

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();
}

Ladda upp och tagga bilder

Ladda först ned exempelbilderna för det här projektet. Spara innehållet i exempelmappen Bilder på din lokala enhet.

Kommentar

Behöver du en bredare uppsättning bilder för att slutföra träningen? Med Trove, ett Microsoft Garage-projekt, kan du samla in och köpa uppsättningar av bilder i utbildningssyfte. När du har samlat in dina bilder kan du ladda ned dem och sedan importera dem till ditt Custom Vision-projekt på vanligt sätt. Besök Trove-sidan om du vill veta mer.

När du taggar bilder i objektidentifieringsprojekt måste du bestämma region för varje taggat objekt med hjälp av normaliserade koordinater. Följande kod associerar var och en av exempelbilderna med dess taggade region.

Kommentar

Om du inte har något verktyg för att klicka och dra för att markera koordinaterna för regioner kan du använda webbgränssnittet på Customvision.ai. I det här exemplet har koordinaterna redan angetts.

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 });

Nästa kodblock lägger till bilderna i projektet. Du måste ändra argumenten för anropen GetImage så att de pekar på platserna för de förgrenings - och saxmappar som du laddade ned.

    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));
    }
}

Det tidigare kodfragmentet använder två hjälpfunktioner som hämtar bilderna som resursströmmar och laddar upp dem till tjänsten (du kan ladda upp upp till 64 bilder i en enda batch). Definiera dessa metoder.

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;
}

Träna projektet

Den här metoden skapar den första tränings-iterationen i projektet. Den frågar tjänsten tills träningen har slutförts.

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());
}

Publicera den aktuella iterationen

Den här metoden gör den aktuella iterationen av modellen tillgänglig för frågor. Du kan använda modellnamnet som referens för att skicka förutsägelsebegäranden. Du måste ange ett eget värde för predictionResourceId. Du hittar resurs-ID:t för förutsägelse på resursens egenskapsflik i Azure-portalen, som visas som resurs-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;
}

Testa förutsägelseslutpunkten

Den här metoden läser in testbilden, frågar modellslutpunkten och matar ut förutsägelsedata till konsolen.

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()));
    }
}

Kör appen

Du kan skapa appen med:

gradle build

Kör programmet med gradle run kommandot :

gradle run

Rensa resurser

Om du vill rensa och ta bort en Azure AI-tjänstprenumeration kan du ta bort resursen eller resursgruppen. Om du tar bort resursgruppen tas även alla andra resurser som är associerade med den bort.

Om du vill implementera ett eget objektidentifieringsprojekt (eller prova ett projekt för bildklassificering istället) kan du vilja ta bort projektet för gaffel-/saxidentifiering (fork/scissors) från det här exemplet. En kostnadsfri prenumeration tillåter två Custom Vision-projekt.

Custom Vision-webbplatsen går du till Projects (Projekt) och väljer papperskorgen under My New Project (Mitt nya projekt).

Screenshot of a panel labeled My New Project with a trash can icon.

Nästa steg

Nu har du gjort varje steg i objektidentifieringsprocessen i koden. Det här exemplet kör en enda tränings iteration, men ofta måste du träna och testa din modell flera gånger för att göra den mer exakt. Följande guide behandlar bildklassificering, men principerna liknar dem som gäller för objektidentifiering.

Den här guiden innehåller instruktioner och exempelkod som hjälper dig att komma igång med custom vision-klientbiblioteket för Node.js för att skapa en objektidentifieringsmodell. Du skapar ett projekt, lägger till taggar, tränar projektet och använder projektets förutsägelseslutpunkts-URL för att testa det programmatiskt. Använd det här exemplet som en mall för att skapa en egen app för bildigenkänning.

Kommentar

Om du vill skapa och träna en objektidentifieringsmodell utan att skriva kod kan du läsa den webbläsarbaserade vägledningen i stället.

Använd Custom Vision-klientbiblioteket för .NET för att:

  • Skapa ett nytt Custom Vision-projekt
  • Lägga till taggar till projektet
  • Ladda upp och tagga bilder
  • Träna projektet
  • Publicera den aktuella iterationen
  • Testa förutsägelseslutpunkten

Referensdokumentation (träning)(förutsägelse) | Biblioteks källkod (träning)(förutsägelse) | Paket (npm) (träning)(förutsägelse) | Exempel

Förutsättningar

  • Azure-prenumeration – Skapa en kostnadsfritt
  • Den aktuella versionen av Node.js
  • När du har din Azure-prenumeration skapar du en Custom Vision-resurs i Azure-portalen för att skapa en tränings- och förutsägelseresurs.
    • Du kan använda den kostnadsfria prisnivån (F0) för att prova tjänsten och uppgradera senare till en betald nivå för produktion.

Skapa miljövariabler

I det här exemplet skriver du dina autentiseringsuppgifter till miljövariabler på den lokala dator som kör programmet.

Gå till Azure-portalen. Om de Custom Vision-resurser som du skapade i avsnittet Förutsättningar har distribuerats väljer du knappen Gå till resurs under Nästa steg. Du hittar dina nycklar och slutpunkter på resursernas nyckel- och slutpunktssidor under resurshantering. Du måste hämta nycklarna för både dina tränings- och förutsägelseresurser, tillsammans med API-slutpunkterna.

Du hittar resurs-ID:t för förutsägelse på fliken Egenskaper för förutsägelseresursen i Azure-portalen, som visas som Resurs-ID.

Dricks

Du använder https://www.customvision.ai/ också för att hämta dessa värden. När du har loggat in väljer du ikonen Inställningar längst upp till höger. På sidorna Inställning kan du visa alla nycklar, resurs-ID och slutpunkter.

Varning

Inkludera inte nyckeln direkt i koden och publicera den aldrig offentligt. Mer autentiseringsalternativ som Azure Key Vault finns i säkerhetsartikeln för Azure AI-tjänster.

Om du vill ange miljövariablerna öppnar du ett konsolfönster och följer anvisningarna för operativsystemet och utvecklingsmiljön.

  1. Om du vill ange VISION_TRAINING KEY miljövariabeln ersätter du your-training-key med en av nycklarna för träningsresursen.
  2. Om du vill ange VISION_TRAINING_ENDPOINT miljövariabeln ersätter your-training-endpoint du med slutpunkten för träningsresursen.
  3. Om du vill ange VISION_PREDICTION_KEY miljövariabeln ersätter du your-prediction-key med en av nycklarna för din förutsägelseresurs.
  4. Om du vill ange VISION_PREDICTION_ENDPOINT miljövariabeln ersätter du your-prediction-endpoint med slutpunkten för förutsägelseresursen.
  5. Om du vill ange VISION_PREDICTION_RESOURCE_ID miljövariabeln ersätter du your-resource-id med resurs-ID:t för din förutsägelseresurs.
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

När du har lagt till miljövariablerna kan du behöva starta om alla program som körs som läser miljövariablerna, inklusive konsolfönstret.

Konfigurera

Skapa ett nytt Node.js-program

Skapa en ny katalog för din app i ett konsolfönster (till exempel cmd, PowerShell eller bash) och navigera till den.

mkdir myapp && cd myapp

Kör kommandot npm init för att skapa ett nodprogram med en package.json-fil.

npm init

Installera klientbiblioteket

Om du vill skriva en bildanalysapp med Custom Vision för Node.js behöver du Custom Vision NPM-paketen. Installera dem genom att köra följande kommando i PowerShell:

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

Programmets package.json-fil kommer att uppdateras med beroenden.

Skapa en fil med namnet index.js och importera följande bibliotek:

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");

Dricks

Vill du visa hela snabbstartskodfilen på en gång? Du hittar den på GitHub, som innehåller kodexemplen i den här snabbstarten.

Skapa variabler för resursens Azure-slutpunkt och -nycklar.

// 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"];

Lägg också till fält för projektnamnet och en timeout-parameter för asynkrona anrop.

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

Objektmodell

Name beskrivning
TrainingAPIClient Den här klassen hanterar skapande, träning och publicering av dina modeller.
PredictionAPIClient Den här klassen hanterar frågor till dina modeller om förutsägelser för objektidentifiering.
Prediktion Det här gränssnittet definierar en enda förutsägelse på en enda bild. Den innehåller egenskaper för objekt-ID och namn samt en konfidenspoäng.

Kodexempel

De här kodfragmenten visar hur du utför följande uppgifter med Custom Vision-klientbiblioteket för JavaScript:

Autentisera klienten

Instansiera klientobjekt med slutpunkten och nyckeln. Skapa ett ApiKeyCredentials-objekt med din nyckel och använd det med slutpunkten för att skapa ett TrainingAPIClient - och PredictionAPIClient-objekt .

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);

Lägg till hjälpfunktion

Lägg till följande funktion för att göra flera asynkrona anrop. Du kommer att använda detta senare.

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);

Skapa ett nytt Custom Vision-projekt

Starta en ny funktion för att innehålla alla dina Custom Vision-funktionsanrop. Lägg till följande kod för att skapa ett nytt Custom Vision Service-projekt.

(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 });

Lägga till taggar till projektet

Om du vill skapa klassificeringstaggar i projektet lägger du till följande kod i funktionen:

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

Ladda upp och tagga bilder

Ladda först ned exempelbilderna för det här projektet. Spara innehållet i exempelmappen Bilder på din lokala enhet.

Infoga följande kod efter att taggen har skapats för att lägga till exempelbilder i projektet. Den här koden laddar upp varje bild med dess motsvarande tagg. När du taggar bilder i objektidentifieringsprojekt måste du bestämma region för varje taggat objekt med hjälp av normaliserade koordinater. I den här självstudien hårdkodas regionerna internt med koden. Regionerna specificerar avgränsningsfältet i normaliserade koordinater, och koordinaterna anges i följande ordning: vänster, överst, bredd, höjd. Du kan ladda upp upp till 64 bilder i en enda 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);

Viktigt!

Du måste ändra sökvägen till bilderna (sampleDataRoot) baserat på var du laddade ned Azure AI-tjänsternas Python SDK-exempel-lagringsplats.

Kommentar

Om du inte har något verktyg för att klicka och dra för att markera koordinaterna för regioner kan du använda webbgränssnittet på Customvision.ai. I det här exemplet har koordinaterna redan angetts.

Träna projektet

Den här koden skapar den första iterationen av förutsägelsemodellen.

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);

Publicera den aktuella iterationen

Den här koden publicerar den tränade iterationen till förutsägelseslutpunkten. Namnet på den publicerade iterationen kan användas för att skicka förutsägelsebegäranden. En iteration är inte tillgänglig i förutsägelseslutpunkten förrän den har publicerats.

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

Testa förutsägelseslutpunkten

Om du vill skicka en bild till förutsägelseslutpunkten och hämta förutsägelsen lägger du till följande kod i funktionen.

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}`);
});

Stäng sedan din Custom Vision-funktion och anropa den.

})()

Kör appen

Kör programmet med kommandot node på din snabbstartsfil.

node index.js

Programmets utdata bör visas i konsolen. Du kan sedan kontrollera att testbilden (som finns i <sampleDataRoot>/Test/) har taggats korrekt och att identifieringsregionen är korrekt. Du kan också gå tillbaka till Custom Vision-webbplatsen och se det aktuella tillståndet för det nyskapade projektet.

Rensa resurser

Om du vill implementera ett eget objektidentifieringsprojekt (eller prova ett projekt för bildklassificering istället) kan du vilja ta bort projektet för gaffel-/saxidentifiering (fork/scissors) från det här exemplet. En kostnadsfri prenumeration tillåter två Custom Vision-projekt.

Custom Vision-webbplatsen går du till Projects (Projekt) och väljer papperskorgen under My New Project (Mitt nya projekt).

Screenshot of a panel labeled My New Project with a trash can icon.

Nästa steg

Nu har du gjort varje steg i objektidentifieringsprocessen i koden. Det här exemplet kör en enda tränings iteration, men ofta måste du träna och testa din modell flera gånger för att göra den mer exakt. Följande guide behandlar bildklassificering, men principerna liknar dem som gäller för objektidentifiering.

Kom igång med Custom Vision-klientbiblioteket för Python. Följ de här stegen för att installera paketet och prova exempelkoden för att skapa en objektidentifieringsmodell. Du skapar ett projekt, lägger till taggar, tränar projektet och använder projektets förutsägelseslutpunkts-URL för att testa det programmatiskt. Använd det här exemplet som en mall för att skapa en egen app för bildigenkänning.

Kommentar

Om du vill skapa och träna en objektidentifieringsmodell utan att skriva kod kan du läsa den webbläsarbaserade vägledningen i stället.

Använd Custom Vision-klientbiblioteket för Python för att:

  • Skapa ett nytt Custom Vision-projekt
  • Lägga till taggar till projektet
  • Ladda upp och tagga bilder
  • Träna projektet
  • Publicera den aktuella iterationen
  • Testa förutsägelseslutpunkten

Exempel på källkodspaket (PyPI) | för referensdokumentation | |

Förutsättningar

  • Azure-prenumeration – Skapa en kostnadsfritt
  • Python 3.x
    • Python-installationen bör innehålla pip. Du kan kontrollera om du har pip installerat genom att köra pip --version på kommandoraden. Hämta pip genom att installera den senaste versionen av Python.
  • När du har din Azure-prenumeration skapar du en Custom Vision-resurs i Azure-portalen för att skapa en tränings- och förutsägelseresurs.
    • Du kan använda den kostnadsfria prisnivån (F0) för att prova tjänsten och uppgradera senare till en betald nivå för produktion.

Skapa miljövariabler

I det här exemplet skriver du dina autentiseringsuppgifter till miljövariabler på den lokala dator som kör programmet.

Gå till Azure-portalen. Om de Custom Vision-resurser som du skapade i avsnittet Förutsättningar har distribuerats väljer du knappen Gå till resurs under Nästa steg. Du hittar dina nycklar och slutpunkter på resursernas nyckel- och slutpunktssidor under resurshantering. Du måste hämta nycklarna för både dina tränings- och förutsägelseresurser, tillsammans med API-slutpunkterna.

Du hittar resurs-ID:t för förutsägelse på fliken Egenskaper för förutsägelseresursen i Azure-portalen, som visas som Resurs-ID.

Dricks

Du använder https://www.customvision.ai/ också för att hämta dessa värden. När du har loggat in väljer du ikonen Inställningar längst upp till höger. På sidorna Inställning kan du visa alla nycklar, resurs-ID och slutpunkter.

Varning

Inkludera inte nyckeln direkt i koden och publicera den aldrig offentligt. Mer autentiseringsalternativ som Azure Key Vault finns i säkerhetsartikeln för Azure AI-tjänster.

Om du vill ange miljövariablerna öppnar du ett konsolfönster och följer anvisningarna för operativsystemet och utvecklingsmiljön.

  1. Om du vill ange VISION_TRAINING KEY miljövariabeln ersätter du your-training-key med en av nycklarna för träningsresursen.
  2. Om du vill ange VISION_TRAINING_ENDPOINT miljövariabeln ersätter your-training-endpoint du med slutpunkten för träningsresursen.
  3. Om du vill ange VISION_PREDICTION_KEY miljövariabeln ersätter du your-prediction-key med en av nycklarna för din förutsägelseresurs.
  4. Om du vill ange VISION_PREDICTION_ENDPOINT miljövariabeln ersätter du your-prediction-endpoint med slutpunkten för förutsägelseresursen.
  5. Om du vill ange VISION_PREDICTION_RESOURCE_ID miljövariabeln ersätter du your-resource-id med resurs-ID:t för din förutsägelseresurs.
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

När du har lagt till miljövariablerna kan du behöva starta om alla program som körs som läser miljövariablerna, inklusive konsolfönstret.

Konfigurera

Installera klientbiblioteket

Om du vill skriva en bildanalysapp med Custom Vision för Python behöver du Custom Vision-klientbiblioteket. När du har installerat Python kör du följande kommando i PowerShell eller ett konsolfönster:

pip install azure-cognitiveservices-vision-customvision

Skapa ett nytt Python-program

Skapa en ny Python-fil och importera följande bibliotek.

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

Dricks

Vill du visa hela snabbstartskodfilen på en gång? Du hittar den på GitHub, som innehåller kodexemplen i den här snabbstarten.

Skapa variabler för resursens Azure-slutpunkt och -nycklar.

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

Objektmodell

Name beskrivning
CustomVisionTrainingClient Den här klassen hanterar skapande, träning och publicering av dina modeller.
CustomVisionPredictionClient Den här klassen hanterar frågor till dina modeller om förutsägelser för objektidentifiering.
ImagePrediction Den här klassen definierar en förutsägelse av ett enskilt objekt på en enda bild. Den innehåller egenskaper för objekt-ID och namn, objektets avgränsningsruta och en konfidenspoäng.

Kodexempel

De här kodfragmenten visar hur du gör följande med Custom Vision-klientbiblioteket för Python:

Autentisera klienten

Instansiera en tränings- och förutsägelseklient med slutpunkten och nycklarna. Skapa ApiKeyServiceClientCredentials-objekt med dina nycklar och använd dem med slutpunkten för att skapa ett CustomVisionTrainingClient - och CustomVisionPredictionClient-objekt .

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

Skapa ett nytt Custom Vision-projekt

Lägg till följande kod i skriptet för att skapa ett nytt Custom Vision Service-projekt.

Se create_project-metoden för att ange andra alternativ när du skapar projektet (förklaras i webbportalguiden skapa en detektor).

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)

Lägga till taggar till projektet

Om du vill skapa objekttaggar i projektet lägger du till följande kod:

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

Ladda upp och tagga bilder

Ladda först ned exempelbilderna för det här projektet. Spara innehållet i exempelmappen Bilder på din lokala enhet.

När du taggar bilder i objektidentifieringsprojekt måste du bestämma region för varje taggat objekt med hjälp av normaliserade koordinater. Följande kod associerar var och en av exempelbilderna med dess taggade region. Regionerna specificerar avgränsningsfältet i normaliserade koordinater, och koordinaterna anges i följande ordning: vänster, överst, bredd, höjd.

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 ]
}

Kommentar

Om du inte har något verktyg för att klicka och dra för att markera koordinaterna för regioner kan du använda webbgränssnittet på Customvision.ai. I det här exemplet har koordinaterna redan angetts.

Använd sedan den här associationskartan för att ladda upp varje exempelbild med dess regionkoordinater (du kan ladda upp upp till 64 bilder i en enda batch). Lägg till följande kod:

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)

Kommentar

Du måste ändra sökvägen till bilderna baserat på var du laddade ned Azure AI-tjänsternas Python SDK-exempel-lagringsplats tidigare.

Träna projektet

Den här koden skapar den första iterationen av förutsägelsemodellen.

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)

Dricks

Träna med markerade taggar

Du kan också träna på endast en delmängd av dina tillämpade taggar. Du kanske vill göra detta om du inte har tillämpat tillräckligt många av vissa taggar ännu, men du har tillräckligt med andra. I anropet train_project anger du den valfria parametern selected_tags till en lista över ID-strängarna för de taggar som du vill använda. Modellen tränar för att endast identifiera taggarna i listan.

Publicera den aktuella iterationen

En iteration är inte tillgänglig i förutsägelseslutpunkten förrän den har publicerats. Följande kod gör den aktuella iterationen av modellen tillgänglig för frågor.

# 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!")

Testa förutsägelseslutpunkten

Om du vill skicka en bild till slutpunkten för förutsägelse och hämta förutsägelsen, lägger du till följande kod i slutet av filen:

# 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))

Kör appen

Kör CustomVisionQuickstart.py.

python CustomVisionQuickstart.py

Programmets utdata bör visas i konsolen. Du kan sedan kontrollera att testbilden (som finns i <base_image_location>/images/Test) har taggats korrekt och att identifieringsregionen är korrekt. Du kan också gå tillbaka till Custom Vision-webbplatsen och se det aktuella tillståndet för det nyskapade projektet.

Rensa resurser

Om du vill implementera ett eget objektidentifieringsprojekt (eller prova ett projekt för bildklassificering istället) kan du vilja ta bort projektet för gaffel-/saxidentifiering (fork/scissors) från det här exemplet. En kostnadsfri prenumeration tillåter två Custom Vision-projekt.

Custom Vision-webbplatsen går du till Projects (Projekt) och väljer papperskorgen under My New Project (Mitt nya projekt).

Screenshot of a panel labeled My New Project with a trash can icon.

Nästa steg

Nu har du gjort varje steg i objektidentifieringsprocessen i koden. Det här exemplet kör en enda tränings iteration, men ofta måste du träna och testa din modell flera gånger för att göra den mer exakt. Följande guide behandlar bildklassificering, men principerna liknar dem som gäller för objektidentifiering.