TFLite 기반 Android 앱에 Firebase 추가

1. 개요

cd824ecfd05a2822.png

Firebase ML을 사용하면 무선으로 모델을 배포할 수 있습니다. 이를 통해 앱 크기를 작게 유지하고 필요할 때만 ML 모델을 다운로드하거나, 여러 모델을 실험하거나, 전체 앱을 다시 게시할 필요 없이 ML 모델을 업데이트할 수 있습니다.

이 Codelab에서는 정적 TFLite 모델을 사용하는 Android 앱을 Firebase에서 동적으로 제공되는 모델을 사용하는 앱으로 변환합니다.

무엇을 배울 것인가

  • TFLite 모델을 Firebase ML에 배포하고 앱에서 액세스하세요.
  • Firebase Analytics로 모델 정확도를 측정하기 위해 사용자 피드백을 추적합니다.
  • Firebase Performance를 통한 프로필 모델 성능
  • 배포된 여러 모델 중 원격 구성을 통해 로드할 모델을 선택하세요.
  • Firebase A/B 테스팅을 통해 다양한 모델 실험

필요한 것

  • 최신 안드로이드 스튜디오 버전.
  • 샘플 코드.
  • 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 스튜디오에서 codelab-digitclassifier-android 디렉터리( android_studio_folder.png ) 샘플 코드 다운로드( 파일 > 열기 > .../codelab-digitclassifier-android/start)에서.

이제 Android Studio에서 시작 프로젝트가 열려 있어야 합니다.

4. 스타터 앱 실행

이제 프로젝트를 Android Studio로 가져왔으므로 처음으로 앱을 실행할 준비가 되었습니다. Android 장치를 연결하고 실행 ( 실행.png ) Android 스튜디오 도구 모음에서.

앱이 기기에서 실행되어야 합니다. 이때 숫자를 그리려고 하면 앱이 이를 인식할 수 있어야 합니다.

6e36e1b947b395f2.png

5. Firebase 콘솔 프로젝트 생성

프로젝트에 Firebase 추가

  1. Firebase 콘솔 로 이동합니다.
  2. 프로젝트 추가를 선택합니다.
  3. 프로젝트 이름을 선택하거나 입력합니다.
  4. Firebase 콘솔의 나머지 설정 단계를 따른 다음 프로젝트 만들기(또는 기존 Google 프로젝트를 사용하는 경우 Firebase 추가)를 클릭합니다.

6. 파이어베이스 추가

  1. 새 프로젝트의 개요 화면에서 Android 아이콘을 클릭하여 설정 워크플로를 시작하세요.
  2. Codelab의 패키지 이름( 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를 사용하도록 애플리케이션을 구성합니다. 프로젝트의 app 디렉터리에 있는 build.gradle.kts 파일 상단에 있는 plugins 블록에 다음 줄을 추가합니다.

앱/build.gradle.kts

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

그런 다음 프로젝트에 있는 build.gradle.kts 파일의 plugins 블록에 다음 줄을 추가합니다.

프로젝트/build.gradle.kts

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

프로젝트를 Gradle 파일과 동기화하세요

앱에서 모든 종속 항목을 사용할 수 있도록 하려면 이 시점에서 프로젝트를 Gradle 파일과 동기화해야 합니다. Android Studio 도구 모음에서 파일 > Gradle 파일과 프로젝트 동기화를 선택합니다.

7. Firebase로 앱 실행

이제 JSON 파일로 google-services 플러그인을 구성했으므로 Firebase로 앱을 실행할 준비가 되었습니다. Android 장치를 연결하고 실행 ( 실행.png ) Android 스튜디오 도구 모음에서.

앱이 기기에서 실행되어야 합니다. 이 시점에서도 앱은 여전히 ​​성공적으로 빌드되어야 합니다.

8. Firebase ML에 모델 배포

Firebase ML에 모델을 배포하는 것은 다음 두 가지 주요 이유로 유용합니다.

  1. 앱 설치 크기를 작게 유지하고 필요한 경우에만 모델을 다운로드할 수 있습니다.
  2. 모델은 정기적으로 업데이트될 수 있으며 전체 앱과 다른 릴리스 주기로 업데이트될 수 있습니다.

앱의 정적 모델을 Firebase에서 동적으로 다운로드한 모델로 대체하려면 먼저 이를 Firebase ML에 배포해야 합니다. 모델은 콘솔을 통해 배포하거나 Firebase Admin SDK를 사용하여 프로그래밍 방식으로 배포할 수 있습니다. 이 단계에서는 콘솔을 통해 배포하겠습니다.

작업을 단순하게 유지하기 위해 이미 앱에 있는 TensorFlow Lite 모델을 사용하겠습니다. 먼저 Firebase 콘솔을 열고 왼쪽 탐색 패널에서 Machine Learning을 클릭합니다. 처음 여는 경우 '시작하기'를 클릭하세요. 그런 다음 "사용자 정의"로 이동하여 "사용자 정의 모델 추가" 버튼을 클릭합니다.

메시지가 표시되면 모델에 mnist_v1 과 같은 설명이 포함된 이름을 지정하고 start/app/src/main/assets/mnist.tflite 아래 Codelab 프로젝트 디렉터리에서 파일을 업로드합니다. 그런 다음 Android 프로젝트에서 이 TF Lite 모델 파일을 삭제할 수 있습니다.

3c3c50e6ef12b3b.png

9. Firebase ML에서 모델 다운로드

TFLite 모델이 상대적으로 커질 수 있으므로 Firebase에서 원격 모델을 앱으로 다운로드할 시기를 선택하는 것이 까다로울 수 있습니다. 이상적으로는 앱이 시작될 때 즉시 모델을 로드하지 않는 것이 좋습니다. 모델이 하나의 기능에만 사용되고 사용자가 해당 기능을 전혀 사용하지 않는다면 아무 이유 없이 상당한 양의 데이터를 다운로드하게 되기 때문입니다. 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") 로 바꾸고 이 메서드를 구현하겠습니다.

메인액티비티.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. 사용자 피드백 및 전환을 추적하여 모델 정확도 측정

Firebase용 Google Analytics는 사용자가 애플리케이션을 통해 이동하는 방식, 성공하는 위치, 막히고 되돌아가는 위치를 이해할 수 있는 방법을 제공합니다. 또한 애플리케이션에서 가장 많이 사용되는 부분을 이해하는 데에도 사용할 수 있습니다.

모델 예측에 대한 사용자 피드백을 추적하여 모델의 정확도를 측정합니다. 사용자가 "예"를 클릭하면 예측이 정확했음을 나타냅니다.

Analytics 이벤트를 기록하여 모델의 정확성을 추적할 수 있습니다. 먼저 프로젝트에서 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 함수에서 correct_inference 이벤트를 Firebase에 기록하도록 onclick 리스너를 설정합니다.

MainActivity.kt(onCreate)

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

앱을 다시 실행하고 숫자를 그립니다. 추론이 정확했다는 피드백을 보내려면 "예" 버튼을 몇 번 누르세요.

디버그 분석

일반적으로 앱에서 기록한 이벤트는 약 1시간에 걸쳐 일괄 처리되어 함께 업로드됩니다. 이 접근 방식은 최종 사용자 장치의 배터리를 절약하고 네트워크 데이터 사용량을 줄입니다. 그러나 분석 구현을 검증하기 위해(그리고 DebugView 보고서에서 분석을 보기 위해) 개발 장치에서 디버그 모드를 활성화하여 최소한의 지연으로 이벤트를 업로드할 수 있습니다.

Android 장치에서 Analytics 디버그 모드를 활성화하려면 다음 명령을 실행하십시오.

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

앱을 다시 실행하고 숫자를 그립니다. 추론이 정확했다는 피드백을 보내려면 "예" 버튼을 몇 번 누르세요. 이제 Firebase 콘솔의 디버그 보기를 통해 거의 실시간으로 로그 이벤트를 볼 수 있습니다. 왼쪽 탐색 모음에서 Analytics > DebugView를 클릭합니다.

5276199a086721fd.png

11. 모델 성능 분석

Firebase 성능 모니터링은 iOS, Android, 웹 앱의 성능 특성을 파악하는 데 도움이 되는 서비스입니다.

Performance Monitoring SDK를 사용하여 앱에서 성능 데이터를 수집한 다음 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() 함수에서 새 downloadTrace를 생성하고 모델을 다운로드하기 직전에 시작합니다. 그런 다음 추적을 중지하는 onsuccess 리스너를 추가하세요.

classifyDrawing() 함수에서 새로운 classifyTrace를 생성하고 분류 직전에 시작합니다. 그런 다음 onsuccess 리스너에서 추적을 중지합니다.

메인액티비티.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. 다음과 같이 앱의 AndroidManifest.xml 파일에 <meta-data> 요소를 추가하여 빌드 시 성능 모니터링에 대한 디버그 로깅을 활성화합니다.

AndroidManifest.xml

<application>
    <meta-data
      android:name="firebase_performance_logcat_enabled"
      android:value="true" />
</application>
  1. 오류 메시지가 있는지 로그 메시지를 확인하세요.
  2. Performance Monitoring은 로그 메시지에 FirebasePerformance 태그를 지정합니다. logcat 필터링을 사용하면 다음 명령을 실행하여 기간 추적 및 HTTP/S 네트워크 요청 로깅을 구체적으로 볼 수 있습니다.
adb logcat -s FirebasePerformance
  1. Performance Monitoring이 성능 이벤트를 기록하고 있음을 나타내는 다음 유형의 로그를 확인하세요.
  • Logging TraceMetric
  • Logging NetworkRequestMetric

12. Firebase ML에 두 번째 모델 배포

더 나은 모델 아키텍처를 갖춘 모델이나 더 크거나 업데이트된 데이터세트로 훈련된 모델 등 새 모델 버전이 나올 때 현재 모델을 새 버전으로 교체하고 싶은 유혹을 느낄 수 있습니다. 그러나 테스트에서 잘 수행되는 모델이 반드시 프로덕션에서도 똑같이 잘 수행되는 것은 아닙니다. 따라서 실제 모델과 새 모델을 비교하기 위해 프로덕션 환경에서 A/B 테스트를 수행해 보겠습니다.

Firebase 모델 관리 API 활성화

이 단계에서는 Firebase 모델 관리 API를 활성화하여 Python 코드를 사용하여 TensorFlow Lite 모델의 새 버전을 배포합니다.

ML 모델을 저장할 버킷 만들기

Firebase 콘솔에서 Storage로 이동하여 시작하기를 클릭하세요. fbbea78f0eb3dc9f.png

대화 상자에 따라 버킷을 설정하세요.

19517c0d6d2aa14d.png

Firebase ML API 활성화

Google Cloud Console의 Firebase ML API 페이지 로 이동하여 활성화를 클릭합니다.

2414fd5cced6c984.png 질문이 나타나면 Digit Classifier 앱을 선택하세요.

새 모델 학습 및 Firebase ML에 게시

이제 더 큰 데이터 세트를 사용하여 새 버전의 모델을 훈련한 다음 Firebase Admin SDK를 사용하여 훈련 노트북에서 직접 프로그래밍 방식으로 배포하겠습니다.

서비스 계정의 비공개 키 다운로드

Firebase Admin SDK를 사용하려면 먼저 서비스 계정을 만들어야 합니다. 이 링크를 클릭하여 Firebase 콘솔의 서비스 계정 패널을 열고 버튼을 클릭하여 Firebase Admin SDK에 대한 새 서비스 계정을 만듭니다. 메시지가 표시되면 새 개인 키 생성 버튼을 클릭합니다. Colab 노트북의 요청을 인증하기 위해 서비스 계정 키를 사용하겠습니다.

c3b95de1e5508516.png

이제 새 모델을 훈련하고 배포할 수 있습니다.

  1. Colab 노트북을 열고 내 드라이브에 사본을 만들어 보세요.
  2. 왼쪽에 있는 재생 버튼을 클릭하여 첫 번째 셀 "개선된 TensorFlow Lite 모델 학습"을 실행합니다. 새 모델을 훈련시키므로 시간이 좀 걸릴 수 있습니다.
  3. 두 번째 셀을 실행하면 파일 업로드 프롬프트가 생성됩니다. 서비스 계정을 생성할 때 Firebase 콘솔에서 다운로드한 json 파일을 업로드하세요.

71e847c6a85423b3.png

  1. 마지막 두 셀을 실행합니다.

Colab 노트북을 실행한 후 Firebase 콘솔에 두 번째 모델이 표시됩니다. 두 번째 모델의 이름이 mnist_v2 인지 확인하세요.

c316683bb4d75d57.png

13. 원격 구성을 통해 모델 선택

이제 두 개의 별도 모델이 있으므로 런타임에 다운로드할 모델을 선택하기 위한 매개변수를 추가하겠습니다. 클라이언트가 수신하는 매개변수 값에 따라 클라이언트가 다운로드하는 모델이 결정됩니다.

Firebase 콘솔에 구성 규칙 추가

먼저, Firebase 콘솔을 열고 왼쪽 탐색 메뉴에서 원격 구성 버튼을 클릭하세요. 그런 다음 "매개변수 추가" 버튼을 클릭하세요.

새 매개변수의 이름을 model_name 지정하고 기본값 "mnist_v1" 을 지정합니다. 원격 구성 매개변수에 모델 이름을 입력하면 테스트하려는 모든 모델에 대해 새 매개변수를 추가하지 않고도 여러 모델을 테스트할 수 있습니다. 업데이트를 적용하려면 변경 사항 게시를 클릭하세요.

2949cb95c7214ca4.png

Firebase RemoteConfig 종속성 추가

앱/build.gradle.kts

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

Firebase 원격 구성 구성

메인액티비티.kt

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

구성 요청 및 사용

구성에 대한 가져오기 요청을 생성하고 완료 핸들러를 추가하여 구성 매개변수를 선택하고 사용합니다.

메인액티비티.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 모델이 다운로드되었다는 Toast 메시지가 표시되는지 확인하세요.
  3. Firebase 콘솔로 돌아가 기본값을 mnist_v2로 변경하고 변경 사항 게시를 선택하여 업데이트를 적용합니다.
  4. 앱을 다시 시작하고 이번에는 mnist_v2 모델이 다운로드되었다는 Toast 메시지를 확인해보세요.

14. A/B 테스트 모델 효율성

Firebase A/B 테스팅은 제품 및 마케팅 실험을 쉽게 실행, 분석, 확장하여 앱 환경을 최적화하는 데 도움이 됩니다. 마지막으로 Firebase에 내장된 A/B 테스팅 동작을 사용하여 두 모델 중 어느 모델이 더 나은 성능을 발휘하는지 확인할 수 있습니다.

Firebase 콘솔에서 Analytics -> 이벤트로 이동합니다. correct_inference 이벤트가 표시되면 "전환 이벤트"로 표시하고, 그렇지 않으면 Analytics -> 전환 이벤트로 이동하여 "새 전환 이벤트 생성"을 클릭하고 correct_inference.

이제 Firebase 콘솔의 "원격 구성"으로 이동하여 방금 추가한 "model_name" 매개변수의 추가 옵션 메뉴에서 "A/B 테스트" 버튼을 선택하세요.

fad5ea36969d2aeb.png

다음 메뉴에서 기본 이름을 그대로 적용합니다.

d7c006669ace6e40.png

드롭다운에서 앱을 선택하고 타겟팅 기준을 활성 사용자의 50%로 변경합니다.

cb72dcc7d2666bd3.png

이전에 correct_inference 이벤트를 전환으로 설정할 수 있었다면 이 이벤트를 추적할 기본 측정항목으로 사용하세요. 그렇지 않고 이벤트가 Analytics에 표시될 때까지 기다리지 않으려면 correct_inference manually 추가할 수 있습니다.

1ac9c94fb3159271.png

마지막으로 Variants 화면에서 mnist_v1 사용하도록 제어 그룹 변형을 설정하고 mnist_v2 사용하도록 변형 A 그룹을 설정합니다.

e4510434f8da31b6.png

오른쪽 하단에 있는 검토 버튼을 클릭하세요.

축하합니다. 두 개의 개별 모델에 대한 A/B 테스트를 성공적으로 만들었습니다! A/B 테스트는 현재 초안 상태이며 '실험 시작' 버튼을 클릭하면 언제든지 시작할 수 있습니다.

A/B 테스트에 대해 자세히 알아보려면 A/B 테스트 문서를 확인하세요.

15. 축하합니다!

이 Codelab에서는 앱의 정적으로 번들된 tflite 애셋을 Firebase에서 동적으로 로드된 TFLite 모델로 바꾸는 방법을 배웠습니다. TFLite 및 Firebase에 대해 자세히 알아보려면 다른 TFLite 샘플과 Firebase 시작 가이드를 살펴보세요.

우리가 다룬 내용

  • 텐서플로우 라이트
  • 파이어베이스 ML
  • Firebase 분석
  • Firebase 성능 모니터링
  • Firebase 원격 구성
  • Firebase A/B 테스팅

다음 단계

  • 앱에 Firebase ML 배포를 구현합니다.

더 알아보기

질문이 있습니다?

문제 보고