Создание и развертывание пользовательской модели обнаружения объектов с помощью TensorFlow Lite (Android)

1. Прежде чем начать

В этой лабораторной работе вы узнаете, как обучить пользовательскую модель обнаружения объектов с помощью набора обучающих изображений с помощью TFLite Model Maker , а затем развернуть вашу модель в приложении для Android с помощью TFLite Task Library . Ты сможешь:

  • Создайте приложение для Android, которое определяет ингредиенты на изображениях блюд.
  • Интегрируйте предварительно обученную модель обнаружения объектов TFLite и узнайте, на что способна эта модель.
  • Обучите пользовательскую модель обнаружения объектов для обнаружения ингредиентов/компонентов еды с помощью пользовательского набора данных, называемого салатом , и TFLite Model Maker.
  • Разверните пользовательскую модель в приложении Android с помощью библиотеки задач TFLite.

В конце концов, вы создадите что-то похожее на изображение ниже:

b9705235366ae162.png

Предпосылки

Эта лаборатория кода предназначена для опытных мобильных разработчиков, которые хотят получить опыт работы с машинным обучением. Вы должны быть знакомы с:

  • Разработка под Android с использованием Kotlin и Android Studio.
  • Базовый синтаксис Python

Что вы узнаете

  • Как обучить пользовательскую модель обнаружения объектов с помощью TFLite Model Maker.
  • Как развернуть модель обнаружения объектов TFLite с помощью библиотеки задач TFLite.

Что вам понадобится

  • Последняя версия Android Studio (v4.2+)
  • Эмулятор Android Studio или физическое устройство Android
  • Пример кода
  • Базовые знания Android-разработки на Kotlin

2. Обнаружение объекта

Обнаружение объектов — это набор задач компьютерного зрения, которые могут обнаруживать и находить объекты на цифровом изображении. При наличии изображения или видеопотока модель обнаружения объектов может определить, какие из известного набора объектов могут присутствовать, и предоставить информацию об их позициях на изображении.

TensorFlow предоставляет предварительно обученные модели, оптимизированные для мобильных устройств, которые могут обнаруживать обычные объекты, такие как автомобили, апельсины и т. д. Вы можете интегрировать эти предварительно обученные модели в свое мобильное приложение, написав всего несколько строк кода. Однако вы можете захотеть или вам нужно обнаружить объекты в более характерных или необычных категориях. Это требует сбора ваших собственных обучающих изображений, а затем обучения и развертывания вашей собственной модели обнаружения объектов.

ТензорФлоу Лайт

TensorFlow Lite — это кроссплатформенная библиотека машинного обучения, оптимизированная для запуска моделей машинного обучения на периферийных устройствах, включая мобильные устройства Android и iOS.

TensorFlow Lite на самом деле является основным механизмом, используемым в ML Kit для запуска моделей машинного обучения. В экосистеме TensorFlow Lite есть два компонента, которые упрощают обучение и развертывание моделей машинного обучения на мобильных устройствах:

  • Model Maker — это библиотека Python, которая позволяет легко обучать модели TensorFlow Lite с использованием ваших собственных данных, написав всего несколько строк кода и не требуя опыта машинного обучения.
  • Библиотека задач — это кроссплатформенная библиотека, которая упрощает развертывание моделей TensorFlow Lite с помощью всего нескольких строк кода в ваших мобильных приложениях.

Эта лаборатория кода фокусируется на TFLite. Концепции и блоки кода, не относящиеся к TFLite и обнаружению объектов, не объясняются и предоставляются для простого копирования и вставки.

3. Настройте

Скачать код

Щелкните следующую ссылку, чтобы загрузить весь код для этой лаборатории кода:

Распакуйте загруженный zip-файл. Это распакует корневую папку ( odml-pathways-main ) со всеми необходимыми ресурсами. Для этой лаборатории кода вам понадобятся только исходники в подкаталоге object-detection/codelab2/android .

Подкаталог android в репозитории object-detection/codelab2/android содержит два каталога:

  • android_studio_folder.png starter — начальный код, на основе которого вы строите эту лабораторию кода.
  • android_studio_folder.png final — Завершенный код для готового примера приложения.

Импортировать стартовое приложение

Начнем с импорта начального приложения в Android Studio.

  1. Откройте Android Studio и выберите «Импорт проекта» (Gradle, Eclipse ADT и т. д.).
  2. Откройте starter папку из исходного кода, который вы скачали ранее.

7c0f27882a2698ac.png

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

  1. Выберите «Синхронизировать проект с файлами Gradle» ( b451ab2d04d835f9.png ) на панели инструментов Android Studio. Импортировать starter/app/build.gradle

Запустите стартовое приложение

Теперь, когда вы импортировали проект в Android Studio, вы готовы запустить приложение в первый раз.

Подключите Android-устройство через USB к компьютеру или запустите эмулятор Android Studio и нажмите « Выполнить» ( исполнять.png ) на панели инструментов Android Studio.

4. Разберитесь со стартовым приложением

Чтобы сделать эту кодовую лабораторию простой и сосредоточенной на битах машинного обучения, начальное приложение содержит некоторый шаблонный код, который делает несколько вещей для вас:

  • Он может делать фотографии с помощью камеры устройства.
  • Он содержит несколько стоковых изображений, чтобы вы могли попробовать обнаружение объектов на эмуляторе Android.
  • У него есть удобный способ отрисовки результата обнаружения объекта на входном растровом изображении.

В основном вы будете взаимодействовать с этими методами в скелете приложения:

  • fun runObjectDetection(bitmap: Bitmap) Этот метод вызывается, когда вы выбираете предустановленное изображение или делаете снимок. bitmap является входным изображением для обнаружения объекта. Позже в этой лабораторной работе вы добавите к этому методу код обнаружения объектов.
  • data class DetectionResult(val boundingBoxes: Rect, val text: String) Это класс данных, представляющий результат обнаружения объекта для визуализации. boundingBoxes — это прямоугольник, в котором находится объект, а text — это строка результата обнаружения, отображаемая вместе с ограничивающей рамкой объекта.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<DetectionResult>): Bitmap Этот метод рисует результаты detectionResults объекта в discoveryResults на входном bitmap и возвращает его измененную копию.

Вот пример вывода служебного метода drawDetectionResult .

f6b1e6dad726e129.png

5. Добавьте обнаружение объектов на устройстве

Теперь вы создадите прототип, интегрировав предварительно обученную модель TFLite, которая может обнаруживать общие объекты, в начальное приложение.

Загрузите предварительно обученную модель обнаружения объектов TFLite

В TensorFlow Hub есть несколько моделей детекторов объектов, которые вы можете использовать. Для этой лаборатории кода вы загрузите модель обнаружения объектов EfficientDet-Lite , обученную на наборе данных COCO 2017 , оптимизированную для TFLite и разработанную для производительности на мобильных процессорах, графических процессорах и EdgeTPU.

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

Добавьте модель в стартовое приложение

  1. Скопируйте модель, которую вы только что загрузили, в папку assets начального приложения. Вы можете найти папку на панели навигации проекта в Android Studio.

c2609599b7d22641.png

  1. Назовите файл model.tflite .

c83e9397177c4561.png

Обновите зависимости библиотеки задач файла Gradle.

Перейдите в файл app/build.gradle и добавьте эту строку в конфигурацию dependencies :

implementation 'org.tensorflow:tensorflow-lite-task-vision:0.3.1'

Синхронизируйте свой проект с файлами gradle

Чтобы быть уверенным, что все зависимости доступны для вашего приложения, вы должны синхронизировать свой проект с файлами gradle на этом этапе. Выберите «Синхронизировать проект с файлами Gradle» ( b451ab2d04d835f9.png ) на панели инструментов Android Studio.

(Если эта кнопка отключена, убедитесь, что вы импортируете только start/app/build.gradle, а не весь репозиторий.)

Настройте и запустите обнаружение объектов на устройстве на изображении

Есть только 3 простых шага с 3 API для загрузки и запуска модели обнаружения объектов:

  • подготовить изображение/поток: TensorImage
  • создать объект детектора: ObjectDetector
  • соедините 2 объекта выше: detect(image)

Вы достигаете этого внутри функции runObjectDetection(bitmap: Bitmap) в файле MainActivity.kt .

/**
* TFLite Object Detection Function
*/
private fun runObjectDetection(bitmap: Bitmap) {
    //TODO: Add object detection code here
}

Сейчас функция пуста. Перейдите к следующим шагам, чтобы реализовать детектор объектов TFLite. Попутно Android Studio предложит вам добавить необходимые импорты:

  • org.tensorflow.lite.support.image.TensorImage
  • org.tensorflow.lite.task.vision.detector.ObjectDetector

Создать объект изображения

Изображения, которые вы будете использовать для этой кодовой лаборатории, будут поступать либо с камеры на устройстве, либо с предустановленных изображений, которые вы выбираете в пользовательском интерфейсе приложения. Входное изображение декодируется в формат Bitmap и передается методу runObjectDetection .

TFLite предоставляет простой API для создания TensorImage из Bitmap . Добавьте приведенный ниже код в начало runObjectDetection(bitmap:Bitmap) :

// Step 1: create TFLite's TensorImage object
val image = TensorImage.fromBitmap(bitmap)

Создайте экземпляр детектора

Библиотека задач TFLite следует шаблону проектирования Builder. Вы передаете конфигурацию сборщику, а затем приобретаете у него детектор. Есть несколько параметров для настройки, в том числе для настройки чувствительности детектора объектов:

  • max result (максимальное количество объектов, которые должна обнаружить модель)
  • порог оценки (насколько уверенным должен быть детектор объекта, чтобы вернуть обнаруженный объект)
  • метка разрешенного/запрещенного списка (разрешить/запретить объекты в предопределенном списке)

Инициализируйте экземпляр детектора объектов, указав имя файла модели TFLite и параметры конфигурации:

// Step 2: Initialize the detector object
val options = ObjectDetector.ObjectDetectorOptions.builder()
    .setMaxResults(5)
    .setScoreThreshold(0.5f)
    .build()
val detector = ObjectDetector.createFromFileAndOptions(
    this, // the application context
    "model.tflite", // must be same as the filename in assets folder
    options
)

Подача изображений на детектор

Добавьте следующий код в fun runObjectDetection(bitmap:Bitmap) . Это подаст ваши изображения на детектор.

// Step 3: feed given image to the model and print the detection result
val results = detector.detect(image)

По завершении детектор возвращает список Detection , каждый из которых содержит информацию об объекте, который модель нашла на изображении. Каждый объект описывается с помощью:

  • boundingBox : прямоугольник, объявляющий о наличии объекта и его местоположении на изображении.
  • categories : что это за объект и насколько модель уверена в результате обнаружения. Модель возвращает несколько категорий, и самая надежная из них — первая.
  • label : название категории объектов.
  • classificationConfidence : число с плавающей запятой от 0,0 до 1,0, где 1,0 представляет 100 %.

Добавьте следующий код в fun runObjectDetection(bitmap:Bitmap) . Это вызывает метод для печати результатов обнаружения объектов в Logcat.

// Step 4: Parse the detection result and show it
debugPrint(results)

Затем добавьте этот debugPrint() в класс MainActivity :

private fun debugPrint(results : List<Detection>) {
    for ((i, obj) in results.withIndex()) {
        val box = obj.boundingBox

        Log.d(TAG, "Detected object: ${i} ")
        Log.d(TAG, "  boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")

        for ((j, category) in obj.categories.withIndex()) {
            Log.d(TAG, "    Label $j: ${category.label}")
            val confidence: Int = category.score.times(100).toInt()
            Log.d(TAG, "    Confidence: ${confidence}%")
        }
    }
} 

Теперь ваш детектор объектов готов! Скомпилируйте и запустите приложение, нажав кнопку « Выполнить» ( исполнять.png ) на панели инструментов Android Studio. Как только приложение появится на устройстве, нажмите на любое из предустановленных изображений, чтобы запустить детектор объектов. Затем посмотрите на окно Logcat *(* 16bd6ea224cf8cf1.png *)* внутри вашей IDE, и вы должны увидеть что-то похожее на это:

D/TFLite-ODT: Detected object: 0 
D/TFLite-ODT:   boundingBox: (0.0, 15.0) - (2223.0,1645.0)
D/TFLite-ODT:     Label 0: dining table
D/TFLite-ODT:     Confidence: 77%
D/TFLite-ODT: Detected object: 1 
D/TFLite-ODT:   boundingBox: (702.0, 3.0) - (1234.0,797.0)
D/TFLite-ODT:     Label 0: cup
D/TFLite-ODT:     Confidence: 69%

Это говорит вам о том, что детектор увидел 2 объекта. Первый:

  • Объект находится внутри прямоугольника (0, 15) – (2223, 1645)
  • Этикетка обеденный стол
  • Модель уверена, что 1-й — это обеденный стол (77%)

Технически это все, что вам нужно, чтобы библиотека задач TFLite работала: на данный момент у вас есть все! Поздравляем !

Однако со стороны пользовательского интерфейса вы все еще находитесь в начальной точке. Теперь вам нужно использовать обнаруженные результаты в пользовательском интерфейсе путем постобработки обнаруженных результатов.

6. Нарисуйте результат обнаружения на входном изображении.

На предыдущих шагах вы выводили результат обнаружения в logcat : просто и быстро. На этом шаге вы будете использовать служебный метод, уже реализованный для вас в стартовом приложении, чтобы:

  • нарисовать ограничивающую рамку на изображении
  • нарисуйте название категории и процент достоверности внутри ограничивающей рамки
  1. Замените debugPrint(results) следующим фрагментом кода:
val resultToDisplay = results.map {
    // Get the top-1 category and craft the display text
    val category = it.categories.first()
    val text = "${category.label}, ${category.score.times(100).toInt()}%"

    // Create a data object to display the detection result
    DetectionResult(it.boundingBox, text)
}
// Draw the detection result on the bitmap and show it.
val imgWithResult = drawDetectionResult(bitmap, resultToDisplay)
runOnUiThread {
    inputImageView.setImageBitmap(imgWithResult)
}
  1. Теперь нажмите «Выполнить» ( исполнять.png ) на панели инструментов Android Studio.
  2. После загрузки приложения коснитесь одного из предустановленных изображений, чтобы увидеть результат обнаружения.

Хотите попробовать со своей фотографией? Нажмите на кнопку « Сделать фото » и сделайте несколько снимков окружающих вас объектов.

8b024362b15096a6.png

7. Обучите пользовательскую модель обнаружения объектов

На предыдущем шаге вы интегрировали предварительно обученную модель обнаружения объектов TFLite в приложение для Android и сами убедились, что она может обнаруживать обычные объекты, такие как миски или обеденные столы, на образцах изображений. Однако ваша цель — обнаружить ингредиенты блюд на изображении, поэтому обычное обнаружение объектов не подходит для вашего варианта использования. Вы хотите обучить пользовательскую модель обнаружения объектов, используя обучающий набор данных с ингредиентами, которые мы хотим обнаружить.

Вот набор данных , содержащий изображения и метки, которые вы можете использовать для обучения своей собственной модели. Он был создан с использованием изображений из Open Images Dataset V4 .

Сотрудничество

Затем перейдем к Google Colab для обучения пользовательской модели.

Обучение пользовательской модели займет около 30 минут.

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

8. Интегрируйте пользовательскую модель TFLite в приложение для Android.

Теперь, когда вы обучили модель обнаружения салата, интегрируйте ее и превратите свое приложение из обычного детектора объектов в, в частности, детектор салата.

  1. Скопируйте модель салата TFLite в папку с assets . Назовите новую модель salad.tflite .

91e8d37c4f78eddb.png

  1. Откройте файл MainActivity.kt и найдите код инициализации ObjectDetector .
  2. Замените модель EfficientDet-Lite ( model.tflite ) моделью салата ( salad.tflite ).
val detector = ObjectDetector.createFromFileAndOptions(
    this, // the application context
    "salad.tflite", // must be same as the filename in assets folder
    options
)
  1. Щелкните Выполнить ( исполнять.png ) на панели инструментов Android Studio, чтобы повторно запустить приложение с новой моделью. Вуаля! Приложение теперь может распознавать сыры, салаты, выпечку.

b9705235366ae162.png

9. Поздравляем!

Вы использовали TFLite для обучения пользовательской модели и добавления возможностей обнаружения объектов в свое приложение. Это все, что вам нужно, чтобы запустить его!

Что мы рассмотрели

  • Как найти предварительно обученные модели обнаружения объектов TFLite на TensorFlow Hub
  • Как интегрировать модели обнаружения возражений в ваше приложение для Android с помощью библиотеки задач TFLite
  • Как обучить пользовательскую модель обнаружения объектов с помощью TFLite Model Maker

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

  • Используйте Firebase для улучшения развертывания модели TFLite.
  • Собирайте обучающие данные для обучения собственной модели
  • Примените обнаружение объектов в своем собственном приложении для Android

Учить больше