앱에 커스텀 모델 통합

1. 시작하기 전에

이 시리즈의 첫 번째 Codelab에서는 이미지 라벨링을 사용하여 이미지의 콘텐츠를 파싱하는 매우 간단한 앱을 만들었습니다. 데이지 사진을 보냈는데 꽃이 피었습니다. 그런 다음 두 번째 Codelab에서는 Python으로 전환하여 5가지 유형의 꽃을 인식하는 새로운 커스텀 모델을 학습시켰습니다.

이 Codelab에서는 첫 번째 실습의 앱을 두 번째 실습의 모델로 업데이트합니다.

클론하여 이 Codelab의 전체 소스 코드를 가져올 수 있습니다.이거 저장소 Android 및 iOS의 하위 디렉터리가 표시됩니다. 계속 진행하려면 이전 Codelab의 코드를 ImageClassifierStep1로 확인할 수 있습니다. 이 Codelab의 완성된 코드는 ImageClassifierStep2로 제공합니다.

기본 요건

  • 이 학습 과정의 처음 두 Codelab을 완료해야 합니다.

빌드하고 학습할 내용

  • 이전 실습에서 학습한 커스텀 모델을 Android 또는 iOS 앱에 통합

준비물

  • Android 스튜디오(developer.android.com/studio에서 실습용 Android 부분 사용 가능)
  • Apple App Store에서 제공되는 iOS 실습용 Xcode

2 시작 앱 다운로드

먼저 Android 또는 iOS Codelab에서 첫 번째 컴퓨터 비전 앱 빌드의 앱이 필요합니다. 실습을 진행한 경우 ImageClassifierStep1이라고 합니다. 실습을 진행하지 않으려면 저장소에서 완료된 버전을 클론하세요.

Android 스튜디오에서 앱을 열고 필요한 업데이트를 실행한 후 앱이 준비되면 앱을 실행하여 작동하는지 확인합니다. 다음과 같이 표시됩니다.

f3703d45d1332d1d.png

이 앱은 프리미티브 앱이지만 적은 코드로 아주 강력한 기능을 보여줍니다. 그러나 이 꽃이 꽃이 아니라 데이지로 인식되도록 하려면 이미지 분류기를 위한 맞춤 모델 만들기에서 맞춤 모델을 사용하도록 앱을 업데이트해야 합니다.

3. 커스텀 ML Kit 모델을 사용하도록 build.gradle 업데이트

  1. Android 스튜디오를 사용하여 앱 수준 build.gradle 파일을 찾습니다. 가장 쉬운 방법은 프로젝트 탐색기를 사용하는 것입니다. 상단에서 Android가 선택되어 있고 하단에 Gradle Scripts 폴더가 있는지 확인합니다.
  2. 다음과 같이 앱 모듈 뒤에 '.app'을 붙여 Module에 해당하는 모듈을 엽니다.(Module: ImageClassifierStep1.app)

8fe1d04b40610047.png

  1. 파일 하단에서 종속 항목 설정을 찾습니다. 다음과 같은 줄이 표시됩니다.
implementation 'com.google.mlkit:image-labeling:17.0.1'

버전 번호가 다를 수 있습니다. ML Kit 사이트에서 항상 최신 버전 번호를 찾습니다. https://developers.google.com/ml-kit/vision/image-labeling/android

  1. 커스텀 이미지 라벨 지정 라이브러리 참조로 이 부분을 대체합니다. 이에 관한 버전 번호는 https://developers.google.com/ml-kit/vision/image-labeling/custom-models/android에서 확인할 수 있습니다.
implementation 'com.google.mlkit:image-labeling-custom:16.3.1'
  1. 또한 이전 실습에서 만든 .tflite 모델도 추가합니다. Android 스튜디오가 앱을 컴파일할 때는 이 모델을 압축하지 않기를 바랍니다. 동일한 build.gradle 파일의 Android 섹션에서 이 설정을 사용해야 합니다.
aaptOptions{
    noCompress "tflite"
}

다른 설정 내에 있지 않은지 확인하세요. android 태그 바로 아래에 중첩되어야 합니다. 다음 예를 참고하세요.

62d546bff11d2a50.png

4. TFLite 모델 추가

이전 Codelab에서는 커스텀 모델을 만들고 model.tflite로 다운로드했습니다.

프로젝트에서 현재 flower1.jpg가 포함된 assets 폴더를 찾습니다. 다음과 같이 모델을 폴더에 복사합니다.

  1. Android 스튜디오에서 Assets 폴더를 마우스 오른쪽 버튼으로 클릭합니다. 메뉴가 열리면 Finder에서 보기를 선택합니다. Windows에서는 ' Explorer에 표시', Linux에서는 '파일에 표시'가 표시됩니다.

db30b47e419a326b.png

  1. 파일 시스템의 디렉터리로 이동합니다. model.tflite 파일을 flower1.jpg.와 함께 이 디렉터리에 복사합니다.

36de0c51bec1c19e.png

Android 스튜디오가 업데이트되어 애셋 폴더에 두 파일이 모두 표시됩니다.

e9f4e9f394d9b357.png

이제 코드를 업데이트할 준비가 되었습니다.

5 커스텀 모델 코드 업데이트

첫 번째 단계는 커스텀 모델을 로드하는 코드를 추가하는 것입니다.

  1. MainActivity 파일에서 setContentView(R.layout.activity_main)라는 줄 바로 아래에 있는 onCreate에 다음을 추가합니다.

이렇게 하면 LocalModel을 사용하여 model.tflite 애셋으로 빌드할 수 있습니다. Android 스튜디오에서 'LocalModel'을 빨간색으로 전환하여 문제가 발생하는 경우 Alt + Enter를 눌러 라이브러리를 가져옵니다. 이렇게 하면 com.google.mlkit.common.model.LocalModel에 가져오기가 추가됩니다.

val localModel = LocalModel.Builder()
        .setAssetFilePath("model.tflite")
        .build()

이전에는 btn.setOnClickListener 핸들러에서 기본 모델을 사용했습니다. 다음 코드로 설정되었습니다.

val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)

커스텀 모델을 사용하도록 바꿉니다.

  1. 맞춤 옵션 객체를 설정하려면 다음 안내를 따르세요.
val options = CustomImageLabelerOptions.Builder(localModel)
        .setConfidenceThreshold(0.7f)
        .setMaxResultCount(5)
        .build()

기본 옵션이 맞춤설정된 세트로 대체됩니다. 신뢰도 임곗값은 반환할 예측 품질의 기준을 설정합니다. 이 Codelab에서 이미지가 데이지인 데 대한 샘플을 다시 살펴보면 4개의 예측이 있으며, 각 예측 옆에는 'Sky'와 같은 값이 있습니다.

신뢰도 임곗값을 사용하면 품질이 낮은 결과를 효과적으로 필터링할 수 있습니다. 예를 들어 이 속성을 0.9로 설정하면 우선순위가 이보다 낮은 라벨은 반환되지 않습니다. setMaxResultCount()는 클래스가 많은 모델에 유용하지만 이 모델은 5개만 있으므로 이 모델을 5로 두면 됩니다.

이제 라벨러 옵션을 만들 수 있으므로 라벨러의 인스턴스화를 다음과 같이 변경할 수 있습니다.

val labeler = ImageLabeling.getClient(options)

나머지 코드는 수정하지 않고 실행됩니다. 한번 사용해 보세요.

dd40c36c4edbb33.png

이제 이 꽃이 .959 확률로 데이지로 식별된 것을 확인할 수 있습니다.

두 번째 꽃 이미지를 추가하고 다음과 같이 다시 실행했다고 가정해 보겠습니다.

8556a5fbea487842.png

장미로 식별합니다.

단순히 '장미'가 아닌 장미라고 표시된 이유를 궁금해할 수 있습니다. 이는 데이터 세트에서 라벨이 폴더 이름으로 지정되기 때문입니다. 그리고 폴더 이름에는 약간 일관되지 않으므로 'dasy'(단수형)와 복수형 (예: 'dasy')이 사용되기도 합니다. 이미지에 있는 항목을 집계하는 모델과 혼동하지 마세요. 이보다 더 기본적이고 꽃 유형만 식별할 수 있습니다.

6. iOS 시작 앱 다운로드

  1. 먼저 첫 번째 Codelab의 앱이 필요합니다. 실습을 진행한 경우 ImageClassifierStep1이라고 합니다. 실습을 진행하지 않으려면 저장소에서 완료된 버전을 클론하면 됩니다. pod와 .xcworkspace는 저장소에 없으므로 다음 단계로 진행하기 전에 .xcproject와 같은 디렉터리에서'pod install'을 실행해야 합니다.
  2. Xcode에서 ImageClassifierStep1.xcworkspace을 엽니다. pod를 사용하여 ML Kit를 번들로 제공하므로 .xcproject가 아닌 .xcworkspace를 사용해야 하며, 작업공간은 이를 로드합니다.

이 실습의 나머지 부분에서는 Codelab의 빌드 타겟을 지원하는 iPhone 시뮬레이터에서 앱을 실행합니다. 본인의 기기를 사용하려면 iOS 버전과 일치하도록 프로젝트 설정에서 빌드 타겟을 변경해야 할 수도 있습니다.

카드를 실행하면 다음과 같이 표시됩니다.

9e151ed18f99fb98.png

매우 일반적인 분류(페탈, 꽃, 하늘)에 유의하세요. 이전 Codelab에서 만든 모델은 데이지 꽃을 비롯해 5가지 꽃을 감지하도록 학습되었습니다.

이 Codelab의 나머지 부분에서는 커스텀 모델로 앱을 업그레이드하는 데 필요한 사항을 알아봅니다.

7 커스텀 ML Kit 이미지 레이블러 포드 사용

첫 번째 앱은 포드 파일을 사용하여 기본 ML Kit 이미지 라벨러 라이브러리와 모델을 가져왔습니다. 커스텀 이미지 라벨 지정 라이브러리를 사용하려면 업데이트해야 합니다.

  1. 프로젝트 디렉터리에서 podfile라는 파일을 찾습니다. 카드를 열면 다음과 같이 표시됩니다.
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabeling'
end
  1. 다음과 같이 pod 선언을 ImageLabeling에서 ImageLabelingCustom로 변경합니다.
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabelingCustom'
end
  1. 작업을 마친 후에는 터미널을 사용하여 podfile(.xcworkspace 포함)이 포함된 디렉터리로 이동하고 pod install를 실행합니다.

bb5d78eb7c7ab975.png

잠시 후 MLKitImageLabeling 라이브러리가 삭제되고 맞춤 라이브러리가 추가됩니다. 이제 .xcworkspace를 열어 코드를 수정할 수 있습니다.

8 Xcode에 TFLite 모델 추가

이전 Codelab에서는 커스텀 모델을 만들고 model.tflite로 다운로드했습니다. 아직 코드가 없다면 뒤로 돌아가 Codelab을 실행하거나 여기에서 colab 코드를 살펴봅니다. Google Colab에 액세스할 수 없는 경우 노트북을 이 링크에서 확인할 수 있습니다.

  1. Xcode에서 작업공간을 연 상태에서 model.tflite를 프로젝트로 드래그합니다. 이 파일은 ViewController.swift 또는 Main.storyboard와 같은 나머지 파일과 같은 폴더에 있어야 합니다.
  2. 파일을 추가하는 옵션이 포함된 대화상자가 나타납니다. 대상에 추가를 선택하거나 모델이 기기에 배포될 때 앱과 번들로 묶이지 않습니다.

참고로 여기서 시작하여 단계별 실습을 진행하는 경우 'Add to Targets' 항목에 ImageClassifierStep1이 표시되며 완성된 코드로 건너뛰면 ImageClassifierStep2를 계속 진행할 수 있습니다.

5b6a7f40c73f0f1f.png

그러면 모델을 로드할 수 있습니다. 다음 단계에서 방법을 알아봅니다.

9. 커스텀 모델 코드 업데이트

  1. ViewController.swift 파일을 엽니다. 파일 상단에 'MLKitImageLabeling 가져오기'에 오류가 표시될 수 있습니다. 이는 포드 파일을 업데이트할 때 일반 이미지 라벨 지정 라이브러리를 삭제했기 때문입니다. 이 줄을 삭제하고 다음과 같이 업데이트할 수 있습니다.
import MLKitVision
import MLKit
import MLKitImageLabelingCommon
import MLKitImageLabelingCustom

내용을 빠르게 읽고 동일한 코드를 반복한다고 생각하기 쉽습니다. 하지만 '일반' 및 '맞춤'이 마지막에 나와 있습니다.

  1. 다음으로 이전 단계에서 추가한 커스텀 모델을 로드합니다. getLabels() 함수를 찾습니다. visionImage.orientation = image.imageOrientation 줄 아래에 다음을 추가합니다.
// Add this code to use a custom model
let localModelFilePath = Bundle.main.path(forResource: "model", ofType: "tflite")
let localModel = LocalModel(path: localModelFilePath!)
  1. 일반 ImageLabeler 옵션을 지정하는 코드를 찾습니다. 라이브러리가 삭제되었을 때 오류가 발생할 수 있습니다.
let options = ImageLabelerOptions()

이 코드를 다음으로 바꿔 CustomImageLabelerOptions를 사용하고 로컬 모델을 지정하는 방법을 알아봅니다.

let options = CustomImageLabelerOptions(localModel: localModel)

끝났습니다. 지금 앱을 실행해 보세요. 이미지를 분류하려고 하면 더 정확해집니다. 그리고 확률이 높은 데이지를 보고 있다고 말해보세요.

238cd21748a97cf4.png

두 번째 꽃 이미지를 추가하고 다음과 같이 다시 실행했다고 가정해 보겠습니다.

75f3970a6b509bfe.png

앱에서 이 이미지가 '장미' 라벨과 일치하는지 감지했습니다.

10. 축하합니다.

이제 일반 모델을 사용하여 이미지 콘텐츠를 인식하는 앱을 빌드하고 꽃과 같은 특정 항목을 인식하는 자체 ML 모델을 만든 다음 커스텀 모델을 사용하도록 앱을 업데이트했습니다.

물론 결과적으로 앱이 번들 이미지 애셋에 의존하기 때문에 매우 제한됩니다. 하지만 ML 부분이 제대로 작동하고 있습니다. 예를 들어 AndroidX 카메라를 사용하여 실시간 피드에서 프레임을 가져와 분류하고 휴대전화가 인식하는 꽃을 찾을 수 있습니다.

여기서 가능성은 무한합니다. 꽃이 아닌 다른 것에 관한 나만의 데이터가 있다면 컴퓨터 비전을 사용해 이들을 인식하는 앱을 빌드하는 데 필요한 기초가 마련됩니다. 이는 더 광범위한 세상으로의 첫걸음을 내딛은 것이며, 여러분과 함께 즐거운 시간을 보내셨기를 바랍니다.