Масштабирование для обработки дополнительных зарегистрированных пользователей

Внимание

Доступ к службе "Распознавание лиц" ограничен на основе соответствия требованиям и критериев использования для реализации поддержки наших принципов ответственного ИИ. Служба "Распознавание лиц" доступна только для клиентов и партнеров, управляемых корпорацией Майкрософт. Используйте форму приема Распознавания лиц, чтобы подать заявку на доступ. Дополнительные сведения см. на странице с ограниченным доступом для лиц.

В этом руководстве показано, как масштабировать существующие объекты PersonGroup и FaceList до объектов LargePersonGroup и LargeFaceList соответственно. PersonGroups может содержать до 1000 человек на бесплатном уровне и 10 000 на платном уровне, в то время как LargePersonGroups может содержать до одного миллиона человек на платном уровне.

Важно!

Для новой разработки рекомендуется использовать новую структуру данных PersonDirectory . Он может содержать до 75 миллионов удостоверений и не требует ручного обучения. Дополнительные сведения см. в руководстве PersonDirectory.

Здесь мы продемонстрируем весь процесс миграции. В нем предполагается базовое знакомство с объектами PersonGroup и FaceList , операцией обучения и функциями распознавания лиц. Чтобы получить дополнительные сведения по этим темам, обратитесь к концептуальному руководству по распознаванию лиц.

LargePersonGroup и LargeFaceList называются крупномасштабными операциями. LargePersonGroup может содержать до 1 миллиона человек, каждый из которых составляет не более 248 лиц. LargeFaceList может содержать до 1 миллиона лиц. Крупномасштабные операции похожи на обычные PersonGroup и FaceList , но имеют некоторые отличия из-за новой архитектуры.

Примеры написаны на C# с помощью клиентской библиотеки Распознавания лиц Azure.

Примечание.

Чтобы обеспечить производительность поиска лиц для идентификации и findSimilar в большом масштабе, введите операцию обучения для предварительной обработки LargeFaceList и LargePersonGroup. Время обучения составляет от нескольких секунд до получаса в зависимости от фактического размера. В течение учебного периода можно выполнить идентификацию и FindSimilar , если раньше было выполнено успешное обучение. Недостаток заключается в том, что новые данные добавленных людей и лиц не появятся в результатах, пока не будет завершено обучение после перехода на крупномасштабные операции.

Шаг 1. Инициализация клиентского объекта

Если вы используете клиентскую библиотеку службы "Распознавание лиц", ключ и конечная точка подписки передаются через конструктор класса FaceClient. Инструкции по созданию клиентского объекта Face см. в кратком руководстве .

Шаг 2. Миграция кода

В этом разделе рассматривается перенос реализации PersonGroup или FaceList в LargePersonGroup или LargeFaceList. Хотя LargePersonGroup или LargeFaceList отличается от PersonGroup или FaceList в разработке и внутренней реализации, интерфейсы API похожи на обратную совместимость.

Перенос данных не поддерживается. Вместо этого вы повторно создадите LargePersonGroup или LargeFaceList .

Переход с PersonGroup на LargePersonGroup

Миграция из PersonGroup в LargePersonGroup проста. Они поддерживают совершенно одинаковые операции на уровне группы.

Для реализации PersonGroup или пользователя необходимо изменить только пути API или класс пакета SDK на LargePersonGroup и LargePersonGroup Person.

Добавьте все лица и лица из PersonGroup в новую группу LargePersonGroup. Дополнительные сведения см. в статье о добавлении лиц.

Переход с FaceList на LargeFaceList

ИНТЕРФЕЙСы API FaceList API LargeFaceList
Создание Создание
DELETE Удаление
Получить Получить
List List
Update Update
- Обучение
- Get Training Status

Предыдущая таблица — это сравнение операций на уровне списка между FaceList и LargeFaceList. Как показано, LargeFaceList поставляется с новыми операциями, обучением и получением состояния обучения по сравнению с FaceList. Обучение LargeFaceList является предварительным условием операции FindSimilar. Обучение не требуется для FaceList. Следующий фрагмент является вспомогательной функцией, чтобы дождаться обучения 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!");
        }
    }
}

Ранее обычное использование FaceList с добавленными лицами и FindSimilar выглядело следующим образом:

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

При миграции в LargeFaceList он становится следующим:

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

Как показано ранее, управление данными и часть FindSimilar почти совпадают. Единственное исключение заключается в том, что перед работой FindSimilar должна завершиться новая предварительная обработка операции обучения в LargeFaceList.

Шаг 3. Обучение предложений

Хотя операция "Обучение" ускоряет поиск и идентификацию,время обучения страдает, особенно при достижении большого масштаба. В представленной ниже таблице приведено предполагаемое время обучения для разных размеров.

Масштаб (люди или лица) Предполагаемое время обучения
1,000 1–2 с
10,000 5–10 с
100,000 1–2 мин
1 000 000 10–30 мин

Для оптимального использования крупномасштабных функций мы рекомендуем применять описанные далее стратегии.

Шаг 3a. Настройка интервала времени

Как показано в TrainLargeFaceList(), можно указать период в миллисекундах для задержки неопределенно долгого процесса проверки состояния обучения. Для LargeFaceList с большим количеством лиц, используя больший интервал, уменьшает количество вызовов и затрат. Настройте интервал времени в соответствии с ожидаемой емкостью LargeFaceList.

Та же стратегия также относится к LargePersonGroup. Например, при обучении LargePersonGroup с 1 миллионом человек может быть 60 000, timeIntervalInMilliseconds что составляет 1 минуту.

Шаг 3b. Небольшой буфер масштабирования

Лица или лица в LargePersonGroup или LargeFaceList доступны для поиска только после обучения. В сценарии динамического изменения данных новые люди и лица добавляются постоянно и должны немедленно становиться доступными для поиска. Но обучение может занимать слишком много времени.

Чтобы устранить эту проблему, используйте дополнительный небольшой масштаб LargePersonGroup или LargeFaceList в качестве буфера только для новых добавленных записей. Обучение этого буфера выполняется быстрее благодаря малому размеру. По нему вы сможете немедленно организовать поиск. Используйте этот буфер в сочетании с обучением на главном объекте LargePersonGroup или LargeFaceList , выполнив мастер-обучение на разреженном интервале. Например, ежедневно в полночь.

Пример рабочего процесса:

  1. Создайте эталонную коллекцию LargePersonGroup или LargeFaceList. Создайте буфер LargePersonGroup или LargeFaceList, который является коллекцией буферов. Буферная коллекция предназначена только для недавно добавленных людей и лиц.
  2. Добавляйте новые элементы Person и Face одновременно в основную и буферную коллекции.
  3. Выполняйте обучение с небольшим интервалом только для буферной коллекции, чтобы при поиске учитывались новые записи.
  4. Вызов идентификации или FindSimilar для основной коллекции и коллекции буферов. Объединяйте результаты операций.
  5. Когда размер буферной коллекции достигнет определенного порога или наступит период низкой загрузки системы, создайте новую буферную коллекцию. Активируйте операцию Train в главной коллекции.
  6. Удалите старую коллекцию буферов после завершения операции Train в главной коллекции.

Шаг 3c. Автономное обучение

Если допустима относительно длинная задержка, не требуется запускать операцию обучения сразу после добавления новых данных. Вместо этого операция обучения может быть разделена от основной логики и регулярно активируется. Такая стратегия подходит для динамических сценариев с допустимой задержкой. Его можно применить к статическим сценариям для дальнейшего уменьшения частоты обучения .

Допустим, есть функция TrainLargePersonGroup, аналогичная TrainLargeFaceList. Типичная реализация автономного обучения в LargePersonGroup путем вызова Timer класса в 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();
}

Дополнительные сведения о реализации управления данными и идентификации см. в статье Добавление лиц в PersonGroup.

Итоги

В этом руководстве вы узнали, как перенести существующий код PersonGroup или FaceList, а не данные в LargePersonGroup или LargeFaceList:

  • LargePersonGroup и LargeFaceList работают аналогично PersonGroup или FaceList, за исключением того, что операция "Обучение" требуется LargeFaceList.
  • Выполните правильную стратегию обучения для динамического обновления данных для крупномасштабных наборов данных.

Следующие шаги

Следуйте инструкциям, чтобы узнать, как добавить лица в PersonGroup или написать сценарий, чтобы выполнить операцию идентификации в PersonGroup.