Добавьте Firebase в свое Android-приложение на базе TFLite

1. Обзор

cd824ecfd05a2822.png

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

В этой лаборатории кода вы преобразуете приложение Android, использующее статическую модель TFLite, в приложение, использующее модель, динамически обслуживаемую из Firebase.

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

  • Разверните модели TFLite в Firebase ML и получите к ним доступ из своего приложения.
  • Отслеживайте отзывы пользователей, чтобы измерить точность модели с помощью Firebase Analytics.
  • Производительность модели профиля через Firebase Performance
  • Выберите, какая из нескольких развернутых моделей загружается через Remote Config.
  • Экспериментируйте с различными моделями с помощью A/B-тестирования Firebase.

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

  • Последняя версия Android Studio .
  • Образец кода.
  • Тестовое устройство с Android 5.0+ и сервисами Google Play 9.8 или новее или эмулятор с сервисами Google Play 9.8 или новее.
  • При использовании устройства — соединительный кабель.

Как вы будете использовать этот урок?

Прочтите только до конца Прочитайте его и выполните упражнения.

Как бы вы оценили свой опыт создания приложений для Android?

Новичок Средний Опытный

2. Получите пример кода

Клонируйте репозиторий GitHub из командной строки.

$ git clone https://github.com/FirebaseExtended/codelab-digitclassifier-android.git

Если у вас не установлен git, вы также можете скачать пример проекта со страницы GitHub или щелкнув эту ссылку .

3. Импортируйте стартовое приложение.

В Android Studio выберите каталог codelab-digitclassifier-android ( android_studio_folder.png ) из загрузки примера кода ( Файл > Открыть > .../codelab-digitclassifier-android/start).

Теперь у вас должен быть открыт стартовый проект в Android Studio.

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

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

Приложение должно запуститься на вашем устройстве. На этом этапе, если вы попытаетесь нарисовать цифру, приложение сможет ее распознать.

6e36e1b947b395f2.png

5. Создайте консольный проект Firebase.

Добавьте Firebase в проект

  1. Перейдите в консоль Firebase .
  2. Выберите Добавить проект .
  3. Выберите или введите имя проекта.
  4. Выполните оставшиеся шаги настройки в консоли Firebase, затем нажмите «Создать проект» (или «Добавить Firebase», если вы используете существующий проект Google).

6. Добавьте Firebase

  1. На обзорном экране вашего нового проекта щелкните значок Android, чтобы запустить рабочий процесс установки.
  2. Введите имя пакета кодовой лаборатории: org.tensorflow.lite.examples.digitclassifier .

Добавьте файл google-services.json в свое приложение.

Зарегистрировав имя пакета и выбрав «Далее», нажмите «Загрузить google-services.json» , чтобы получить файл конфигурации Firebase Android, а затем скопируйте файл google-services.json в каталог app вашего проекта. После загрузки файла вы можете пропустить следующие шаги, показанные в консоли (они уже были сделаны за вас в проекте build-android-start).

Добавьте плагин Google-сервисов в свое приложение

Плагин google-services использует файл google-services.json для настройки вашего приложения на использование Firebase. Добавьте следующую строку в блок plugins в верхней части файла build.gradle.kts в каталоге app вашего проекта:

приложение/build.gradle.kts

id("com.google.gms.google-services")

Затем добавьте следующую строку в блок plugins вашего файла build.gradle.kts в проекте:

проект/build.gradle.kts

id("com.google.gms.google-services") version "4.3.15" apply false

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

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

7. Запустите приложение с помощью Firebase.

Теперь, когда вы настроили плагин google-services с помощью файла JSON, вы готовы запустить приложение с помощью Firebase. Подключите устройство Android и нажмите «Выполнить» ( выполнить.png ) на панели инструментов Android Studio.

Приложение должно запуститься на вашем устройстве. На этом этапе ваше приложение все равно должно успешно собираться.

8. Разверните модель в Firebase ML.

Развертывание модели в Firebase ML полезно по двум основным причинам:

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

Прежде чем мы сможем заменить статическую модель в нашем приложении динамически загруженной моделью из Firebase, нам необходимо развернуть ее в Firebase ML. Модель можно развернуть либо через консоль, либо программно с помощью Firebase Admin SDK. На этом этапе мы выполним развертывание через консоль.

Для простоты мы будем использовать модель TensorFlow Lite, которая уже есть в нашем приложении. Сначала откройте консоль Firebase и нажмите «Машинное обучение» на левой навигационной панели. Нажмите «Начать», если вы открываете первый раз. Затем перейдите к «Пользовательский» и нажмите кнопку «Добавить пользовательскую модель».

При появлении запроса дайте модели описательное имя, например mnist_v1 , и загрузите файл из каталога проекта codelab в start/app/src/main/assets/mnist.tflite . Затем вы можете удалить этот файл модели TF Lite из проекта Android.

3c3c50e6ef12b3b.png

9. Загрузите модель из Firebase ML.

Выбор времени загрузки удаленной модели из Firebase в ваше приложение может оказаться непростым делом, поскольку модели TFLite могут вырасти относительно большими. В идеале мы хотим избежать загрузки модели сразу при запуске приложения, поскольку, если наша модель используется только для одной функции, а пользователь никогда не использует эту функцию, мы без причины загрузим значительный объем данных. Мы также можем установить параметры загрузки, например, загрузку моделей только при подключении к Wi-Fi. Если вы хотите, чтобы модель была доступна даже без подключения к сети, важно также связать ее без приложения в качестве резервной копии.

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

В файле app/build.gradle.kts добавьте зависимость Firebase Machine Learning.

приложение/build.gradle.kts

implementation("com.google.firebase:firebase-ml-modeldownloader:24.1.2")

Затем добавьте логику для загрузки модели из Firebase.

Мы заменим digitClassifier.initialize(loadModelFile()) на downloadModel("mnist_v1") и реализуем этот метод.

MainActivity.kt

  private fun downloadModel(modelName: String): Task<CustomModel> {
    val conditions = CustomModelDownloadConditions.Builder()
    .requireWifi()
    .build()
    return FirebaseModelDownloader.getInstance()
        .getModel(modelName, DownloadType.LOCAL_MODEL, conditions)
        .addOnCompleteListener {
          val model = it.result
          if (model == null) {
            showToast("Failed to get model file.")
          } else {
            showToast("Downloaded remote model: $modelName")
            digitClassifier.initialize(model)
          }
        }
      .addOnFailureListener {
        showToast("Model download failed for $modelName, please check your connection.")
      }
  }

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

10. Отслеживайте отзывы пользователей и конверсии, чтобы измерить точность модели.

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

Мы будем измерять точность модели, отслеживая отзывы пользователей о прогнозах модели. Если пользователь нажмет «ДА», это будет означать, что прогноз оказался точным.

Мы можем зарегистрировать событие Analytics, чтобы отслеживать точность нашей модели. Во-первых, мы должны добавить Analytics в зависимость, прежде чем ее можно будет использовать в проекте:

Добавить зависимость Firebase Analytics

приложение/build.gradle.kts

implementation(platform("com.google.firebase:firebase-bom:32.0.0"))
implementation("com.google.firebase:firebase-analytics-ktx")

Журнал событий

Затем в функции onCreate мы настроим прослушиватель onclick для регистрации события correct_inference в Firebase.

MainActivity.kt (onCreate)

// Setup YES button
yesButton?.setOnClickListener {
  Firebase.analytics.logEvent("correct_inference", null)
}

Запустите приложение еще раз и нарисуйте цифру. Нажмите кнопку «Да» несколько раз, чтобы сообщить, что вывод верен.

Отладочная аналитика

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

Чтобы включить режим отладки Analytics на устройстве Android, выполните следующие команды:

adb shell setprop debug.firebase.analytics.app org.tensorflow.lite.examples.digitclassifier

Запустите приложение еще раз и нарисуйте цифру. Нажмите кнопку «Да» несколько раз, чтобы сообщить, что вывод верен. Теперь вы можете просматривать события журнала практически в реальном времени через представление отладки в консоли Firebase. Нажмите Аналитика > DebugView на левой панели навигации.

5276199a086721fd.png

11. Анализ производительности модели

Мониторинг производительности Firebase — это сервис, который помогает вам получить представление о характеристиках производительности ваших iOS, Android и веб-приложений.

Вы используете SDK Performance Monitoring для сбора данных о производительности из вашего приложения, а затем просматриваете и анализируете эти данные в консоли Firebase. Мониторинг производительности помогает вам понять, где и когда производительность вашего приложения можно улучшить, чтобы вы могли использовать эту информацию для устранения проблем с производительностью.

Здесь мы добавляем трассировки производительности вокруг вывода и скачиваем

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

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

проект/build.gradle.kts

plugins {
  // ...

  // Add the dependency for the Performance Monitoring plugin
  id("com.google.firebase.firebase-perf") version "1.4.2" apply false
}

приложение/build.gradle.kts

plugins {
  // ...

  // Add the Performance Monitoring plugin
  id("com.google.firebase.firebase-perf")
}

// ...

dependencies {
  // ...

  // Add the dependency for the Performance Monitoring library
  implementation("com.google.firebase:firebase-perf")
}

Добавить пользовательские трассировки

В функции setupDigitClassifier() создайте новую трассировку загрузки и запустите ее непосредственно перед загрузкой модели. Затем добавьте прослушиватель успеха, останавливающий трассировку.

В функции classifyDrawing() создайте новый classifyTrace и запустите его непосредственно перед классификацией. Затем остановите трассировку в прослушивателе успеха.

MainActivity.kt

class MainActivity : AppCompatActivity() {
  // ...
  
  private val firebasePerformance = FirebasePerformance.getInstance()
  
  // ...

  private fun setupDigitClassifier() {
    // Add these lines to create and start the trace
    val downloadTrace = firebasePerformance.newTrace("download_model")
    downloadTrace.start()
    downloadModel("mnist_v1")
      // Add these lines to stop the trace on success
      .addOnSuccessListener {
        downloadTrace.stop()
      }
  }

// ...

  private fun classifyDrawing() {
    val bitmap = drawView?.getBitmap()

    if ((bitmap != null) && (digitClassifier.isInitialized)) {
      // Add these lines to create and start the trace
      val classifyTrace = firebasePerformance.newTrace("classify")
      classifyTrace.start()
      digitClassifier
        .classifyAsync(bitmap)
        .addOnSuccessListener { resultText -> 
          // Add this line to stop the trace on success
          classifyTrace.stop()
          predictedTextView?.text = resultText
        }
        .addOnFailureListener { e ->
          predictedTextView?.text = getString(
            R.string.tfe_dc_classification_error_message,
            e.localizedMessage
          )
          Log.e(TAG, "Error classifying drawing.", e)
        }
    }
  }

Просмотр сообщений журнала о событиях производительности

  1. Включите ведение журнала отладки для мониторинга производительности во время сборки, добавив элемент <meta-data> в файл AndroidManifest.xml вашего приложения, например:

AndroidManifest.xml

<application>
    <meta-data
      android:name="firebase_performance_logcat_enabled"
      android:value="true" />
</application>
  1. Проверьте сообщения журнала на наличие сообщений об ошибках.
  2. Мониторинг производительности помечает свои сообщения журнала тегами FirebasePerformance . Используя фильтрацию logcat, вы можете просмотреть трассировку продолжительности и журнал сетевых запросов HTTP/S, выполнив следующую команду:
adb logcat -s FirebasePerformance
  1. Проверьте следующие типы журналов, которые указывают на то, что мониторинг производительности регистрирует события производительности:
  • Logging TraceMetric
  • Logging NetworkRequestMetric

12. Разверните вторую модель в Firebase ML.

При разработке новой версии вашей модели, например, с лучшей архитектурой модели или версии, обученной на более крупном или обновленном наборе данных, у нас может возникнуть соблазн заменить текущую модель новой версией. Однако модель, хорошо зарекомендовавшая себя в тестировании, не обязательно будет так же хорошо работать в производстве. Поэтому давайте проведем A/B-тестирование в производстве, чтобы сравнить нашу исходную модель и новую.

Включить API управления моделями Firebase

На этом этапе мы включим API управления моделями Firebase для развертывания новой версии нашей модели TensorFlow Lite с использованием кода Python.

Создайте корзину для хранения моделей машинного обучения.

В консоли Firebase перейдите в раздел «Хранилище» и нажмите «Начать». fbbea78f0eb3dc9f.png

Следуйте диалогу, чтобы настроить ведро.

19517c0d6d2aa14d.png

Включить API Firebase ML

Перейдите на страницу Firebase ML API в Google Cloud Console и нажмите «Включить».

2414fd5cced6c984.png Когда вас спросят, выберите приложение «Классификатор цифр».

Обучите новую модель и опубликуйте ее в Firebase ML.

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

Скачать закрытый ключ для сервисного аккаунта

Прежде чем мы сможем использовать Firebase Admin SDK, нам необходимо создать сервисную учетную запись. Откройте панель «Учетные записи служб» консоли Firebase, щелкнув эту ссылку , и нажмите кнопку, чтобы создать новую учетную запись службы для Firebase Admin SDK. При появлении запроса нажмите кнопку «Создать новый закрытый ключ». Мы будем использовать ключ служебной учетной записи для аутентификации наших запросов из блокнота Colab.

c3b95de1e5508516.png

Теперь мы можем обучить и развернуть новую модель.

  1. Откройте этот блокнот Colab и скопируйте его на свой Диск.
  2. Запустите первую ячейку «Обучение улучшенной модели TensorFlow Lite», нажав кнопку воспроизведения слева от нее. Это обучит новую модель и может занять некоторое время.
  3. Запуск второй ячейки создаст запрос на загрузку файла. Загрузите файл JSON, который вы скачали из консоли Firebase при создании учетной записи службы.

71e847c6a85423b3.png

  1. Запустите две последние ячейки.

После запуска блокнота Colab вы должны увидеть вторую модель в консоли Firebase. Убедитесь, что вторая модель называется mnist_v2 .

c316683bb4d75d57.png

13. Выберите модель через Remote Config.

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

Добавьте правила конфигурации в консоль Firebase

Сначала откройте консоль Firebase и нажмите кнопку Remote Config в левом навигационном меню. Затем нажмите кнопку «Добавить параметр».

Назовите новый параметр model_name и присвойте ему значение по умолчанию "mnist_v1" . Указав имя модели в параметре удаленной конфигурации, мы можем протестировать несколько моделей, не добавляя новый параметр для каждой модели, которую мы хотим протестировать. Нажмите «Опубликовать изменения» , чтобы применить обновления.

2949cb95c7214ca4.png

Добавить зависимость Firebase RemoteConfig

приложение/build.gradle.kts

implementation("com.google.firebase:firebase-config-ktx")

Настройка удаленной конфигурации Firebase

MainActivity.kt

  private fun configureRemoteConfig() {
    remoteConfig = Firebase.remoteConfig
    val configSettings = remoteConfigSettings {
      minimumFetchIntervalInSeconds = 3600
    }
    remoteConfig.setConfigSettingsAsync(configSettings)
  }

Запросить и использовать конфигурацию

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

MainActivity.kt

 private fun setupDigitClassifier() {
    configureRemoteConfig()
    remoteConfig.fetchAndActivate()
      .addOnCompleteListener { task ->
        if (task.isSuccessful) {
          val modelName = remoteConfig.getString("model_name")
          val downloadTrace = firebasePerformance.newTrace("download_model")
          downloadTrace.start()
          downloadModel(modelName)
            .addOnSuccessListener {
              downloadTrace.stop()
            }
        } else {
          showToast("Failed to fetch model name.")
        }
      }
  }

Тестирование удаленной конфигурации

  1. Нажмите кнопку 98205811bbed9d74.png Кнопка запуска .
  2. Убедитесь, что вы видите всплывающее сообщение о том, что модель mnist_v1 загружена.
  3. Вернитесь в консоль Firebase, измените значение по умолчанию на mnist_v2 и выберите «Опубликовать изменения» , чтобы применить обновления.
  4. Перезапустите приложение и проверьте всплывающее сообщение о том, что на этот раз загружена модель mnist_v2.

14. Эффективность модели A/B-тестирования

Firebase A/B-тестирование помогает оптимизировать работу вашего приложения, упрощая запуск, анализ и масштабирование продуктов и маркетинговых экспериментов. Наконец, мы можем использовать встроенное в Firebase поведение A/B-тестирования, чтобы увидеть, какая из двух наших моделей работает лучше.

Перейдите в Аналитика -> События в консоли Firebase. Если отображается событие correct_inference , отметьте его как «Событие-конверсия», если нет, вы можете перейти в «Аналитика» -> «События-конверсии», нажать «Создать новое событие-конверсию» и проставить correct_inference.

Теперь перейдите в «Удаленная настройка» в консоли Firebase, выберите кнопку «A/B-тест» в меню дополнительных параметров для только что добавленного параметра «имя_модели».

fad5ea36969d2aeb.png

В следующем меню примите имя по умолчанию.

d7c006669ace6e40.png

Выберите свое приложение в раскрывающемся списке и измените критерии таргетинга на 50 % активных пользователей.

cb72dcc7d2666bd3.png

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

1ac9c94fb3159271.png

Наконец, на экране «Варианты» установите для варианта контрольной группы использование mnist_v1 , а для группы варианта A — использование mnist_v2 .

e4510434f8da31b6.png

Нажмите кнопку «Просмотреть» в правом нижнем углу.

Поздравляем, вы успешно создали A/B-тест для двух отдельных моделей! A/B-тест в настоящее время находится в состоянии черновика, и его можно запустить в любой момент, нажав кнопку «Начать эксперимент».

Более подробную информацию об A/B-тестировании можно найти в документации по A/B-тестированию .

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

В этой лабораторной работе вы узнали, как заменить статически связанный ресурс tflite в вашем приложении динамически загружаемой моделью TFLite из Firebase. Чтобы узнать больше о TFLite и Firebase, ознакомьтесь с другими примерами TFLite и руководствами по началу работы с Firebase.

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

  • ТензорФлоу Лайт
  • Firebase ML
  • Аналитика Firebase
  • Мониторинг производительности Firebase
  • Удаленная конфигурация Firebase
  • A/B-тестирование Firebase

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

  • Внедрите развертывание Firebase ML в свое приложение.

Узнать больше

Есть вопрос?

Сообщить о проблемах