Příklad: Použití funkce ve velkém měřítku

Tento průvodce je pokročilý článek o tom, jak škálovat z existujících objektů PersonGroup a FaceList na objekty LargePersonGroup a LargeFaceList. Tento průvodce ukazuje proces migrace. Předpokládá základní znalost objektů PersonGroup a FaceList, operace Train a funkcí rozpoznávání tváře. Další informace o těchto tématech najdete v koncepčním průvodci rozpoznáváním tváře.

LargePersonGroup a LargeFaceList se souhrnně označují jako rozsáhlé operace. LargePersonGroup může obsahovat až 1 milion osob, z nichž každá má maximálně 248 tváří. LargeFaceList může obsahovat až 1 milion tváří. Operace ve velkém měřítku se podobají konvenčním skupinám PersonGroup a FaceList, ale vzhledem k nové architektuře existují určité rozdíly.

Ukázky jsou napsané v jazyce C# pomocí klientské knihovny Azure Cognitive Services Face.

Poznámka

Pokud chcete povolit výkon vyhledávání tváří pro funkce Identification a FindSimilar ve velkém měřítku, zavedete operaci Train, která předzpracuje LargeFaceList a LargePersonGroup. Doba trénování se v závislosti na skutečné kapacitě liší od sekund až po půlhodinu. Během trénování je možné provést operaci Identification a FindSimilar, pokud se dříve úspěšně trénování provedlo. Nevýhodou je, že nové přidané osoby a tváře se ve výsledku nezobrazují, dokud se nedokončí nová migrace na rozsáhlé trénování.

Krok 1: Inicializace objektu klienta

Když použijete klientskou knihovnu pro službu Face, klíč předplatného a koncový bod předplatného se předá prostřednictvím konstruktoru třídy FaceClient. Příklad:

string SubscriptionKey = "<Subscription Key>";
// Use your own subscription endpoint corresponding to the subscription key.
string SubscriptionEndpoint = "https://westus.api.cognitive.microsoft.com";
private readonly IFaceClient faceClient = new FaceClient(
            new ApiKeyServiceClientCredentials(subscriptionKey),
            new System.Net.Http.DelegatingHandler[] { });
faceClient.Endpoint = SubscriptionEndpoint

Pokud chcete získat klíč předplatného s odpovídajícím koncovým bodem, přejděte na Azure Marketplace z Azure Portal. Další informace najdete v tématu Předplatná.

Krok 2: Migrace kódu

Tato část se zaměřuje na migraci implementace PersonGroup nebo FaceList do LargePersonGroup nebo LargeFaceList. Přestože se LargePersonGroup nebo LargeFaceList v návrhu a interní implementaci liší od PersonGroup nebo FaceList, rozhraní API jsou pro zpětnou kompatibilitu podobná.

Migrace dat se nepodporuje. Místo toho znovu vytvoříte LargePersonGroup nebo LargeFaceList.

Migrace skupiny PersonGroup do skupiny LargePersonGroup

Migrace z PersonGroup do LargePersonGroup je jednoduchá. Sdílejí přesně stejné operace na úrovni skupiny.

Pro implementaci PersonGroup nebo person-related je nutné změnit pouze cesty rozhraní API nebo třídu nebo modul sady SDK na LargePersonGroup a LargePersonGroup Person.

Přidejte všechny tváře a osoby ze skupiny PersonGroup do nové skupiny LargePersonGroup. Další informace najdete v tématu Přidání tváří.

Migrace prvku FaceList do largeFaceList

Rozhraní API kolekce FaceList Rozhraní API kolekce LargeFaceList
Vytvořit Vytvořit
Odstranit Odstranit
Získat Získat
Seznam Seznam
Aktualizace Aktualizace
- Trénování
- Get Training Status

Předchozí tabulka je srovnáním operací na úrovni seznamu mezi kolekcemi FaceList a LargeFaceList. Jak je vidět na obrázku, LargeFaceList obsahuje nové operace Train (Trénovat) a Get Training Status (Získat stav trénování) v porovnání se seznamem FaceList. Trénování LargeFaceList je předpokladem operace FindSimilar. Ovládací prvek FaceList nevyžaduje trénování. Následující fragment kódu je pomocná funkce pro čekání na trénování LargeFaceList:

/// <summary>
/// Helper function to train LargeFaceList and wait for finish.
/// </summary>
/// <remarks>
/// The time interval can be adjusted considering the following factors:
/// - The training time which depends on the capacity of the LargeFaceList.
/// - The acceptable latency for getting the training status.
/// - The call frequency and cost.
///
/// Estimated training time for LargeFaceList in different scale:
/// -     1,000 faces cost about  1 to  2 seconds.
/// -    10,000 faces cost about  5 to 10 seconds.
/// -   100,000 faces cost about  1 to  2 minutes.
/// - 1,000,000 faces cost about 10 to 30 minutes.
/// </remarks>
/// <param name="largeFaceListId">The Id of the LargeFaceList for training.</param>
/// <param name="timeIntervalInMilliseconds">The time interval for getting training status in milliseconds.</param>
/// <returns>A task of waiting for LargeFaceList training finish.</returns>
private static async Task TrainLargeFaceList(
    string largeFaceListId,
    int timeIntervalInMilliseconds = 1000)
{
    // Trigger a train call.
    await FaceClient.LargeTrainLargeFaceListAsync(largeFaceListId);

    // Wait for training finish.
    while (true)
    {
        Task.Delay(timeIntervalInMilliseconds).Wait();
        var status = await faceClient.LargeFaceList.TrainAsync(largeFaceListId);

        if (status.Status == Status.Running)
        {
            continue;
        }
        else if (status.Status == Status.Succeeded)
        {
            break;
        }
        else
        {
            throw new Exception("The train operation is failed!");
        }
    }
}

Dříve typické použití prvku FaceList s přidaných tváří a funkce FindSimilar vypadala takto:

// Create a FaceList.
const string FaceListId = "myfacelistid_001";
const string FaceListName = "MyFaceListDisplayName";
const string ImageDir = @"/path/to/FaceList/images";
faceClient.FaceList.CreateAsync(FaceListId, FaceListName).Wait();

// Add Faces to the FaceList.
Parallel.ForEach(
    Directory.GetFiles(ImageDir, "*.jpg"),
    async imagePath =>
        {
            using (Stream stream = File.OpenRead(imagePath))
            {
                await faceClient.FaceList.AddFaceFromStreamAsync(FaceListId, stream);
            }
        });

// Perform FindSimilar.
const string QueryImagePath = @"/path/to/query/image";
var results = new List<SimilarPersistedFace[]>();
using (Stream stream = File.OpenRead(QueryImagePath))
{
    var faces = faceClient.Face.DetectWithStreamAsync(stream).Result;
    foreach (var face in faces)
    {
        results.Add(await faceClient.Face.FindSimilarAsync(face.FaceId, FaceListId, 20));
    }
}

Při migraci na LargeFaceList se stane toto:

// Create a LargeFaceList.
const string LargeFaceListId = "mylargefacelistid_001";
const string LargeFaceListName = "MyLargeFaceListDisplayName";
const string ImageDir = @"/path/to/FaceList/images";
faceClient.LargeFaceList.CreateAsync(LargeFaceListId, LargeFaceListName).Wait();

// Add Faces to the LargeFaceList.
Parallel.ForEach(
    Directory.GetFiles(ImageDir, "*.jpg"),
    async imagePath =>
        {
            using (Stream stream = File.OpenRead(imagePath))
            {
                await faceClient.LargeFaceList.AddFaceFromStreamAsync(LargeFaceListId, stream);
            }
        });

// Train() is newly added operation for LargeFaceList.
// Must call it before FindSimilarAsync() to ensure the newly added faces searchable.
await TrainLargeFaceList(LargeFaceListId);

// Perform FindSimilar.
const string QueryImagePath = @"/path/to/query/image";
var results = new List<SimilarPersistedFace[]>();
using (Stream stream = File.OpenRead(QueryImagePath))
{
    var faces = faceClient.Face.DetectWithStreamAsync(stream).Result;
    foreach (var face in faces)
    {
        results.Add(await faceClient.Face.FindSimilarAsync(face.FaceId, largeFaceListId: LargeFaceListId));
    }
}

Jak jsme si ukázali dříve, správa dat a část FindSimilar jsou téměř stejné. Jedinou výjimkou je, že než funkce FindSimilar funguje, musí se v seznamu LargeFaceList dokončit nová operace předběžného zpracování Train.

Krok 3: Trénovat návrhy

I když operace Train urychluje operace FindSimilar a Identification,doba trénování se zkrátí, zejména při nácvičí ve velkém měřítku. Odhadovaná doba trénování v různých měřítkách je uvedená v následující tabulce.

Škálování tváří nebo osob Odhadovaná doba trénování
1 000 1–2 s
10 000 5–10 sekund
100 000 1–2 min
1 000 000 10–30 minut

Pro lepší využití funkce ve velkém měřítku doporučujeme následující strategie.

Krok 3.1: Přizpůsobení časového intervalu

Jak je znázorněno v souboru , existuje časový interval v milisekundách, který TrainLargeFaceList() zpozdí nekonečnou kontrolu stavu trénování. U kolekce LargeFaceList s více tvářemi bude použití delšího intervalu znamenat nižší počet volání i náklady. Upravte časový interval podle očekávané kapacity prvku LargeFaceList.

Stejná strategie platí také pro LargePersonGroup. Například při trénování skupiny LargePersonGroup s 1 milionem osob může být timeIntervalInMilliseconds 60 000, což je 1minutový interval.

Krok 3.2: Malá vyrovnávací paměť

Osoby nebo tváře ve skupině LargePersonGroup nebo LargeFaceList lze prohledávat až po vytrénované podobě. V dynamickém scénáři se nové osoby nebo tváře neustále přidávají a musí být okamžitě prohledávatelné, ale trénování může trvat déle, než je žádoucí.

Pokud chcete tento problém zmírnit, použijte velmi malou skupinu LargePersonGroup nebo LargeFaceList jako vyrovnávací paměť pouze pro nově přidané položky. Vytrénovat tuto vyrovnávací paměť trvá kratší dobu kvůli menší velikosti. Funkce okamžitého vyhledávání v této dočasné vyrovnávací paměti by měla fungovat. Tuto vyrovnávací paměť použijte v kombinaci s trénování hlavní skupiny LargePersonGroup nebo LargeFaceList spuštěním hlavního trénování v intervalu parseru. Příklady jsou uprostřed noci a každý den.

Příklad pracovního postupu:

  1. Vytvořte hlavní kolekci LargePersonGroup nebo LargeFaceList, což je hlavní kolekce. Vytvořte vyrovnávací paměť LargePersonGroup nebo LargeFaceList, což je kolekce vyrovnávací paměti. Kolekce vyrovnávací paměti je pouze pro nově přidané osoby nebo tváře.
  2. Přidejte nové osoby nebo tváře do hlavní kolekce i kolekce vyrovnávací paměti.
  3. Trénování kolekce vyrovnávací paměti pouze s krátkým časovým intervalem, aby se zajistilo, že se nově přidané položky projeví.
  4. Zavolejte Identification nebo FindSimilar jak pro hlavní kolekci, tak pro kolekci vyrovnávací paměti. Sloučí výsledky.
  5. Když se velikost kolekce vyrovnávací paměti zvýší na prahovou hodnotu nebo v době nečinnosti systému, vytvořte novou kolekci vyrovnávací paměti. Aktivujte operaci Train v hlavní kolekci.
  6. Po dokončení operace Train v hlavní kolekci odstraňte starou kolekci vyrovnávací paměti.

Krok 3.3: Samostatné trénování

Pokud je přijatelná relativně dlouhá latence, není nutné hned po přidání nových dat aktivovat operaci Train. Místo toho můžete operaci Train oddělit od hlavní logiky a spouštět ji pravidelně. Tato strategie je vhodná pro dynamické scénáře s přijatelnou latencí. Můžete ho použít u statických scénářů, abyste frekvenci trénování dále snížili.

Předpokládejme, že je TrainLargePersonGroup funkce podobná TrainLargeFaceList . Typická implementace samostatného školení na LargePersonGroup vyvoláním Timer třídy v System.Timers je:

private static void Main()
{
    // Create a LargePersonGroup.
    const string LargePersonGroupId = "mylargepersongroupid_001";
    const string LargePersonGroupName = "MyLargePersonGroupDisplayName";
    faceClient.LargePersonGroup.CreateAsync(LargePersonGroupId, LargePersonGroupName).Wait();

    // Set up standalone training at regular intervals.
    const int TimeIntervalForStatus = 1000 * 60; // 1-minute interval for getting training status.
    const double TimeIntervalForTrain = 1000 * 60 * 60; // 1-hour interval for training.
    var trainTimer = new Timer(TimeIntervalForTrain);
    trainTimer.Elapsed += (sender, args) => TrainTimerOnElapsed(LargePersonGroupId, TimeIntervalForStatus);
    trainTimer.AutoReset = true;
    trainTimer.Enabled = true;

    // Other operations like creating persons, adding faces, and identification, except for Train.
    // ...
}

private static void TrainTimerOnElapsed(string largePersonGroupId, int timeIntervalInMilliseconds)
{
    TrainLargePersonGroup(largePersonGroupId, timeIntervalInMilliseconds).Wait();
}

Další informace o implementacích týkajících se správy dat a identifikace najdete v tématu Přidání plošek.

Souhrn

V této příručce jste zjistili, jak migrovat existující kód person nebo FaceList, ne data, na LargePersonGroup nebo LargeFaceList:

  • LargePersonGroup a LargeFaceList fungují podobně jako person nebo FaceList, s tím rozdílem, že operace vlaku vyžaduje LargeFaceList.
  • Využijte správnou strategii vlaků k aktualizaci dynamických dat pro velké datové sady.

Další kroky

Postupujte podle pokynů průvodce, abyste se seznámili s tím, jak přidat plošky do pole person nebo napsat skript, který provede operaci identifikace ve službě Person.