Pytorch 로 YOLOv3 를 구현해 직접 만든 데이터셋을 활용해 이미지 디텍션을 시도했다. 이 깃헙을 바탕으로 파이썬 모듈을 생성했다. 그 과정에서 중요하다고 생각하는 개념 및 코드를 공유하고자 한다.
YOLOv3 의 경우 Darknet-53 를 backbone으로 하며 ResNet에서 사용하는 skip connection 을 사용한다. 또한 마지막에 detection 층을 추가했다. 아래 총 5 종류의 레이어로 구성되어 있다.
-
shortcut layers
- skip connection 정보를 저장한다. 해당 레이어들간 정보 흐름을 담당한다.
-
rout layers
- detection 단계에서 필요한 레이어 정보를 저장한다.
-
upsample layers
- detection 단계에서 필요한 upsampling 연산 정보를 저장한다.
-
detection layer
- YOLOv3 에선 총 3 개의 레이어를 사용한다.
- mask에 해당하는 인덱스의 anchor 정보를 가져와 해당 피쳐 맵의 앵커박스를 지정한다.
- 이를 통해 하나의 그리드셀당 3개의 앵커박스를 생성할 수 있게 한다.
-
3개의 크기가 다른 피쳐 맵에서 prediction이 이뤄지기 때문에 detection layer 의 아웃풋값을 같은 scale 로 맞춰 주는것이 필요하다.
-
이를 위해 predict_transform 함수를 사용한다.
-
한 피쳐 맵에서 grid 사이즈와 stride 는 같은 값을 가진다. ( 그리드 사이즈만큼 이동해서 anchor box 를 지정해야 하기 때문)
-
anchors 에 있는 수치는 anchor box의 너비와 높이를 의미하며, 이를 해당 grid size 로 나눠 비율을 구한다.
-
-
offset 을 지정하는 코드이다.
-
52 by 52 feature map 의 경우 (0,0), ... (51,51) 의 offset 행렬을 생성한다.
-
이후 그리드 상에서 바운딩 박스의 좌표(0~1사이 값)를 offset에 더해주며 최종 바운딩 박스의 좌표 정보를 구한다.
-
YOLOv1, v2 에서 겪었던 멀티라벨 문제를 해결하기 위해 클래스 확률을 구할 때 softmax에서 sigmoid 를 사용했다.
-
멀티라벨 문제란 하나의 사물이 여러개의 라벨을 가질 수 있음에도 불구하고, 하나의 사물에 하나의 라벨만 배정되는 문제를 말한다.
-
sigmoid 를 사용하게 되면 연산량도 줄어들뿐만아니라 멀티라벨 문제를 해결할 수 있어 복잡한 데이터셋에서도 좋은 성능을 나타낼 수 있다는 장점이 있다.