iOS에서 TensorFlow Lite로 꽃 인식

1. 소개

657431be3173fa86.png

TensorFlow는 다목적 머신러닝 프레임워크입니다. TensorFlow는 클라우드의 클러스터 전반에서 대규모 모델을 학습시키거나 휴대전화와 같은 임베디드 시스템에서 로컬로 모델을 실행하는 데 이르기까지 어디서나 사용할 수 있습니다.

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

학습 내용

  • TFLite 변환기를 사용하여 모델을 최적화하는 방법
  • TFLite 인터프리터를 사용하여 사전 제작된 iOS 앱에서 실행하는 방법

빌드할 항목

TensorFlow 영상 인식 프로그램을 실행하여 꽃을 식별하는 간단한 카메라 앱

기본 요건

자체 하드웨어에서 이 Codelab을 실행하는 경우 다음이 설치되어 있는지 확인하세요.

  • Xcode 10 이상
  • CocoaPods 1.8.0 이상

c45ecd122998622e.png

라이선스: 무료 사용

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

이 Codelab에서는 Colaboratory와 Xcode를 사용합니다.

TensorFlow Lite Model Maker를 사용하여 전이 학습을 통해 꽃을 인식하도록 분류기를 학습시키고 모바일 앱에서 사용할 TFLite 모델을 내보내는 Colab을 엽니다.

3. 작업 디렉터리 설정

Git 저장소 클론

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

git clone https://github.com/tensorflow/examples.git

이제 방금 만든 클론의 Xcode 프로젝트 루트로 cd합니다. 이 Codelab의 나머지 부분은 여기서 작업하게 됩니다.

cd examples/lite/examples/image_classification/ios

4. iOS 앱 설정

종속 항목 설치

CocoaPods를 사용하여 iOS 앱의 종속 항목 (TensorFlow Lite 포함)을 설치합니다. 설치 명령어가 완료되면 ImageClassification.xcworkspace를 열어 Xcode에서 프로젝트를 엽니다.

pod install --repo-update
open ImageClassification.xcworkspace

5. 앱 테스트 실행

카메라를 사용하려면 앱이 실제 기기에서 실행되어야 합니다. iOS 시뮬레이터는 Mac의 카메라에 액세스할 수 없기 때문입니다. iOS 기기에 빌드하려면 Apple Developer Program에 등록하거나 다른 사람이 프로비저닝한 기기에 액세스할 수 있어야 합니다.

시뮬레이터에서 이 Codelab을 실행하려면 시뮬레이터 자체의 Safari에서 이미지를 복사하여 페이스트보드로 보내야 합니다. 시뮬레이터에서 이미지를 처리하는 단계는 다음과 같습니다.

  1. 원하는 시뮬레이터 대상에 앱을 빌드합니다.
  2. iOS 시뮬레이터에서 Cmd+Shift+H를 눌러 앱을 최소화합니다.
  3. 홈 화면 하단의 Safari를 탭하고 이미지를 검색합니다.
  4. Google 이미지 검색결과에서 결과를 탭하고 이미지를 길게 누릅니다. 팝업 대화상자에서 '복사'를 선택합니다.
  5. TFL Classify 앱으로 돌아갑니다. 복사된 이미지는 추론 결과와 함께 자동으로 표시됩니다. 복사되지 않는 경우 이미지의 URL이 아닌 이미지 데이터 자체를 복사했는지 확인합니다.

앱 빌드 및 설치 테스트

앱을 변경하기 전에 저장소와 함께 제공되는 버전을 실행해 보겠습니다. 왼쪽 상단 드롭다운 메뉴에서 사용 중인 iOS 기기를 선택합니다.

275753d3a77a0df3.png

그런 다음 Cmd+R을 누르거나 Xcode에서 재생 f96cf117245c0fa6.png 버튼을 눌러 기기에 앱을 빌드합니다. 기기에 앱을 설치하면 앱이 자동으로 실행됩니다.

이 버전의 앱은 1, 000개의 ImageNet 카테고리에 대해 선행 학습된 표준 MobileNet을 사용합니다. 예를 들면 다음과 같습니다.

d11436f0bb5a75db.jpeg

6. 맞춤설정된 앱 실행

기본 앱 설정은 표준 MobileNet을 사용하여 이미지를 1, 000개의 ImageNet 클래스 중 하나로 분류합니다.

이제 앱이 Colab에서 학습된 커스텀 이미지 카테고리에 다시 학습된 모델을 사용하도록 앱을 수정해 보겠습니다.

7. 모델을 실행하도록 앱 변환

모델 파일을 프로젝트에 추가

프로젝트의 모델 리소스는 Xcode 프로젝트 탐색기의 ImageClassification > Model에 있습니다. 이 파일을 바꾸려면 먼저 Model 그룹에서 기존 파일 두 개를 삭제합니다. 메시지가 표시되면 '휴지통으로 이동'을 선택합니다.

cf2f7fefb2e5075f.png

그런 다음 Colab에서 다운로드한 model.tflitelabels.txt 파일을 모델 그룹으로 드래그합니다. 메시지가 표시되면 Copy items if neededAdd to targets이 모두 선택되어 있는지 확인합니다.

281d7eb72635bb5f.png

앱 코드 수정

앱이 작동하도록 하려면 추가한 새 모델을 가리키도록 모델 로드 로직의 경로를 업데이트해야 합니다.

ModelDataHandler.swift (Xcode 탐색기 경로: ImageClassification -> ModelDataHandler -> ModelDataHandler.swift)를 열고 36번 줄

// before
static let modelInfo: FileInfo = (name: "mobilenet_quant_v1_224", extension: "tflite")

// after
static let modelInfo: FileInfo = (name: "model", extension: "tflite")

모든 변경사항을 저장해야 합니다.

8. 맞춤설정된 앱 실행

Cmd+B를 누르거나 Xcode에서 재생 f96cf117245c0fa6.png 버튼을 눌러 기기에 앱을 빌드합니다. 앱이 실행되면 다음과 같이 표시됩니다.

c45ecd122998622e.png

전원 버튼과 볼륨 업 버튼을 동시에 누르면 스크린샷을 찍을 수 있습니다.

이제 웹에서 꽃을 검색해 보고 카메라를 컴퓨터 화면으로 향하게 하여 사진이 정확하게 분류되는지 확인하세요.

아니면 친구에게 내 사진을 찍어 달라고 하고 \\uf339 \\uf33b \\uf337 어떤 종류의 TensorFlower인지 확인해 보세요.

9. 기본 원리

이제 앱을 실행했으므로 TensorFlow Lite 관련 코드를 살펴보겠습니다.

TensorFlowLiteSwift

이 앱은 CocoaPods를 통해 TensorFlowLite Swift 라이브러리를 사용합니다. Swift 라이브러리는 TFLite C API의 씬 래퍼로, 그 자체가 TFLite C++ 라이브러리의 래퍼입니다.

모듈의 Podfile 파일에서 다음 줄은 최신 버전의 포드 전역 CocoaPods 사양 저장소를 프로젝트로 가져옵니다.

Podfile

target 'ImageClassification' do
  use_frameworks!

  # Pods for ImageClassification
   pod 'TensorFlowLiteSwift'
end

TensorFlow Lite Swift API 사용

TensorFlow Lite와 상호작용하는 코드는 모두 ModelDataHandler.swift에 포함되어 있습니다.

설정

첫 번째로 살펴볼 블록은 ModelDataHandler의 이니셜라이저입니다.

ModelDataHandler.swift

/// A failable initializer for `ModelDataHandler`. A new instance is created if the model and
/// labels files are successfully loaded from the app's main bundle. Default `threadCount` is 1.
init?(modelFileInfo: FileInfo, labelsFileInfo: FileInfo, threadCount: Int = 1) {
  let modelFilename = modelFileInfo.name

  // Construct the path to the model file.
  guard let modelPath = Bundle.main.path(
    forResource: modelFilename,
    ofType: modelFileInfo.extension
  ) else {
    print("Failed to load the model file with name: \(modelFilename).")
    return nil
  }

  // Specify the options for the `Interpreter`.
  self.threadCount = threadCount
  var options = InterpreterOptions()
  options.threadCount = threadCount
  do {
    // Create the `Interpreter`.
    interpreter = try Interpreter(modelPath: modelPath, options: options)
    // Allocate memory for the model's input `Tensor`s.
    try interpreter.allocateTensors()
  } catch let error {
    print("Failed to create the interpreter with error: \(error.localizedDescription)")
    return nil
  }
  // Load the classes listed in the labels file.
  loadLabels(fileInfo: labelsFileInfo)
}

좀 더 자세히 다루어야 할 사항이 몇 가지 있습니다.

다음 줄은 TFLite 인터프리터를 생성합니다.

ModelDataHandler.swift

interpreter = try Interpreter(modelPath: modelPath, options: options)

인터프리터는 TensorFlow 그래프를 통해 원시 데이터 입력을 전달합니다. 우리가 인터프리터에 디스크에 있는 모델 경로를 전달하면 인터프리터는 이를 FlatBufferModel로 로드합니다.

마지막 줄은 라벨 목록을 로드합니다.

loadLabels(fileInfo: labelsFileInfo)

이 작업은 텍스트 파일에서 메모리로 문자열을 로드합니다.

모델 실행

두 번째로 살펴볼 블록은 runModel 메서드입니다. CVPixelBuffer를 입력으로 사용하고 인터프리터를 실행하고 앱에서 인쇄할 텍스트를 반환합니다.

ModelDataHandler.swift

try interpreter.copy(rgbData, toInputAt: 0)
// ...
try interpreter.invoke()
// ...
outputTensor = try interpreter.output(at: 0)

10. 다음 단계

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