COCO dataset으로 간단한 object detection 해보기
포스트 난이도: HOO_Middle
# COCO Dataset
COCO는 Common objects in context의 줄임말로 YOLO와 같이 computer vision의 효율성 향상을 위해서 만들어진 오픈형 데이터셋이다. 쉽게 생각해서 Google의 Open images dataset을 생각하면 된다. 우리가 사용하고 있는 computer vision 모델들은 Train과 Test, 학습과 테스트 과정을 위해서 특정한 데이터셋이 필요하다. 이러한 데이터셋을 기본값으로 사용하고 있는 것이 바로 코코 (COCO)인 셈이다. 따라서 YOLO에서는 특정한 이미지를 가지고 라벨링 학습 없이도 코코 데이터셋에서 제공된 라벨링의 경우에는 이미지가 알아서 인식하고 결과를 산출해 낼 수 있다. 조금 더 쉽게 이야기하자면 마치 우리가 파이썬을 설치했을 때 별도의 모듈이나 라이브러리를 설치하지 않고도 기본적으로 제공되는 라이브러리를 사용할 수 있는 거와 비슷한 맥락이라고 보면 된다.
코코 데이터셋에는 대략 80개의 학습 라벨링이 되어 있기에 실생활에서 존재하는 사물이나 생물에 대해서 인식이 어느정도 가능하다. 코코 데이터셋에 대해서 조금 더 이야기하자면 데이터 셋의 값은 총 3개로 나뉘는데 x, y, v 값으로 나뉘어 있다. x와 y의 경우에는 좌표를 나타내고 v는 visibility를 나타낸다. 따라서 해당 사물이 보이는지 보이지 않는지를 구분해 주는 역할을 담당하는 셈이다. 이야기하다 보니 너무 신나서 본론에서 벗어나는 거 같아 코코에 대해서는 여기까지만 이야기하고 본론으로 돌아오도록 하자.
# Object Detection
욜로 (YOLO)에 대해서 이야기를 하다보면 Object detection이 전부인 줄 오해하는 경우가 있는데 욜로는 사실상 Computer vision model이다. Object detection이 외에도 vision 역할을 할 수 있는 다른 기능들도 존재하는데 대표적으로 Semantic segmentation이나 Semantic instance segmentation, Localization 등이 있다. 따라서 사물을 인식하는 기능 외적으로도 사람의 눈처럼 물체를 분류하고 구분하는 역할의 기능도 YOLO를 통해서 가능하고 이게 가능한 이유 중 하나가 바로 COCO Dataset로 학습과 모델 개발이 이루어졌기 때문이다. 이번 포스트에서는 YOLO를 통해서 가볍게 Object detection을 해보도록 해보자.
# YOLO example codes
앞서 이야기한 바와 같이 기존의 데이터셋을 사용할 예정이고 이후에 custom dataset을 통해서 원하는 사물이나 생물에 대한 detection이 가능하다. 참고로 글쓴이는 colab을 사용하였다.
from ultralytics import YOLO
model = YOLO("yolov8m.pt")
Downloading https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8m.pt to 'yolov8m.pt'...
100%|██████████| 49.7M/49.7M [00:00<00:00, 154MB/s]
우선 YOLO를 가져와서 원하는 모델을 선택해준다. Object detection 사이즈 선택을 할 수 있는 것을 알고 있을 텐데 일단 간단하게 해 보는 정도이기에 평범한 Medium으로 선택하였다. 만약에 다른 사이즈를 원하면 "yolov8m.pt"에서 "m" 부분만 다른 사이즈로 바꿔주면 된다. (HOO_Middle급 포스트인데 너무 설명이 길다면 앞으로 설명을 더 생략을 하겠습니다.)
results = model.predict("me_test.jpeg")
image 1/1 /content/me_test.jpeg: 640x640 3 persons, 1672.8ms
Speed: 6.3ms preprocess, 1672.8ms inference, 2.6ms postprocess per image at shape (1, 3, 640, 640)
results = model.precit("")은 거의 기본급 반찬과 같은 것이기에 그냥 눈감고 사용해주면 된다. 글쓴이는 이번에 프로필에 있는 욜로 이전 버전으로 디텍팅 한 글쓴이 이미지를 다시 사용하려고 한다.
result = results[0]
len(result.boxes)
3
array를 만들어서 결과를 저장해주고 박스의 개수를 len() 기능을 통해서 확인하면 총 3개가 디텍팅 된 것을 알 수 있었다. 코코 데이터셋에는 사람 인식하는 게 있고 글쓴이가 찍힌 이미지를 디텍팅했으니, 아무래도 이미지 속 사람 3명이 디텍팅 된 게 아닐까 추측이 된다. 사실 이전 모델에도 같은 개수로 디텍팅 되어서 크게 놀랄 일은 아니었다.
box = result.boxes[0]
box 개수 결과는 박스라는 변수 안에 새롭게 저장해 준다. 개발자라면 산출된 값들을 항상 저장해 주는 습관을 가지는 게 좋다. 특히 데이터 관련 개발자라면 더더욱 사용할지도 모른다 싶으면 temp으로 해서 저장하고 관리하는 편이 수월한데, 프로젝트 내에서 가공 과정에서 발생하는 새로운 값들이 매우 많기 때문이다. 잔소리는 이쯤 하고 다시 본론으로 돌아가도록 하자.
print("Object type:", box.cls)
print("Coordinates:", box.xyxy)
print("Probability:", box.conf)
Object type: tensor([0.])
Coordinates: tensor([[144.7448, 216.3489, 267.2790, 426.8051]])
Probability: tensor([0.9375])
이것도 정석이기에 굳이 필요한 설명은 생략하고 object type부터 보게 되면, 0. 얼마의 소수점이 나온 걸 알 수 있다. 일단 코코 데이터셋에서 0은 사람이기에 0에 가까운 값이 나온 걸 알 수 있다. 0이 아니라 0과 가까운 숫자가 나왔다는 것은 마치 "사람일걸?"이라고 말해주는 거와 같다. 여기서 알 수 있는 것이 디텍팅된 이미지의 정확도가 100프로가 아니라는 것이다. 사실상 100프로가 나온 적은 없기 때문에 해당 값으로 인해 추후에 에러의 소지가 있다면 반올림 처리를 해주는 것이 좋다. 나머지는 위치 값이나 예측 값이니 참고하면 된다.
obj_id = box.cls[0].item()
cords = box.xyxy[0].tolist()
conf = box.conf[0]
print("Object type:", obj_id)
print("Coordinates:", cords)
print("Probability:", conf)
Object type: 0.0
Coordinates: [144.7448272705078, 216.34886169433594, 267.2790222167969, 426.80511474609375]
Probability: tensor(0.9375)
이런 식으로 보기 편하게 좀 정리해 주면 좋다. Probability의 소수점 끝까지 비교해야 하는 경우에는 이 역시도 item() 기능을 활용하면 된다.
for box in result.boxes:
obj_id_name = result.names[box.cls[0].item()]
cords = box.xyxy[0].tolist()
cords = [round(x) for x in cords]
conf = round(box.conf[0].item(), 2)
print("Object type name:", obj_id_name)
print("Coordinates:", cords)
print("Probability:", conf)
print("----------------------------------")
Object type name: person
Coordinates: [145, 216, 267, 427]
Probability: 0.94
----------------------------------
Object type name: person
Coordinates: [123, 244, 127, 251]
Probability: 0.33
----------------------------------
Object type name: person
Coordinates: [116, 243, 122, 251]
Probability: 0.29
----------------------------------
앞선 코드에서 박스 개수가 하나가 아니라 3개가 있다는 걸 알았다. 따라서 박스를 하나씩 비교 분석하기 위해서는 for문을 사용하여 나타낼 수 있다. 또한 name function을 통해서 아예 이름값에서 이름 명으로 바꿔서 출력을 해주면 보기 훨씬 편하다. 값에서 명으로 바꿨더니 출력되는 키워드가 Person인 것을 확인할 수 있다.
print(result.names)
{0: 'person', 1: 'bicycle', 2: 'car', 3: 'motorcycle', 4: 'airplane', 5: 'bus', 6: 'train', 7: 'truck', 8: 'boat', 9: 'traffic light', 10: 'fire hydrant', 11: 'stop sign', 12: 'parking meter', 13: 'bench', 14: 'bird', 15: 'cat', 16: 'dog', 17: 'horse', 18: 'sheep', 19: 'cow', 20: 'elephant', 21: 'bear', 22: 'zebra', 23: 'giraffe', 24: 'backpack', 25: 'umbrella', 26: 'handbag', 27: 'tie', 28: 'suitcase', 29: 'frisbee', 30: 'skis', 31: 'snowboard', 32: 'sports ball', 33: 'kite', 34: 'baseball bat', 35: 'baseball glove', 36: 'skateboard', 37: 'surfboard', 38: 'tennis racket', 39: 'bottle', 40: 'wine glass', 41: 'cup', 42: 'fork', 43: 'knife', 44: 'spoon', 45: 'bowl', 46: 'banana', 47: 'apple', 48: 'sandwich', 49: 'orange', 50: 'broccoli', 51: 'carrot', 52: 'hot dog', 53: 'pizza', 54: 'donut', 55: 'cake', 56: 'chair', 57: 'couch', 58: 'potted plant', 59: 'bed', 60: 'dining table', 61: 'toilet', 62: 'tv', 63: 'laptop', 64: 'mouse', 65: 'remote', 66: 'keyboard', 67: 'cell phone', 68: 'microwave', 69: 'oven', 70: 'toaster', 71: 'sink', 72: 'refrigerator', 73: 'book', 74: 'clock', 75: 'vase', 76: 'scissors', 77: 'teddy bear', 78: 'hair drier', 79: 'toothbrush'}
실제로 라벨들을 출력해 보면 각 값들에 매겨진 이름들을 확인할 수 있는데 0이 Person인 것을 알 수 있다.
!yolo predict model="yolov8m.pt" source='me_test.jpeg'
Ultralytics YOLOv8.0.142 🚀 Python-3.10.6 torch-2.0.1+cu118 CPU (Intel Xeon 2.20GHz)
YOLOv8m summary (fused): 218 layers, 25886080 parameters, 0 gradients
image 1/1 /content/me_test.jpeg: 640x640 3 persons, 1770.9ms
Speed: 5.1ms preprocess, 1770.9ms inference, 2.4ms postprocess per image at shape (1, 3, 640, 640)
Results saved to runs/detect/predict4
이렇게 이미지 결과로 분석된 것을 확인해 보면 이미지 속에서 사람으로 추정되는 물체에 디텍팅이 이루어진 것을 확인할 수 있다. YOLO를 처음 써보는 브로라면 이렇게 간단하게 한번 해보면서 Object detection의 재미에 빠져볼 수 있다.
'AI & Data > AI&ML Examples' 카테고리의 다른 글
[AI & ML Examples] Computer Vision Calibration: Normalized Points 예제코드 (0) | 2023.10.13 |
---|---|
[AI/Computer Vision] 커스텀 데이터셋으로 사물 분석하기 #01 (Object Detection by Custom Dataset) (0) | 2023.08.08 |
[AI / Computer Vision] YOLOv8 맛보기 후기 (0) | 2023.07.27 |
[SML] Marginal PDF Example codes (0) | 2023.02.15 |
[SML] Misclassification Rates Example Codes: guess, test data (0) | 2023.02.15 |
댓글