Android에서 TensorFlow Lite로 꽃 인식

1. 소개

657431be3173fa86.png android.png

참고: 이 Codelab에서는 테스트를 위해 실제 기기가 필요합니다.

TensorFlow는 다목적 머신러닝 프레임워크입니다. TensorFlow는 클라우드의 클러스터 전반에서 대규모 모델을 학습하고 스마트폰과 같은 임베디드 시스템에서 로컬로 모델을 실행하는 데 사용할 수 있습니다.

이 Codelab에서는 TensorFlow Lite를 사용하여 Android 기기에서 이미지 인식 모델을 실행합니다.

Android 스튜디오 4.1 이상 설치

아직 설치하지 않았다면 TensorFlow Lite 모델을 학습하는 동안 Android 스튜디오 4.1 이상을 다운로드하고 설치하세요.

학습할 내용

  • TensorFlow Lite Model Maker를 사용하여 자체 맞춤 이미지 분류기를 학습하는 방법
  • Android 스튜디오를 사용하여 TensorFlow Lite 모델을 가져와 CameraX를 사용하여 Android 앱에 맞춤 모델을 통합하는 방법
  • 휴대전화에서 GPU를 사용하여 모델을 가속화하는 방법

빌드 대상

TensorFlow 이미지 인식 프로그램을 실행하여 꽃을 식별하는 간단한 카메라 앱입니다.

f11c2821f2c8311d.png

라이선스: 무료로 사용

2. Colab을 사용하여 꽃 인식기 학습

모델 학습을 시작하기 전에 Android 스튜디오 4.1 이상을 다운로드하고 설치하세요.

TensorFlow Lite 전이 학습을 사용하여 꽃을 인식하도록 Keras로 분류기를 학습하는 방법을 보여주는 Colab을 엽니다.

3. 작업 디렉터리 설정

Git 저장소 클론

다음 명령어는 이 Codelab에 필요한 파일이 포함된 Git 저장소를 클론합니다.

git clone https://github.com/hoitab/TFLClassify.git

그런 다음 방금 저장소를 클론한 디렉터리로 이동합니다. 여기에서 이 Codelab의 나머지 작업을 진행하게 됩니다.

cd TFLClassify

4. Android 스켈레톤 앱 설정

android.png

Android 스튜디오 4.1 이상 설치

아직 설치하지 않았다면 Android 스튜디오 4.1 이상을 설치하세요.

Android 스튜디오로 프로젝트 열기

다음 단계에 따라 Android 스튜디오로 프로젝트를 엽니다.

  1. Android 스튜디오 7f2480ded53a193b.png를 엽니다. 앱이 로드되면 다음 팝업에서 'Open an Existing project(기존 프로젝트 열기)'를 선택합니다.

f3b8bea7e3b39376.png

  1. 파일 선택기에서 작업 디렉터리의 TFLClassify/build.gradle을 선택합니다.
  1. 프로젝트를 처음 열면 Gradle 래퍼를 사용할지 묻는 'Gradle Sync(Gradle 동기화)' 팝업이 표시됩니다. '확인'을 클릭합니다.

d68b4d7189e6c1e4.png

  1. 아직 사용 설정하지 않은 경우 휴대전화에서 개발자 모델과 USB 디버깅을 사용 설정합니다. 이 작업은 일회성 설정입니다. 이 안내를 따르세요.
  2. 프로젝트와 휴대전화가 모두 준비되면 TFL_Classify.start을 선택하고 툴바에서 실행 버튼 86934b7b01ad7565.png을 눌러 실제 기기에서 실행할 수 있습니다.

60a77ef126c1373d.png

  1. 이제 TensorFlow 데모가 카메라에 액세스하도록 허용합니다.

b63cba02bb36b7e3.png

  1. 실제 결과가 표시될 위치에 임의의 숫자가 표시된 다음 화면이 휴대전화에 표시됩니다.

82c603596afa35f1.png

5. Android 앱에 TensorFlow Lite 추가

  1. 왼쪽의 프로젝트 탐색기에서 start 모듈을 선택합니다.

cede7f2b8b23c1a7.png

  1. start 모듈을 마우스 오른쪽 버튼으로 클릭하거나 File을 클릭한 다음 New > Other > TensorFlow Lite Model을 클릭합니다.

bf243d9fdd27e20a.png

  1. 이전에 맞춤 학습된 FlowerModel.tflite를 다운로드한 모델 위치를 선택합니다.

cfee18cc6674a408.png

  1. Finish를 클릭합니다.
  2. 다음이 끝에 표시됩니다. FlowerModel.tflite가 성공적으로 가져오기되었으며 입력 / 출력과 시작하는 데 도움이 되는 샘플 코드를 비롯한 모델에 관한 대략적인 정보가 표시됩니다.

82840065f0d59def.png

6. 선택사항: 모든 할 일 목록 확인

할 일 목록을 사용하면 Codelab을 업데이트해야 하는 정확한 위치로 쉽게 이동할 수 있습니다. Android 프로젝트에서 향후 작업을 상기시키는 데 사용할 수도 있습니다. 코드 주석을 사용하여 할 일 항목을 추가하고 TODO 키워드를 입력할 수 있습니다. 할 일 목록에 액세스하려면 다음을 실행하세요.

  1. 할 일 목록을 확인하면 앞으로 수행할 작업을 파악하는 데 도움이 됩니다. 이렇게 하려면 상단 메뉴바에서 View > Tool Windows > TODO를 선택합니다.

5de29b413574f25c.png

  1. 기본적으로 모든 모듈의 모든 할 일이 나열되므로 약간 혼동될 수 있습니다. 할 일 패널 측면에서 그룹화 기준 버튼을 클릭하고 Modules를 선택하여 시작 할 일만 정렬할 수 있습니다.

5d8fe7b102340208.png

  1. 시작 모듈 아래의 모든 항목을 펼칩니다.

8d0f14a039995b20.png

7. TensorFlow Lite로 맞춤 모델 실행

  1. 할 일 목록에서 할 일 1을 클릭하거나 MainActivity.kt 파일을 열고 할 일 1을 찾아 이 줄을 추가하여 모델을 초기화합니다.
private class ImageAnalyzer(ctx: Context, private val listener: RecognitionListener) :
        ImageAnalysis.Analyzer {

  ...
  // TODO 1: Add class variable TensorFlow Lite Model
  private val flowerModel = FlowerModel.newInstance(ctx)

  ...
}
  1. CameraX Analyzer의 analyze 메서드 내에서 카메라 입력 ImageProxyBitmap으로 변환하고 추론 프로세스를 위한 TensorImage 객체를 만들어야 합니다.
override fun analyze(imageProxy: ImageProxy) {
  ...
  // TODO 2: Convert Image to Bitmap then to TensorImage
  val tfImage = TensorImage.fromBitmap(toBitmap(imageProxy))
  ...
}

  1. 이미지를 처리하고 결과에 다음 작업을 실행합니다.
  • 확률이 가장 높은 순서대로 score 속성에서 확률을 기준으로 결과를 내림차순으로 정렬합니다.
  • 상수 MAX_RESULT_DISPLAY에 정의된 대로 상위 k개의 결과를 가져옵니다. 선택적으로 이 변수의 값을 변경하여 결과를 더 많이 또는 더 적게 가져올 수 있습니다.
override fun analyze(imageProxy: ImageProxy) {
  ...
  // TODO 3: Process the image using the trained model, sort and pick out the top results
  val outputs = flowerModel.process(tfImage)
      .probabilityAsCategoryList.apply {
          sortByDescending { it.score } // Sort with highest confidence first
      }.take(MAX_RESULT_DISPLAY) // take the top results

  ...
}
  1. 정렬되고 필터링된 결과를 Recognition 데이터 바인딩을 통해 RecyclerView 에서 사용할 수 있는 데이터 객체 Data Binding으로 변환합니다.
override fun analyze(imageProxy: ImageProxy) {
  ...
  // TODO 4: Converting the top probability items into a list of recognitions
  for (output in outputs) {
      items.add(Recognition(output.label, output.score))
  }
  ...
}
  1. 이전에 표시된 가짜 결과를 생성하는 데 도움이 되는 다음 줄을 주석 처리하거나 삭제합니다.
// START - Placeholder code at the start of the codelab. Comment this block of code out.
for (i in 0..MAX_RESULT_DISPLAY-1){
    items.add(Recognition("Fake label $i", Random.nextFloat()))
}
// END - Placeholder code at the start of the codelab. Comment this block of code out.
  1. TFL_Classify.start를 선택하고 툴바에서 실행 버튼 86934b7b01ad7565.png을 눌러 실제 기기에서 앱을 실행합니다.

60a77ef126c1373d.png

  1. 실제 결과가 표시될 위치에 임의의 숫자가 표시된 다음 화면이 휴대전화에 표시됩니다.

f11c2821f2c8311d.png

8. 선택사항: GPU 위임으로 추론 가속화

TensorFlow Lite는 휴대기기에서 추론 속도를 높이기 위해 여러 하드웨어 가속기를 지원합니다. GPU는 TensorFlow Lite가 위임 메커니즘을 통해 활용할 수 있는 가속기 중 하나이며 사용하기가 매우 쉽습니다.

  1. start 모듈에서 build.gradle 을 열거나 할 일 목록에서 할 일 5를 클릭하고 다음 종속 항목을 추가할 수 있습니다.
// TODO 5: Optional GPU Delegates    
implementation 'org.tensorflow:tensorflow-lite-gpu:2.3.0'
  1. MainActivity.kt 파일로 돌아가거나 할 일 목록에서 할 일 6을 클릭합니다. flowerModel의 간단한 시작을 다음으로 바꿉니다. GPU 호환성 목록의 인스턴스를 가져오고 나열된 호환 GPU 중 하나인지에 따라 GPU를 초기화합니다. 그렇지 않으면 모델을 실행하기 위해 4개의 CPU 스레드를 시작합니다.
private class ImageAnalyzer(ctx: Context, private val listener: RecognitionListener) :
        ImageAnalysis.Analyzer {
  ...

  // TODO 1: Add class variable TensorFlow Lite Model
  // Initializing the flowerModel by lazy so that it runs in the same thread when the process
  // method is called.
  private val flowerModel: FlowerModel by lazy{

    // TODO 6. Optional GPU acceleration
    val compatList = CompatibilityList()

    val options = if(compatList.isDelegateSupportedOnThisDevice){
        Log.d(TAG, "This device is GPU Compatible ")
        Model.Options.Builder().setDevice(Model.Device.GPU).build()
    } else {
        Log.d(TAG, "This device is GPU Incompatible ")
        Model.Options.Builder().setNumThreads(4).build()
    }

  ...
}
  1. 메서드 입력에 options를 추가하여 모델 이니셜라이저가 이를 사용하도록 변경합니다.
private class ImageAnalyzer(ctx: Context, private val listener: RecognitionListener) :
        ImageAnalysis.Analyzer {

  private val flowerModel: FlowerModel by lazy{

    ...

    // Initialize the Flower Model
    FlowerModel.newInstance(ctx, options)
  }
}

  1. TFL_Classify.start를 선택하고 툴바에서 실행 버튼 86934b7b01ad7565.png을 눌러 실제 기기에서 앱을 실행합니다.

60a77ef126c1373d.png

9. 다음 단계

자세한 내용은 다음 링크를 참고하세요.