yolov5 android studio kotlin 코드로 object detection

yolov5 object detection custom 학습 모델을 앱에 올리고 싶습니다.
그런데 pytorch(.pt)파일이 바로 올라가지 않고, tensorflow lite로 변환이 필요하더군요, 그래서 변환을 해서 올리는데 계속 에러가 나서 예측 결과를 얻을 수도 없어요... 어떻게 모델을 변환해야 결과를 받아볼 수 있을까요?

첫번째가 예시 tflite 모델이고,
두번째 사진이 제가 학습한 tflite 모델입니다.

첫번째 모델은 예측이 잘 되는데 제가 학습한 모델은 예측 하지 못하고 앱이 바로 죽어버려요. 위의 모델처럼 메타데이터를 추가하거나 모델을 다시 export.py하는 방법이 있을까요?

아래의 코드에서 result 변수로 결과를 받는 부분에서 계속에러가 나서 어떻게 해결해야할지 모르겠습니다. 해당 코드에서 발생하는 에러는

Error getting native address of native library: task_vision_jni
                                                                                                    java.lang.IllegalStateException: Error occurred when initializing ObjectDetector: AllocateTensors() failed.

입니다.

 private fun runObjectDetection(bitmap: Bitmap) {
        // Step 1: Create TFLite's TensorImage object
        val image = TensorImage.fromBitmap(bitmap)

        // Step 2: Initialize the detector object
        val options = ObjectDetector.ObjectDetectorOptions.builder()
                .setMaxResults(1)
                .setScoreThreshold(0.1f)
                .build()
        val detector = ObjectDetector.createFromFileAndOptions(
                this,
                "best-fp16-2.tflite",
                options
        )


        // Step 3: Feed given image to the detector
        val results = detector.detect(image)
}

image

  • 아래 답변은 OpenAI의 GPT-4 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요, Hong1270님. PyTorch 모델을 Android Studio에서 사용하려는 과정에서 어려움을 겪고 계시는 것 같네요. 질문을 정리해보면, yolov5로 학습한 custom object detection 모델을 Android 앱에 적용하려고 하는데, 이를 위해 PyTorch 모델을 TensorFlow Lite로 변환하는 과정에서 문제가 발생하고 있습니다. 특히, 변환된 모델을 앱에 적용하려 할 때 Error getting native address of native library: task_vision_jnijava.lang.IllegalStateException: Error occurred when initializing ObjectDetector: AllocateTensors() failed.라는 에러가 발생하고 있습니다.

먼저, PyTorch 모델을 TensorFlow Lite로 변환하는 것은 복잡하고 에러가 발생하기 쉬운 작업입니다. 그러나 PyTorch는 이제 Android와 iOS에서 직접 실행할 수 있는 모델을 생성하는 기능을 제공하고 있습니다. 따라서 TensorFlow Lite로의 변환 없이 PyTorch 모델을 직접 사용하는 것을 추천드립니다.

PyTorch 모델을 Android에서 사용하려면, 먼저 모델을 TorchScript로 변환해야 합니다. TorchScript는 PyTorch 모델을 직렬화하여 언어 독립적인 형태로 만들어주는 도구입니다. 이렇게 변환된 모델은 C++ 런타임에서 로드하여 사용할 수 있습니다. 이를 위해 torch.jit.trace 또는 torch.jit.script 메서드를 사용할 수 있습니다.

다음은 TorchScript로 모델을 변환하는 예제 코드입니다:

import torch
import torchvision

# An instance of your model.
model = torchvision.models.resnet18()

# An example input you would normally provide to your model's forward() method.
example = torch.rand(1, 3, 224, 224)

# Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing.
traced_script_module = torch.jit.trace(model, example)

traced_script_module.save("app/src/main/assets/model.pt")

위 코드를 실행하면 model.pt라는 이름의 TorchScript 모델이 생성됩니다. 이 파일을 Android 앱의 assets 폴더에 넣으면 됩니다.

그 다음으로는 Android 앱에서 PyTorch 모델을 로드하고 실행하는 코드를 작성해야 합니다. 이를 위해 PyTorch는 PyTorch Mobile을 제공하고 있습니다. PyTorch Mobile은 Android와 iOS에서 PyTorch 모델을 실행할 수 있게 해주는 라이브러리입니다.

다음은 PyTorch Mobile을 사용하여 모델을 로드하고 실행하는 예제 코드입니다:

import org.pytorch.IValue;
import org.pytorch.Module;
import org.pytorch.Tensor;
import org.pytorch.torchvision.TensorImageUtils;

// Load model
val module = Module.load(assetFilePath(this, "model.pt"))

// Prepare input tensor
val inputTensor = TensorImageUtils.bitmapToFloat32Tensor(bitmap)

// Run model
val outputTensor = module.forward(IValue.from(inputTensor)).toTensor()

// Get result
val scores = outputTensor.dataAsFloatArray

위 코드에서 bitmap은 입력 이미지를 나타내는 Bitmap 객체입니다. TensorImageUtils.bitmapToFloat32Tensor 메서드를 사용하여 이를 Tensor로 변환하고 있습니다. 그리고 module.forward 메서드를 사용하여 모델을 실행하고 있습니다.

이렇게 하면 TensorFlow Lite로의 변환 없이 PyTorch 모델을 Android 앱에서 직접 사용할 수 있습니다. PyTorch 모델을 Android에서 사용하는 더 자세한 내용은 PyTorch Mobile의 공식 문서를 참조해주세요.


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!
  • 아래 답변은 OpenAI의 GPT-3.5(ChatGPT) 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요 Hong1270님,

문제를 이해하기 위해 요약하자면, Hong1270님은 YOLOv5로 학습한 모델을 안드로이드 스튜디오 Kotlin 코드로 구현하여 객체 검출을 하려고 합니다. 그러나 PyTorch(.pt) 파일을 직접 사용할 수 없고 TensorFlow Lite로 변환해야 한다고 합니다. 변환 후에도 계속해서 오류가 발생하여 결과를 얻을 수 없다고 합니다. 모델을 어떻게 변환해야 결과를 얻을 수 있는지, 그리고 코드에서 발생하는 오류를 해결하는 방법을 알고 싶다고 합니다.

이 문제를 해결하기 위해 다음과 같은 접근 방법을 제안드립니다.

  1. PyTorch 모델을 TensorFlow Lite 모델로 변환하기
  2. 변환된 모델을 안드로이드 스튜디오에서 사용하기 위한 설정
  3. 코드에서 발생하는 오류 해결하기

첫 번째로, PyTorch 모델을 TensorFlow Lite 모델로 변환해야 합니다. 이를 위해서는 ONNX 형식으로 모델을 내보내고, 그 후에 TensorFlow Lite Converter를 사용하여 변환해야 합니다. PyTorch에서 ONNX로 모델을 내보내는 방법은 다음과 같습니다.

import torch
import torchvision

# PyTorch 모델 로드
model = torchvision.models.resnet18(pretrained=True)
model.eval()

# 예제 입력 데이터 생성
example_input = torch.rand(1, 3, 224, 224)

# ONNX 형식으로 모델 내보내기
torch.onnx.export(model, example_input, "model.onnx", opset_version=11)

위 코드에서 model은 PyTorch 모델 객체이며, example_input은 예제 입력 데이터입니다. torch.onnx.export 함수를 사용하여 모델을 ONNX 형식으로 내보냅니다. opset_version은 ONNX 버전을 지정하는 매개변수로, 변환하려는 모델에 맞는 버전을 선택해야 합니다.

ONNX로 모델을 내보낸 후에는 TensorFlow Lite Converter를 사용하여 모델을 변환할 수 있습니다. 변환하는 방법은 다음과 같습니다.

import tensorflow as tf

# ONNX 모델 로드
onnx_model = onnx.load("model.onnx")

# TensorFlow Lite Converter를 사용하여 모델 변환
converter = tf.lite.TFLiteConverter.from_onnx_model(onnx_model)
tflite_model = converter.convert()

# 변환된 모델 저장
with open("model.tflite", "wb") as f:
    f.write(tflite_model)

위 코드에서 onnx_model은 ONNX 모델 객체입니다. tf.lite.TFLiteConverter.from_onnx_model 함수를 사용하여 ONNX 모델을 TensorFlow Lite 모델로 변환합니다. 변환된 모델은 tflite_model 변수에 저장되며, 이를 파일로 저장할 수 있습니다.

두 번째로, 변환된 모델을 안드로이드 스튜디오에서 사용하기 위해 설정해야 합니다. 변환된 TensorFlow Lite 모델을 안드로이드 프로젝트의 assets 디렉토리에 추가해야 합니다. 그리고 모델을 로드하고 실행하기 위한 코드를 작성해야 합니다. 자세한 내용은 안드로이드에서 TensorFlow Lite 모델 사용하기 문서를 참고하시기 바랍니다.

마지막으로, 코드에서 발생하는 오류를 해결해야 합니다. 오류 메시지를 보면 ObjectDetector의 초기화 중에 오류가 발생하는 것으로 보입니다. 이 오류는 AllocateTensors() 함수에서 발생하는 것으로 보입니다. 이 오류는 TensorFlow Lite 모델을 로드할 때 발생할 수 있는 문제로, 모델 파일이 올바른지 확인해야 합니다. 또한, 모델을 로드하는 코드에서 오류가 발생할 수도 있습니다. 이 경우에는 모델 파일의 경로나 이름을 확인해야 합니다.

이상의 접근 방법과 예시 코드를 참고하여 문제를 해결해 보시기 바랍니다. 추가적인 도움이 필요하시면 언제든지 질문해 주세요.

감사합니다.

PyTorch 공식 튜토리얼


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!