객체 탐지에서 주로 사용하는 개념으로, 이미지 내에서 다양한 크기와 비율로 물체를 탐지하기 위해 미리 정의된 사각형 영역을 말한다. 주로 YOLO , Faster R-CNN , RetinaNet과 같은 객체 탐지 모델에서 사용.
기본 역할
이미지의 특정 위치에 대해 다양한 크기와 비율의 사전 정의된 박스를 배치한다.
해당 박스는 물체 후보 영역으로 사용되며, 모델이 학습하면서 각 박스를 실제 물체와 정교히 맞추는 방식으로 탐지를 수행함.
다양한 크기와 비율을 가진다.
객체는 다양한 크기와 형태를 가지니, 서로 다른 크기와 비율의 Anchor Box가 필요하다.
만약, 현재 위치에 대해서 3가지의 크기와 3가지의 비율을 정의하면, 해당 위치에는 9개의 Anchor Box가 만들어 진다.
예측 방법
모델은 각 Anchor Box에 대해서 클래스 확률과 박스 오프셋을 예측한다.
장점
다양한 물체 크기와 형태 탐지 가능
anchor box가 사전 정의되어 있어 탐지 속도가 빠르다.
단점
너무 많은 anchor box를 사용하면 계산량이 증가하며, 불필요한 후보영역이 많아질수있음
적절한 하이퍼 파라미터를 설정해야 최적의 성능을 얻을수있다.
작동과정
1. 특정한 격자 위치에 대해서 여러가지 anchor box를 만든다. 이는 물체를 포함할 가능성이 있는 후보 영역이다.
1-1. 특정 위치에 다양한 크기와 비율의 박스를 정의함.
ex) 512 x 512 image를 16x16격자로 나누면 32x32의 cell로 이미지가 나뉜다.
1-2. 각 격자의 중심에서 시작해서 다양한 크기와 비율의 anchor box를 생성한다.
anchor box의 scale과 aspect radio(비율)는 사전에 하이퍼파라미터로 정의.
2. IoU ( intersection over union ) 계산한다. 즉 이는 anchor box와 ground truth box 사이의 IoU를 계산. 이때 IoU가 특정 임계값을 초과하면, anchor box는 물체를 포함한다고 간주하며, 이를 모델이 학습하게 한다.
IoU가 높으면, Anchor Box는 물체를 포함한다고 간주. 낮은 경우는 물체와 무관한 배경으로 간주.(식1참고)
positive anchor box
Iou가 특정 임계값(ex. 0.5 )를 초과하면, 해당 anchor box는 물체를 포함하는 것으로 간주.
positive anchor box는 ground truth box와 최대한 일치하도록 학습된다.
negative anchor box
IoU가 낮은 anchor box는 물체를 포함하지 않는 것으로 간주하며, 이를 모델이 학습한다. 그리고 이는 배경으로 처리된다.
3. anchor box는 초기에는 고정된 크기와 위치를 가지지만, 학습이 진행되며 모델이 예측한 오프셋 값을 통헤서 물체와 더 정밀하게 일치하게 조정한다.
3-1. 물체 존재 여부 및 클래스 확률 예측
우선 해당되는 anchor box가 물체를 포함하는지 확인한다. ( 0 or 1 ) 그리고 anchor박스가 특정 클래스일 확률을 구한다. ( 배경이라고 판단하면 이는 수행안함 ) 그 다음에 bounding box offset을 구한다.
bounding box offset이란 anchor box와 ground truth box 사이의 차이를 보정하는 값이다. 이 값은 anchor box의 중심 좌표( x , y )와 크기( w , h )를 보정한다. ( 식2 참고)
4. Loss Function을 통해서 학습을 합니다.
4-1. classification loss 클래스 손실
anchor box가 예측한 클래스와 ground truth의 실제 클래스를 비교. 주로 cross-entropy loss를 사용
4-2. localization loss 위치 손실
anchor box와 ground box 사이의 좌표 및 크기 차이를 최소화 주로 smooth L1 loss or IoU Loss를 사용
4-3. objectness Loss 물체 여부 손실
anchor box가 물체를 포함하는지 여부를 예측 주로 binary cross entropy loss사용
5. 모델이 각 anchor box에 대해서 예측한 결과를 기반으로 물체를 탐지함.
모델이 예측한 offset값을 anchor box에 적용해서 최종 bounding box를 계산
동일한 객체에 대해서 여러개의 anchor box가 예측될 수 있으니, IoU가 높은 중복된 박스를 제거해서 최적의 bounding box만 남김. 그리고 각 물체의 클래스,bounding box, 확률이 최종 결과로 출력
식2
import numpy as np
def generate_anchor_boxes( img_size , grid_size , scales , aspect_radios ):
anchor_boxes = []
grid_width = img_size[0] / grid_size[1] # 격자 한칸의 폭 계산
grid_height = img_size[1] / grid_size[0]# 격자 한칸의 높이 계산
print(f'img_size is {img_size} grid_size is {grid_size} scales is {scales} aspect_radios is {aspect_radios}\ngrid_width is {grid_width} grid_height is {grid_height} 즉, 입력 이미지를 {grid_width} x {grid_height}의 셀로 나눈다. ')
# 각 격자 위치를 순회하면서 anchor box를 만든다.
for i in range( grid_size[ 0 ] ): # 격자의 세로 (행) 반복
for j in range( grid_size[ 1 ] ): # 격자의 세로 (열) 반복
# 현재 격자의 중심 좌표를 계산
center_x = ( j + 0.5 ) *grid_width
center_y = ( i + 0.5 ) * grid_height
# 주어진 scale과 aspect ratio를 사용해서 anchor box 생성
for scale in scales:
for ratio in aspect_ratios:
box_width = scale * img_size[0] * np.sqrt( ratio ) # anchor box의 폭 계산
box_height = scale * img_size[1] / np.sqrt( ratio ) # anchor box의 높이 계산
anchor_boxes.append( (center_x , center_y , box_width , box_height ) )
#print(f'{center_x} {center_y} {box_width} {box_height}')
return np.array( anchor_boxes )
img_size = (512 , 512) # 이미지 크기 widh , height
grid_size = ( 4 , 4 ) # 격자 크기 rows , cols
scales = [ 0.1 , 0.2 , 0.4 ] # 앵커 박스의 크기
aspect_ratios = [1.0 , 2.0 , 0.5 ] # 앵커 박스의 비율
anchor_boxes = generate_anchor_boxes( img_size , grid_size , scales , aspect_ratios)
print(anchor_boxes)