본문 바로가기

개발/딥러닝

[논문 구현] SSD: Single Shot MultiBox Detector 모델 구현

 

이제 SSD를 구현해 보겠습니다. 저는 이미지를 받으면 트럼프 카드의 위치와 카드의 색(빨강, 검정)을 찾아주는 인공지능을 만들 것입니다.

 

 

논문에서는 vgg-16을 Conv5_3 레이어까지 가져왔습니다. 아래 그림에서 D에 해당하는 부분입니다. 이 부분 먼저 구현해 보겠습니다.

 

여기서 he_normal은 가중치를 초기화 해 주는 방법 중 하나입니다. kernel_regularizer은 커널의 가중치가 너무 커지는 것을 막기 위한 것입니다. 해당 모델의 summary를 출력해 봅니다.

 

이 뒤 부분도 진행해 줍니다.

 

다행히 논문과 같은 구조가 나왔습니다.

 

이제 각 클래스 별 confidence와 위치를 가져올 것입니다. 이 값들은 c4_3, c7, c8_2, c9_2, c10_2, c11_2에서 Conv2D를 통해 가져옵니다. 여기서 n_class = 3, boxes=[3,5,5,5,3,3]입니다. n_class는 클래스 수로 (배경, 빨강, 검정)입니다. boxes는 각 피쳐 맵에 적용되는 anchor box의 비율입니다. 논문에서는 4,6,6,6,4,4를 사용했지만 구현 난이도를 줄이기 위해 [1, 2, 1/2, 3. 1/3] 5개만 사용했습니다.

 

각 피쳐의 픽셀이 어느 정도의 영역을 차지하는지 저장해 두는 레이어를 만듭니다. 이 레이어는 따로 학습을 하는 레이어는 아니고 로스를 계산할 때 참고하기 위한 레이어입니다. AnchorBoxes는 커스텀 레이어로 조금 있다가 만들 것입니다. 파라미터는 원본 이미지의 너비, 높이, 스케일, anchor box 비율입니다. 스케일은 [0.2, 0.34, 0.48, 0.62, 0.76, 0.9]로 0.2에서 0.9까지 6등분 한 것입니다.

 

각 레이어의 모양을 바꿔줍니다. 모든 anchor box를 일렬로 늘였다고 생각하면 됩니다.

 

각 레이어를 전부 하나로 합쳐줍니다.

커스텀 레이어 만들기

커스텀 레이어인 AnchorBoxes가 어떤 역할을 하는지부터 알아보겠습니다. 이 레이어는 각 anchor box의 중심 좌표와 너비, 높이를 너비와 높이에 대한 비율로 보여줍니다. 아래는 scale=0.2, 비율=1일 때의 예시입니다. 만약 비율이 2였다면 0.2, 0.2 부분이 0.2828, 0.1414가 됩니다. 너비 * 높이를 유지할 것이기 때문에 너비에 $*\sqrt{2}$, 높이에 $/\sqrt{2}$를 해줍니다.

 

 

이제 커스텀 레이어를 만들어 봅시다. Layer를 상속받는 클래스를 하나 만듭니다. 이때, call 함수가 있어야 합니다. 이 레이어는 파라미터가 업데이트되는 것은 아니기 때문에 특별히 세팅해 줄 것은 없습니다. 너비, 높이, scale, retios를 입력받습니다.

 

call 함수를 통해 입력받은 레이어를 처리해 줍니다. input에는 입력받은 레이어가 들어옵니다.

size는 크기가 안맞을 때를 대비한 것입니다. ratios에 맞게 anchor box를 만들어 줍니다.

 

계산하기 쉽게 하기 위해서 먼저 각 픽셀이 담당하는 좌표를 픽셀 기준으로 뽑아낼 것입니다. 입력 크기를 뽑아내고 각 픽셀의 너비를 구합니다. 

 

각 픽셀의 중심 좌표를 구합니다. 아래의 예시를 보면 meshgrid가 어떤 함수인지 감을 잡을 수 있을 것입니다.

 

위에서 구한 x, y, w, h를 하나로 합해 줍니다.

 

지금까지 각 anchor 픽셀이 담당하는 영역을 픽셀 기준으로 뽑아냈습니다. 이를 원본 이미지에 대한 비율로 바꿔줍니다.

 

원래는 학습까지 한번에 진행하려 했지만 너무 복잡해 질 것 같아 모델 구현과 로스 계산으로 나누어 진행할 예정입니다.