[23 -2 캡스톤디자인과창업프로젝트] Grounding DINO를 알아보자

PinkTopaz·2023년 11월 24일
0

일명 '졸업프로젝트'라고 불리는 '캡스톤디자인과창업프로젝트'를 진행하면서 Grounding DINO라는 모델을 사용하여 흉기 난동에 대한 객체 탐지를 하게 되었다.

보통 객체 탐지를 하는 서비스나 프로젝트를 보면 Yolo 모델을 사용하는데, 우리는 Grounding DINO라는 새로운 모델 활용에 도전을 해보기로 했다.

지금부터 Grounding DINO에 대해 알아보자.

Grounding DINO란?

Grounding DINO는 Zero-Shot Object Detection을 수행하기 위한 기술이다.

Grounding DINO는 pre-trained 모델인 DINO를 응용하여 새로운 클래스의 객체를 탐지한 후, 탐지된 객체의 시각적 특징과 클래스 이름을 연결하여 상호 작용을 수행하는 방법이다.

실제로 Grounding DINO 공식 레포에서 제공한 코랩 데모 환경에서 서현역 흉기 난동 사건 영상을 돌려보았다.
(text_prompt = "A person with a knife in their hand"로 넣어주었다.)

다음과 같이 흉기를 들고 있는 사람을 저화질 영상에서도 잘 탐지를 하는 것을 볼 수 있다.

Zero-shot Object Detection은 뭔데?

대부분의 객체 탐지 모델은 좁은 범주의 클래스를 식별할 수 있도록 훈련되어 있어 유연성이 부족하다.
따라서 식별 가능한 객체를 늘리거나 변경하려면 데이터를 새로 라벨링하고 모델을 훈련시켜야한다.

Zero-Shot Object Detection은 모델을 다시 훈련하지 않고도 새로운 객체를 탐지할 수 있도록 한다.
단순히 프롬프트를 변경하면 모델이 설명한 객체를 감지할 수 있다.

실제로 Grounding DINO 공식 레포에서 제공한 코랩 데모의 코드를 보면 다음과 같다.

import os
import supervision as sv

IMAGE_NAME = "dog-2.jpeg"
IMAGE_PATH = os.path.join(HOME, "data", IMAGE_NAME)

# TEXT_PROMPT에 명시한 객체를 탐지할 수 있다. 
TEXT_PROMPT = "dog, cup"
BOX_TRESHOLD = 0.35
TEXT_TRESHOLD = 0.25

image_source, image = load_image(IMAGE_PATH)

boxes, logits, phrases = predict(
    model=model,
    image=image,
    caption=TEXT_PROMPT,
    box_threshold=BOX_TRESHOLD,
    text_threshold=TEXT_TRESHOLD
)

annotated_frame = annotate(image_source=image_source, boxes=boxes, logits=logits, phrases=phrases)

%matplotlib inline
sv.plot_image(annotated_frame, (16, 16))

위 코드를 보면 TEXT-PROMPT에 명시한 객체를 위 이미지와 같이 탐지하고 있다.

이러한 ZERO-SHOT 감지 능력은 모델이 새로운 객체와 시나리오에 적응하여 다양한 실전 상황에 적용하기 쉽게 만든다는 장점이 있다.

왜 Grounding DINO?

우리팀의 경우 실시간 CCTV 데이터를 통해 흉기 난동을 감지해야하는데, 대부분의 실시간 CCTV 영상은 화질이 그닥 좋지 못하기 때문에 저화질 영상에서도 어느 정도 정확하게 객체를 탐지하는 것이 중요했다.
또한 그동안 Yolo 모델을 사용한 프로젝트가 굉장히 많았기 때문에 다른 모델에 도전해보고 싶은 마음도 있었다.

졸업 프로젝트 멘토님께 Grounding Dino에 관한 이야기를 듣고 실제로 테스트를 해보며 저화질의 사진과 영상을 돌려보았다.
그 결과 정확도가 아주 높지는 않지만 어느 정도 잘 탐지하는 것을 확인하고 이 모델을 파인튜닝하여 졸업프로젝트를 수행하기로 하였다.

Grounding DINO를 사용해보자

Grounding Dino 공식 레포지토리에 들어가보자.

Readme를 보면
Helpful Tutorial에 Try the Colab Demo라는 링크가 있다.
여기로 접속해보자. (여기로 바로 접속해도 된다.)

Colab은 구글에서 제공하는 Jupiter Notebook으로, 웹 브라우저에서 파이썬 코드를 실행할 수 있도록 해준다.
Colab은 무료로 제공되는 가상 머신에서 GPU 리소스를 사용할 수 있기 때문에, 이를 통해 딥러닝 모델 학습과 같은 고성능 계산 작업을 수행할 수 있다.
이 Colab 환경에서 천천히 따라가며 Grounding DINO를 사용해보자.

Step 1. GPU 세팅

본격적으로 시작하기 전에, Grounding DINO를 돌리기 위해서는 GPU가 필요하다.
현재 내가 사용하고 있는 코랩 환경에서 GPU를 돌릴 수 있는지부터 확인을 해보자.
!nvidia-smi 명령어를 실행한다.

GPU를 활용할 수 있다면 다음과 같이 현재 Colab 환경에서 사용할 수 있는 NVIDIA GPU인 Tesla T4에 대한 정보를 보여준다.

현재 실행 중인 프로세스에 대한 정보도 하단에 표시되어 있는데, 현재 실행 중인 프로세스가 없어서 "No running processes found"라고 나와 있다.

안내가 되어 있는 대로 문제가 발생하는 경우에는 편집(Edit) -> 노트북 설정(Notebook settings) -> 하드웨어 가속기(Hardware accelerator)로 이동하여 GPU로 설정한 후 저장을 클릭하면 된다.

Step 2. Grounding DINO 설치

%cd {HOME} 
!git clone https://github.com/IDEA-Research/GroundingDINO.git
%cd {HOME}/GroundingDINO
!pip install -q -e .
!pip install -q roboflow

를 실행해 Grounding DINO를 설치한다.

GitHub의 "GroundingDINO" 를 클론하고, 클론한 프로젝트의 GroundingDINO 디렉토리로 이동하여 !pip install -q -e로 현재 디렉토리에 있는 프로젝트를 개발 모드로 설치한다.
(-q 옵션은 설치 과정에서의 출력을 간소화하고, -e 옵션은 개발 모드로 설치한다는 것을 나타낸다.)
!pip install -q roboflow를 실행해 Roboflow라는 Python 패키지를 설치한다.

Roboflow는 컴퓨터 비전 및 이미지 처리 프로젝트를 위한 툴과 서비스를 제공하는 플랫폼 중 하나로, 이미지 데이터를 효율적으로 처리하고 관리한다.
주로 객체 감지 같은 작업을 수행하는 프로젝트에서 사용된다.

Step 3. Grounding DINO 가중치 설치

User
%cd {HOME}
!mkdir {HOME}/weights
%cd {HOME}/weights

!wget -q https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth

해당 단계에서는 weights라는 디렉토리를 만들어 가중치(weight) 파일을 저장한다.

!wget -q https://github.com/IDEA-Research/GroundingDINO/releases/download/v0.1.0-alpha/groundingdino_swint_ogc.pth

해당 코드를 이용해 원격 서버에서 학습된 모델의 가중치 파일을 다운로드한다.
가중치는 모델이 입력 데이터에서 출력을 생성하기 위해 찾아야 하는 "규칙"이나 "패턴"을 정의하는데 사용된다.

Step 4. Sample Data 넣기

객체 탐지를 위해 필요한 샘플 이미지를 넣어보자.

%cd {HOME}
!mkdir {HOME}/data
%cd {HOME}/data

!wget -q https://media.roboflow.com/notebooks/examples/dog.jpeg
!wget -q https://media.roboflow.com/notebooks/examples/dog-2.jpeg
!wget -q https://media.roboflow.com/notebooks/examples/dog-3.jpeg
!wget -q https://media.roboflow.com/notebooks/examples/dog-4.jpeg

해당 부분에서는 data라는 디렉토리를 만들어 샘플 이미지 데이터를 저장한다.
원격 서버에서 이미지 파일을 다운로드하는데, 4가지의 강아지 사진을 저장했다.

Step 5. Grounding DINO 로드

%cd {HOME}/GroundingDINO

from groundingdino.util.inference import load_model, load_image, predict, annotate

model = load_model(CONFIG_PATH, WEIGHTS_PATH)

GroundingDINO 프로젝트에서 유틸리티 함수들을 가져온다.
이 함수들은 모델을 로드하고, 이미지를 로드하고 전처리하며, 모델에 대한 예측을 수행하고, 그 결과를 시각화하는 데 사용된다.

함수를 다 가져왔다면 이 중 load_model 함수를 사용하여 GroundingDINO 모델을 설정 파일 (CONFIG_PATH)과 사전에 다운로드한 학습된 가중치 파일 (WEIGHTS_PATH)로부터 로드한다.
이렇게 로드된 모델은 변수 model에 할당되는데, 이를 이용해서 이제부터 이미지에 대한 예측을 수행할 수 있다.

Step 6. Grounding DINO Demo

환경 설정은 모두 마쳤으니 이제 Grounding DINO를 이용해 객체 탐지를 수행해보자.

IMAGE_NAME = "dog-3.jpeg"
IMAGE_PATH = os.path.join(HOME, "data", IMAGE_NAME)

분석할 이미지 파일의 이름을 앞서 다운받은 샘플 이미지 중 하나인 "dog-3.jpeg"로 지정하여 변수 IMAGE_NAME에 할당한다.
os.path.join를 통해 변수 IMAGE_PATH에 이미지 파일의 전체 경로를 설정한다.

TEXT_PROMPT = "chair, dog, cup, person, shoes, tree, car"
BOX_TRESHOLD = 0.35
TEXT_TRESHOLD = 0.25

변수 TEXT_PROMPT에 객체를 찾을 때 사용할 텍스트 캡션을 할당한다.
나의 경우 사진에 있는 최대한 많은 객체를 찾아보고 싶어서 많은 단어를 할당했다.

BOX_TRESHOLD는 객체 감지를 하면 그 객체를 감싸는 박스의 임계값인데, 예를 들어 이 객체가 0.35 이하의 탐지 되었다면 박스는 표시되지 않는다.

TEXT_TRESHOLD도 BOX_TRESHOLD와 마찬가지로 텍스트 캡션의 임계값이며, 이 임계값보다 낮은 확률이면 텍스트가 표시되지 않는다.

image_source, image = load_image(IMAGE_PATH)

이미지 파일을 로드하고, 해당 이미지를 모델에 사용할 수 있는 형식으로 전처리한다.

boxes, logits, phrases = predict(
    model=model, 
    image=image, 
    caption=TEXT_PROMPT, 
    box_threshold=BOX_TRESHOLD, 
    text_threshold=TEXT_TRESHOLD
)

predict 함수를 사용하여 모델에 이미지를 입력하고 객체 감지와 텍스트 캡션을 얻는다.

annotated_frame = annotate(image_source=image_source, boxes=boxes, logits=logits, phrases=phrases)

annotate 함수를 사용하여 이미지에 상자와 텍스트를 추가하여 시각적으로 표시된 박스와 텍스트를 그려준 후


%matplotlib inline  
sv.plot_image(annotated_frame, (16, 16))

맷플롯립을 사용하여 화면에 바로 이미지가 뜰 수 있도록 처리하고, sv 라이브러리를 사용하여 주어진 크기로 이미지를 시각화한다.

그 결과 다음과 같은 이미지를 얻을 수 있다.

나무의 경우 상자가 표시가 되기는 했지만 텍스트 캡션은 임계값보다 낮아서 표시되지 않았다.
이를 보면 꽤나 많은 객체들이 사전에 학습을 시키지 않았음에도 불구하고 꽤나 정확하게 탐지되는 것을 확인할 수 있다.

마치며

사실 머신러닝이나 인공지능에 대한 강의를 듣거나 학습을 해본 적이 없는데, 당장 졸업프로젝트에 맞닥뜨려서 이렇게 모델을 결정하고 학습을 해야하다보니 모든 것이 쉽지 않다고 느껴진다.

Grounding Dino를 멘토님께 추천 받고 이 정도 이해하기까지도 시간이 오래 걸렸는데, 이 Grounding Dino가 내가 처음 사용해보는 모델이고 이를 통해 앞으로 여러가지 학습을 할 수 있을 것이라고 생각하니 기대도, 걱정도 많이 된다.

앞으로 Grounding Dino를 사용하며 얻은 인사이트를 모두 잘 정리해가며 졸업프로젝트를 큰 성장의 기회로 삼아야겠다

참고자료

Grounding Dino 공식 레포지토리
Grounding Dino 논문 리뷰
[IN-ISP] Grounding DINO

profile
🌱Connecting the dots🌱

0개의 댓글