YOLO(You Only Look Once)는 객체 탐지 분야에서 매우 혁신적인 접근법으로, 여러 객체를 실시간으로 인식할 수 있는 뛰어난 능력을 가지고 있습니다. YOLO는 특히 연구자들과 개발자들 사이에서 인기가 있으며, 시간에 따라 여러 버전이 개발되었습니다. 이 글에서는 YOLO의 다양한 버전인 YOLOv3, YOLOv4, YOLOv5의 특징, 차이점, 그리고 어떤 경우에 어떤 버전을 선택해야 하는지를 자세히 살펴보겠습니다.
1. YOLO 개요
YOLO는 2016년에 처음 소개되었습니다. 이전의 객체 탐지 알고리즘들과 달리, YOLO는 이미지 전체를 한 번에 처리하여 객체를 탐지합니다. 이는 전통적인 방법들(예: R-CNN 계열)이 지역 제안(region proposal)을 먼저 생성한 후, 해당 영역에 대해 분류기를 적용하는 방식과 달리, 훨씬 빠르고 효율적입니다. YOLO는 입력 이미지에서 객체의 경계 박스와 클래스 확률을 동시에 예측하는 단일 신경망으로 구성됩니다.
2. YOLOv3
YOLOv3는 2018년에 발표된 버전으로, 이전 버전인 YOLOv2에 비해 여러 가지 개선이 있었습니다. 주요 특징은 다음과 같습니다:
- 다양한 크기의 객체 인식: YOLOv3는 다양한 크기의 객체를 처리하기 위해 여러 해상도의 특성 맵을 사용합니다. 이를 통해 작은 객체와 큰 객체 모두를 잘 인식할 수 있습니다.
- 다중 레이어 예측: 네트워크에서 세 개의 서로 다른 크기의 피쳐 맵을 사용하여 여러 스케일에서 예측을 수행합니다.
- 클래스 확률 예측 개선: YOLOv3는 각 경계 박스에 대해 클래스 확률을 예측하는 방식이 개선되어, 각 클래스에 대한 정보가 더욱 명확해졌습니다.
YOLOv3의 성능은 COCO 데이터셋에서 mAP(mean Average Precision) 57.9%로 평가되었으며, 객체 탐지 분야에서 여전히 널리 사용되고 있습니다.
YOLOv3 예제 코드
import cv2
import numpy as np
# YOLOv3 모델 로드
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
# 이미지 로드
img = cv2.imread("image.jpg")
height, width, channels = img.shape
# 이미지 전처리
blob = cv2.dnn.blobFromImage(img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers)
# 탐지된 정보 출력
class_ids, confidences, boxes = [], [], []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
# 경계 박스 좌표
x = int(center_x - w / 2)
y = int(center_y - h / 2)
boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)
# Non-Maximum Suppression
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
for i in indexes:
i = i[0]
box = boxes[i]
x, y, w, h = box
label = str(classes[class_ids[i]])
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(img, label, (x, y + 30), cv2.FONT_HERSHEY_SIMPLEX, 3, (0, 255, 0), 3)
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. YOLOv4
YOLOv4는 2020년에 발표되었으며, YOLOv3의 성능을 개선하기 위해 여러 혁신을 도입했습니다. 주요 특징은 다음과 같습니다:
- 다양한 최적화 기법: 전이 학습(transfer learning)과 데이터 증강(data augmentation) 기법을 통합하여 모델의 효율성을 높였습니다.
- CSPNet의 사용: Cross Stage Partial Networks (CSPNet)를 도입하여 더 나은 특징 표현을 하도록 했습니다.
- 한층 개선된 성능: YOLOv4는 COCO 데이터셋에서 43.5 FPS의 속도에서도 mAP 43.5%를 달성하여, 많은 실제 애플리케이션에서 쓰일 수 있는 강력한 솔루션이 되었습니다.
YOLOv4 예제 코드
# YOLOv4 예제는 YOLOv3와 매우 유사합니다.
# YOLOv4의 가중치와 구성 파일을 이용하여 아래와 같이 로드할 수 있습니다.
net = cv2.dnn.readNet("yolov4.weights", "yolov4.cfg")
# 나머지 코드는 YOLOv3와 동일합니다...
# 이미지 전처리, 예측, 결과 시각화는 동일하게 진행할 수 있습니다.
4. YOLOv5
YOLOv5는 2020년에 발표된 비공식적인 YOLO 버전으로, Ultralytics에 의해 개발되었습니다. YOLOv5는 YOLOv4보다 더 간결하고, 쉽게 사용할 수 있도록 많은 커뮤니티의 기여를 받았습니다. 주요 특징은 다음과 같습니다:
- PyTorch 기반 구현: YOLOv5는 PyTorch로 구현되어 있어, 코드가 간결하고 사용자 친화적입니다.
- 모델 크기와 속도: YOLOv5는 크기와 속도 면에서 다양한 옵션을 제공하여, 사용자가 요구에 맞게 선택할 수 있습니다.
- 향상된 성능: YOLOv5는 COCO 데이터셋에서 50 FPS 이상의 속도로 mAP 50% 이상의 성능을 보여주며 사용하기 쉬운 인터페이스로 빠르게 확산되었습니다.
YOLOv5 예제 코드
!pip install torch torchvision # PyTorch 설치
from yolov5 import YOLOv5 # YOLOv5 라이브러리 임포트
model = YOLOv5("yolov5s.pt") # 모델 로드
# 이미지 로드
img = "image.jpg"
results = model.predict(img)
# 결과 시각화
results.show()
results.save() # 저장된 이미지 확인용
5. YOLO 버전 선택 기준
다양한 YOLO 버전이 존재하지만, 적합한 버전을 선택하기 위해서는 몇 가지 요소를 고려해야 합니다:
- 속도: 실시간 성능이 중요한 애플리케이션에서는 YOLOv4나 YOLOv5가 적합할 수 있습니다.
- 정확도: 높은 정확도가 필요하다면 YOLOv4가 좋은 선택일 수 있습니다. YOLOv5도 충분한 정확도를 제공하지만, YOLOv4와 비교할 때 조금 낮을 수 있습니다.
- 개발 편의성: YOLOv5는 PyTorch로 구현되어 있어, 빠른 개발과 튜닝이 가능합니다.
- 모델 크기: 경량화된 모델이 필요하다면 작은 버전의 YOLOv5를 고려할 수 있습니다.
결론
YOLO 계열은 객체 탐지 분야에서 매우 중요한 역할을 하고 있으며, 각각의 버전이 발전하면서 더 높은 성능과 사용 편의성을 제공합니다. YOLOv3는 여전히 많은 애플리케이션에서 사용되지만, YOLOv4와 YOLOv5의 출시로 인해 더 나은 성능을 제공하는 옵션이 많아졌습니다. 개인의 필요에 따라 적절한 YOLO 버전을 선택하여 사용하시기 바랍니다.