AI을_통한_라벨링 - boostcampwm-2024/and04-Nature-Album GitHub Wiki

💡문제 해결 과정 기록

우선 기존 팀원과의 회의에서 AI 사용과 관련해서 2가지 방법이 제시되었다.

첫번재는 Tensorflow Lite를 사용하는 것이고, 두번째는 Gemini AI를 사용하는 것이었다.

우선 Tensorflow Lite를 통해 구현해보기로 결정했다.

TensorFlow Lite

TensorFlow Android 빠른 시작

위 공식문서에서 코코 데이터셋을 사용하여 객체인식을 구현했다.

class ObjectDetectorHelper(context: Context, modelPath: String) {
    private val detector: ObjectDetector

    init {
        val modelFile = copyAssetToInternalStorage(context, "EfficientDet.tflite", "EfficientDet.tflite")
        val options = ObjectDetector.ObjectDetectorOptions.builder()
            .setMaxResults(5) // 최대 5개의 결과만 반환
            .setScoreThreshold(0.5f) // 50% 이상의 신뢰도만 반환
            .build()
        detector = ObjectDetector.createFromFileAndOptions(modelFile, options)
    }

    fun detectObjects(bitmap: Bitmap): List<Detection> {
        val tensorImage = TensorImage.fromBitmap(bitmap)
        return detector.detect(tensorImage)
    }
}

fun copyAssetToInternalStorage(context: Context, assetFileName: String, outputFileName: String): File {
    val outputFile = File(context.filesDir, outputFileName)
    if (!outputFile.exists()) {
        context.assets.open(assetFileName).use { inputStream ->
            outputFile.outputStream().use { outputStream ->
                inputStream.copyTo(outputStream)
            }
        }
    }
    return outputFile
}

코드는 정말 간단했고, bitmap을 통해 detector.detect 메서드를 호출하면 끝이다.


💥 정확도가 매우 떨어지는 코코 데이터…

image

image image

처음에는 고양이, 강아지, 새 같은 간단한 이미지를 통해 테스트 했을 땐 70~ 80%의 정확도를 보여주었다.

하지만 위의 이미지 같이 사자, 나비, 장수풍뎅이 처럼 조금만 복잡해져도 정확도가 매우 떨어졌다.

위 이미지의 사자를 여러번 돌렸을 때, 꼬끼리, 말 같은 탐지만 되는 것을 보아하니 코코 데이터에는 사자가 없는 듯 했다.

그렇기에 이렇게 정확도가 떨어지는 것을 사용할 수 없다고 생각하여 두 번째 방법인 Gemini AI를 사용하기로 했다.


Gemini AI

Google AI for Developers Gemini API | Google AI for Developers

Google AI for Developers Gemini API 빠른 시작 | Google AI for Developers


Gemini API를 사용하기 위해 REST API를 사용하는 방법과 REST API없이 Google AI SDK 를 통해 사용하는 두개의 방법이 존재했다.

복잡한 REST API 보다는, 클라이언트에서 바로 사용 가능한 Google AI SDK를 사용하자는 회의를 통해 후자의방식으로 진행하고자 했다.


Android Developers Google AI 클라이언트 SDK | Android Developers

image

사용하려 공식문서를 확인했을 때 아래와 같은 주의사항이 있었고, 안드로이드에서 Gemini API를 직접 호출하려면 Google SDK가 아닌 Android용 Vertex AI 사용하라는 안내하고 있었다.


❓ Google SDK vs Vertext AI

Firebase Google AI SDK 대신 Vertex AI SDK를 사용하도록 마이그레이션

어떤 이유로 Vertex AI를 사용하라고 권장했던 걸까?

이는 위 공식문서에서 확인할 수 있었다.

우선 가장 큰 특징은 API KEY 노출 여부인 것 같았다.

// Google AI
val generativeModel = GenerativeModel(modelName = "MODEL_NAME",
    // Access your API key as a Build Configuration variable
    apiKey = BuildConfig.apiKey
)

//Vertext AI in Firebase
val generativeModel = Firebase.vertexAI.generativeModel("MODEL_NAME")

위와 같이 키를 사용하지 않고도 Gemini AI를 사용할 수 있다.

image

공식문서에도 나와있듯이 API 키를 앱에 직접 삽입하는 거는 악위적인 행위자에게 노출될 수 있기에 적극 권장하고 있다. Vertex AI Gemini API는 Google AI Gemini API와 같은 API 키가 아닌 Google Cloud IAM에 의해 승인되기에 더 안전하게 호출할 수 있다고 한다.

이 외에도 아래와 같은 장점이 있다고 한다.

image

💥 Gemini API에게 이미지 업로드하는 방법

Gemini API에게 이미지를 넘겨주기 위하여 첫 시도로는 Bitmap을 Base64로 변환하는 것이었다.

image

하지만 위와 같은 답변을 받았다…

그럼 다른 방법으로는 uri를 보내는 것인데, Uri를 보내기 위해서는 서버에 저장 후 그 URI를 가져오는 방법을 선택해야 한다. 하지만 우리 앱은 RoomDB의 이미지를 uri로 가져오는 것이기에 이 uri를 사용할 수 없었다.

또한, uri를 통해 Gemini AI를 사용해봤는데 아래와 같은 답변을 받았다.

image

즉, 다른 방법을 선택해야 했는데 찾을 수 없었다.

시간을 지체할 수 없어 내 상황을 팀원에게 공유했고, 팀원들과 함께 서칭한 결과 답을 찾을 수 있었다.

image

처음에는 문자열 형태로만 보내야 한다고 생각했는데 bitmap 자체를 보낼 수 있었던 것이다…

image 메서드 안에 비트맵을 넣고 실행한 결과 정확한 결과를 얻을 수 있었다.


💥 리컴포지션이 무한으로 일어나는 버그

error.mov

문제 정의

사진 찍고 Gemini AI를 통해 이미지 식별하는 과정이 여러번 일어나는 버그가 발생했다.

위 영상 뒤쪽에 보이다 시피 Label이 계속 바뀌고 있는 것을 볼 수 있었고, Log와 Inspector를 통해 여러번 리컴포지션되고 있는 버그라는 것을 확인했다.

문제 해결 과정

우선 UiStateUiState.Sucess 됐을 때 저장하는 상태를 합치는 작업을 진행했다.

그 후 UiState.Idle 인 상태에만 Gemini AI 를 호출하도록 변경하였고, UiState.Loading 상태일 땐, 로딩 애니메이션을 UiState.Sucess 일때는 Success 상태의 데이터를 하위 컴포저블에게 넘겨주는 방식으로 해결했다.

⚠️ **GitHub.com Fallback** ⚠️