Condividi tramite


Ridimensionare per gestire più utenti registrati

Attenzione

L'accesso al servizio Viso è limitato in base ai criteri di idoneità e utilizzo al fine di supportare i nostri principi di intelligenza artificiale responsabile. Il servizio Viso è disponibile solo per i clienti e i partner gestiti da Microsoft. Usare il modulo di acquisizione riconoscimento volto per richiedere l'accesso. Per altre informazioni, vedere la pagina Accesso limitato dalla funzione Viso.

Questa guida illustra come aumentare le prestazioni da oggetti PersonGroup e FaceList esistenti rispettivamente a oggetti LargePersonGroup e LargeFaceList. PersonGroups può contenere fino a 1000 persone nel livello gratuito e 10.000 nel livello a pagamento, mentre LargePersonGroups può contenere fino a un milione di persone nel livello a pagamento.

Importante

La struttura di dati più recente PersonDirectory è consigliata per il nuovo sviluppo. Può contenere fino a 75 milioni di identità e non richiede training manuale. Per altre informazioni, vedere la Guida di PersonDirectory.

Questa guida illustra il processo di migrazione. Presuppone una conoscenza di base degli oggetti PersonGroup e FaceList , dell'operazione Train e delle funzioni di riconoscimento del viso. Per altre informazioni su questi argomenti, vedere la guida concettuale al riconoscimento volto.

LargePersonGroup e LargeFaceList sono collettivamente definiti operazioni su larga scala. LargePersonGroup può contenere fino a 1 milione di persone, ognuna con un massimo di 248 visi. LargeFaceList può contenere fino a 1 milione di visi. Le operazioni su larga scala sono simili a PersonGroup e FaceList convenzionali, ma presentano alcune differenze a causa della nuova architettura.

Gli esempi vengono scritti in C# usando la libreria client viso di Intelligenza artificiale di Azure.

Nota

Per abilitare le prestazioni di ricerca viso per Identificazione e FindSimilar su larga scala, introdurre un'operazione Train per pre-elaborare LargeFaceList e LargePersonGroup. Il tempo di training varia da alcuni secondi a circa mezz'ora, a seconda della capacità effettiva. Durante il periodo di training, è possibile eseguire Identificazione e FindSimilar se un'operazione di training corretta è stata eseguita in precedenza. Nuove persone e nuovi visi aggiunti non vengono visualizzati nel risultato fino a quando non viene completata una nuova post-migrazione al training su larga scala.

Passaggio 1 - Inizializzare l'oggetto client

Quando si usa la libreria client Viso, la chiave e l'endpoint di sottoscrizione vengono trasferiti tramite il costruttore della classe FaceClient. Per istruzioni sulla creazione di un oggetto client Viso, vedere avvio rapido.

Passaggio 2 - Migrazione del codice

Questa sezione è incentrata su come eseguire la migrazione dell'implementazione PersonGroup o FaceList a LargePersonGroup o LargeFaceList. Anche se LargePersonGroup o LargeFaceList differisce da PersonGroup o FaceList nella progettazione e nell'implementazione interna, le interfacce API sono simili per la compatibilità con le versioni precedenti.

La migrazione dei dati non è supportata. È invece possibile ricreare LargePersonGroup o LargeFaceList.

Eseguire la migrazione da un oggetto PersonGroup a un oggetto LargePersonGroup

La migrazione da un persongroup a un oggetto LargePersonGroup è semplice. Questi oggetti condividono esattamente le stesse operazioni a livello di gruppo.

Per l'implementazione di PersonGroup o persona, è necessario modificare solo i percorsi API o la classe/modulo SDK in LargePersonGroup e LargePersonGroupPerson.

Aggiungere tutti i visi e le persone del PersonGroup al nuovo LargePersonGroup. Per altre informazioni, vedere Aggiungere visi.

Eseguire la migrazione da un oggetto FaceList a un oggetto LargeFaceList

API FaceList API LargeFaceList
Creazione Creazione
Eliminare Elimina
Recupero Recupero
List List
Aggiornamento Aggiornamento
- Esecuzione del training
- Get Training Status

La tabella precedente è un confronto delle operazioni a livello di elenco tra FaceList e LargeFaceList. Come illustrato, LargeFaceList include nuove operazioni, Train e Get Training Status, rispetto a FaceList. Il training di LargeFaceList è una precondizione dell'operazione FindSimilar . Il training non è necessario per FaceList. Il frammento di codice seguente è una funzione helper che attende il training di un oggetto 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.LargeFaceList.TrainAsync(largeFaceListId);

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

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

In precedenza, un uso tipico di FaceList con visi aggiunti e FindSimilar ha un aspetto simile al seguente:

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

// 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 = await faceClient.Face.DetectWithStreamAsync(stream);
    foreach (var face in faces)
    {
        results.Add(await faceClient.Face.FindSimilarAsync(face.FaceId, FaceListId, 20));
    }
}

Quando si esegue la migrazione a LargeFaceList, diventa il seguente:

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

// 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 = await faceClient.Face.DetectWithStreamAsync(stream);
    foreach (var face in faces)
    {
        results.Add(await faceClient.Face.FindSimilarAsync(face.FaceId, largeFaceListId: LargeFaceListId));
    }
}

Come illustrato in precedenza, la gestione dei dati e la parte FindSimilar sono quasi uguali. L'unica eccezione è che un'operazione train di pre-elaborazione aggiornata deve essere completata in LargeFaceList prima del funzionamento di FindSimilar.

Passaggio 3 - Suggerimenti per l'operazione di training

Anche se l'operazione Train accelera FindSimilar e Identificazione, il tempo di training soffre, soprattutto quando si arriva su larga scala. I tempi di training stimati per dimensioni diverse sono elencati nella tabella seguente.

Dimensione per visi o persone Tempo di training stimato
1.000 1-2 secondi
10,000 5-10 secondi
100,000 1-2 minuti
1\.000.000 10-30 minuti

Per usare al meglio la funzionalità su larga scala, è consigliabile adottare le strategie seguenti.

Passaggio 3a: Personalizzare l'intervallo di tempo

Come illustrato in TrainLargeFaceList(), è presente un intervallo di tempo, espresso in millisecondi, per ritardare il processo di verifica dello stato di training infinito. Per LargeFaceList con più visi, l'uso di un intervallo maggiore riduce i conteggi e i costi delle chiamate. Personalizzare l'intervallo di tempo in base alla capacità prevista di LargeFaceList.

La stessa strategia si applica anche a LargePersonGroup. Ad esempio, quando si esegue il training di un oggetto LargePersonGroup con 1 milione di persone, timeIntervalInMilliseconds potrebbe essere 60.000, ovvero un intervallo di 1 minuto.

Passaggio 3b: buffer su scala ridotta

Le persone o i visi in un oggetto LargePersonGroup o LargeFaceList possono essere cercati solo dopo il training. In uno scenario dinamico, nuovi visi o persone vengono continuamente aggiunti e deve essere immediatamente possibile eseguirne la ricerca. Il training può pertanto richiedere più tempo del previsto.

Per attenuare questo problema, usare un LargePersonGroup o LargeFaceList su larga scala come buffer solo per le voci appena aggiunte. Grazie alle dimensioni ridotte, questo buffer richiede un tempo di training minore. La funzionalità di ricerca immediata in questo buffer temporaneo dovrebbe funzionare in modo corretto. Usare questo buffer in combinazione con il training sul master LargePersonGroup o LargeFaceList eseguendo il training master in un intervallo di tipo sparse. Ad esempio, a mezzanotte e con frequenza giornaliera.

Di seguito viene indicato un flusso di lavoro di esempio:

  1. Creare un master LargePersonGroup o LargeFaceList, ovvero la raccolta master. Creare un buffer LargePersonGroup o LargeFaceList, ovvero la raccolta di buffer. La raccolta buffer è relativa solo alle persone o ai visi nuovi aggiunti.
  2. Aggiungere nuovi visi o persone sia alla raccolta principale che alla raccolta buffer.
  3. Eseguire solo il training della raccolta buffer con un breve intervallo di tempo per verificare che le voci appena aggiunte diventino effettive.
  4. Chiamare Identification o FindSimilar sia per la raccolta master che per la raccolta di buffer. Unire i risultati.
  5. Quando le dimensioni della raccolta buffer aumentano fino a una soglia stabilita o causano un tempo di inattività del sistema, creare una nuova raccolta buffer. Attivare l'operazione Train sulla raccolta master.
  6. Eliminare la raccolta di buffer precedente al termine dell'operazione Train nella raccolta master.

Passaggio 3c: Training autonomo

Se una latenza relativamente lunga è accettabile, non è necessario attivare l'operazione Train subito dopo l'aggiunta di nuovi dati. L'operazione Train può invece essere suddivisa dalla logica principale e attivata regolarmente. Questa strategia è adatta per scenari dinamici con una latenza accettabile. Può essere applicato agli scenari statici per ridurre ulteriormente la frequenza di training .

Si supponga che sia disponibile una funzione TrainLargePersonGroup analoga alla funzione TrainLargeFaceList. Un'implementazione tipica del training autonomo in un LargePersonGroup richiamando la Timer classe in System.Timers è:

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

Per altre informazioni sulla gestione dei dati e sulle implementazioni correlate all'identificazione, vedere Aggiungere visi.

Riepilogo

In questa guida si è appreso come eseguire la migrazione del codice PersonGroup o FaceList esistente, non dei dati, a LargePersonGroup o LargeFaceList:

  • LargePersonGroup e LargeFaceList funzionano in modo simile a PersonGroup o FaceList, ad eccezione del fatto che l'operazione Train è richiesta da LargeFaceList.
  • Adottare la strategia di training appropriata per l'aggiornamento dinamico dei dati per set di dati su larga scala.

Passaggi successivi

Seguire una guida pratica per informazioni su come aggiungere visi a un PersonGroup o scrivere uno script per eseguire l'operazione Di identificazione in un PersonGroup.