챕터 11 - Detection and Segmentation
강의 링크: YouTube
• • •
1. CV Task 종류
지금까지 강의에서는 주로 Image Classification만 다뤘다. 이미지 하나를 받아서 전체가 어떤 클래스에 속하는지 맞히는 문제다. 근데 실제 세상은 그것보다 훨씬 복잡하다. 이미지 안에 물체가 여러 개 있을 수도 있고, 각 물체가 정확히 어디에 있는지 알아야 할 수도 있고, 심지어 픽셀 단위로 분류해야 할 때도 있다.
11강에서는 그런 다양한 CV Task를 한꺼번에 다룬다. 크게 네 가지다.
Semantic Segmentation은 입력 이미지의 모든 픽셀에 카테고리 레이블을 붙이는 문제다. 고양이 사진이 있으면 "이 픽셀은 고양이, 이건 잔디, 이건 하늘" 식으로 픽셀마다 답을 내놓는다. 단, 같은 카테고리에 속하는 객체가 여러 개 있어도 구별하지 않는다는 게 포인트다. 두 마리 고양이가 있으면 둘 다 그냥 "고양이"다.
Classification + Localization은 이미지 안에 물체가 하나 있고, 그게 뭔지 분류하면서 동시에 어디에 있는지 bounding box로 표시하는 문제다. 물체 개수가 정해져 있다는 점에서 Object Detection과 다르다.
Object Detection은 이미지 안에 물체가 몇 개든 다 찾아서 각각에 bounding box와 클래스 레이블을 붙이는 문제다. 물체가 없을 수도 있고, 수십 개가 있을 수도 있다. 가변적인 출력 개수를 다뤄야 하기 때문에 단순한 regression 문제로 바꾸기가 쉽지 않다.
Instance Segmentation은 Object Detection + Semantic Segmentation이다. 각 물체를 bounding box로 검출하면서, 동시에 그 물체의 정확한 픽셀 영역(마스크)까지 함께 예측한다. 같은 카테고리의 물체가 여러 개 있어도 각각을 독립된 인스턴스로 분리한다는 점에서 Semantic Segmentation보다 어렵다.

▲ 네 가지 CV Task 비교 - Classification, Semantic Segmentation, Object Detection, Instance Segmentation (출처: cs231n Lecture 11)
• • •
2. Semantic Segmentation
슬라이딩 윈도우 방식의 한계
가장 단순하게 생각할 수 있는 아이디어는 이미지를 작은 패치로 잘라서 각 패치의 중심 픽셀 클래스를 분류하는 방식이다. 근데 이건 말이 안 되게 비싸다. 이미지의 모든 픽셀을 중심으로 패치를 잘라내고, 각각을 CNN에 따로 넣어야 하니까. 이웃 패치끼리 공유되는 연산도 전혀 재활용 못 한다.
Fully Convolutional Network
더 나은 방법은 FC layer를 완전히 없애고 전부 Convolution layer로만 네트워크를 구성하는 거다. 3×3 padding=1 conv를 쌓으면 공간 해상도를 유지하면서 특징을 뽑을 수 있다. 최종 출력은 C × H × W 텐서인데, C는 카테고리 수다. 모든 픽셀 위치에서 동시에 클래스 스코어를 뽑는 거다.
이렇게 하면 학습할 때 모든 픽셀에 대해 cross-entropy loss를 계산해서 end-to-end로 학습시킬 수 있다. 슬라이딩 윈도우 대비 훨씬 효율적이다.
Downsampling과 Upsampling

▲ Semantic Segmentation: 픽셀별 카테고리 레이블, 인스턴스 구별 없음 (출처: cs231n Lecture 11)
Downsampling과 Upsampling을 모두 네트워크 안에 두면 처음 해상도로 복원하면서 픽셀 단위 예측이 가능해진다.
근데 공간 해상도를 처음부터 끝까지 유지하는 건 메모리와 연산 측면에서 너무 비싸다. 실제로 쓰는 방법은 네트워크 중간에 downsampling으로 feature map을 압축했다가, 나중에 upsampling으로 다시 원본 해상도로 복원하는 구조다. 인코더-디코더 구조라고도 불린다.
Downsampling 방법은 두 가지다. 기존에 익숙한 Max Pooling과, stride=2로 설정한 Strided Convolution이다.
Upsampling은 그 반대인데, 몇 가지 방식이 있다.
Unpooling: Max Pooling을 뒤집는 개념이다. 가장 단순한 건 "Nearest Neighbor Unpooling"인데, 하나의 값을 그냥 주변 칸에 복사해서 크기를 늘리는 거다. "Bed of Nails" 방식은 특정 위치에만 값을 넣고 나머지는 0으로 채운다. 좀 더 정교한 건 Max Unpooling인데, Max Pooling 할 때 최댓값이 있던 위치를 기억해뒀다가, Unpooling 시 그 자리에만 값을 넣고 나머지는 0으로 채운다. 공간 정보를 어느 정도 보존할 수 있다는 장점이 있다.

▲ Semantic Segmentation용 FCN: Downsampling + Upsampling 대칭 구조 (출처: cs231n Lecture 11)
Transpose Convolution: "Learnable upsampling"이라고도 불린다. Strided Convolution이 input의 각 값에 필터를 곱해서 output에 더하는 방식인데, Transpose Convolution은 그 반대다. input의 값 하나가 filter 크기만큼의 output 영역에 영향을 준다. stride가 output에서의 간격이 된다. 겹치는 영역은 합산한다. 이 필터 가중치도 학습이 되기 때문에 단순 interpolation보다 더 세밀한 복원이 가능하다.

▲ Max Unpooling: Pooling 시 max 위치를 기억해뒀다가 복원 시 해당 위치에만 값을 넣는다 (출처: cs231n Lecture 11)

▲ Transpose Convolution (stride 2): input 값이 filter 가중치로 output 영역에 뿌려지고, 겹치는 곳은 합산된다 (출처: cs231n Lecture 11)

▲ Normal Conv(stride 2)는 input을 훑으며 output을 줄이고, Transpose Conv(stride 2)는 input 값 하나가 output 영역에 뿌려진다. 겹치는 부분은 합산 (직접 제작)
Transpose Convolution을 수학적으로 이해하려면 stride=1, padding=0인 경우를 먼저 보자. 입력 크기가 a, 필터 크기가 k면 출력은 a+k-1이 된다. stride=2이면 입력에서 각 값 사이에 빈 공간(stride-1개의 0)이 생긴다고 생각하면 된다. 이 이름 때문에 혼란이 생기는데, "Deconvolution"이라고도 불리지만 실제로는 Convolution의 수학적 역연산이 아니다. 그냥 learnable upsampling이라고 생각하면 충분하다.
• • •
3. Classification + Localization
이제 픽셀 단위가 아니라 객체 단위 문제로 넘어간다. Classification + Localization은 이미지 안에 물체가 정확히 하나 있다고 가정하고, 그게 뭔지 맞히는 동시에 어디 있는지 bounding box 좌표 네 개로 표시하는 문제다.
구조 자체는 단순하다. 기존 분류용 CNN의 FC layer 뒤에 head를 두 갈래로 나눈다. 하나는 클래스 스코어를 내는 Softmax head고, 나머지는 bounding box 좌표 네 개 (x, y, w, h)를 뱉는 Regression head다. 각각의 loss를 더해서 한 번에 학습시킨다.

▲ Classification + Localization: CNN feature에서 두 갈래로 분기 - Softmax Loss (cls) + L2 Loss (bbox) (출처: cs231n Lecture 11)
이걸 Multitask Loss라고 한다. 분류 loss는 cross-entropy, bounding box loss는 L2 regression loss다. 두 loss의 스케일이 달라서 가중치 를 잘 맞춰줘야 한다는 게 실용적인 골칫거리다.
이 아이디어는 사람의 자세 추정(Pose Estimation)에도 똑같이 쓸 수 있다. 사람 관절 위치 K개의 좌표를 예측하는 regression 문제로 바꾸면 된다. 입력 이미지에서 CNN으로 feature를 뽑고, 거기서 2K개의 실수값(각 관절의 x, y)을 regression하면 전신 포즈를 추정할 수 있다.
• • •
4. Object Detection: R-CNN 계열
Object Detection은 이미지 안에 물체가 몇 개든 찾아야 하는 문제다. 고양이 한 마리면 출력이 4개(bbox 좌표)지만, 강아지 세 마리 고양이 한 마리면 출력이 16개가 된다. 이미지마다 출력 크기가 달라지니까 단순 regression으로는 접근이 안 된다. 어디를 봐야 할지 결정하는 것과 거기에 뭐가 있는지 분류하는 것, 이 두 가지를 동시에 해결해야 한다.
R-CNN
2014년 Girshick et al.이 제안한 R-CNN(Rich feature hierarchies for accurate object detection)은 딥러닝 기반 detection의 시작점이다.
먼저 Selective Search같은 Region Proposal 알고리즘으로 "물체가 있을 법한 영역" 약 2000개를 추려낸다. 이걸 Region Proposal이라고 한다. 그 다음 각 proposal을 고정 크기(227×227)로 warp해서 CNN에 넣고 feature를 뽑는다. 뽑힌 feature로 SVM 분류기를 돌려서 클래스를 결정하고, 별도의 regression으로 bounding box를 정교하게 조정한다.
문제는 느리다는 거다. 이미지 하나에 proposal 2000개를 CNN에 따로 넣으니 VGG16 기준으로 추론에 47초가 걸린다. 학습은 84시간이다. 학습 파이프라인도 복잡하다. CNN fine-tuning, SVM 학습, bbox regression 학습이 다 따로 돌아가는 ad-hoc 구조다.

▲ R-CNN 파이프라인: Region Proposal → CNN Feature → SVM + BBox Regression (출처: cs231n Lecture 11)
Fast R-CNN
R-CNN의 핵심 비효율은 이미지당 CNN을 2000번 돌린다는 거다. Fast R-CNN은 이걸 뒤집는다. 먼저 전체 이미지를 CNN에 한 번만 통과시켜서 전체 feature map을 만든다. 그 다음 Region Proposal을 feature map 위에 projection해서, 각 proposal에 해당하는 feature 영역만 잘라낸다.
문제는 proposal마다 feature map 영역 크기가 제각각이라는 거다. 이걸 해결하는 게 RoI Pooling(Region of Interest Pooling)이다. 어떤 크기의 RoI가 들어와도 고정 크기 feature(예: 7×7)로 변환해준다. 이후 FC layer에서 classification과 bbox regression을 동시에 수행한다. 하나의 네트워크로 end-to-end 학습이 가능해진다.

▲ Fast R-CNN: 전체 이미지를 CNN에 1번 통과 후 RoI Pooling으로 고정 크기 feature 추출 (출처: cs231n Lecture 11)
결과적으로 학습은 R-CNN 대비 10배, 추론은 제안 알고리즘 제외 시 약 150배 빨라진다. 근데 여전히 bottleneck이 있다. Region Proposal 자체를 Selective Search라는 CPU 기반 알고리즘으로 뽑기 때문에, CNN 연산은 빨라졌는데 거기서 시간이 다 잡아먹힌다.
Faster R-CNN
그럼 Region Proposal도 딥러닝으로 하면 되지 않나. Faster R-CNN이 바로 그 아이디어다. Region Proposal Network(RPN)을 추가해서 feature map 위에서 직접 proposal을 생성한다.
RPN은 feature map 위를 슬라이딩 윈도우로 돌면서 각 위치마다 여러 개의 Anchor Box를 기준으로 "여기에 물체가 있는가(objectness score)"와 "bounding box 조정값(bbox regression)"을 동시에 예측한다. Anchor box는 미리 정해둔 다양한 크기와 비율의 기준 박스다. 보통 3가지 크기 × 3가지 비율 = 9개의 anchor를 각 위치마다 사용한다.
이렇게 뽑은 proposal은 Fast R-CNN과 동일한 RoI Pooling + classifier 구조로 처리한다. CNN backbone을 RPN과 detector가 공유하기 때문에 거의 비용 없이 proposal을 얻을 수 있다. VGG16 기준으로 추론 속도가 5fps 수준이 되고, 정확도도 올라간다.

▲ Faster R-CNN: CNN backbone 공유 + RPN으로 proposal 생성 (출처: cs231n Lecture 11)
Faster R-CNN은 하나의 네트워크에서 loss가 네 개 동시에 흐른다. RPN의 objectness 분류 loss, RPN의 bbox regression loss, 최종 detector의 클래스 분류 loss, 최종 detector의 bbox regression loss. 복잡해 보이지만 CNN backbone을 전부 공유하니까 실제로 학습이 불가능한 구조는 아니다.
이 흐름 전체를 묶어서 Two-Stage Detector라고 부른다. 1단계에서 어디를 볼지 후보를 추리고, 2단계에서 그 후보 각각을 분류하고 정제하는 구조다. 정확도가 높은 대신 속도를 포기한 트레이드오프다.
• • •
5. Object Detection: Single-Stage 방법
Two-Stage에서 first stage를 없애면 어떻게 될까. 이미지를 보고 바로 bounding box와 클래스를 예측하면 훨씬 빠를 거다. 이게 Single-Stage Detector의 핵심 아이디어다.
YOLO
YOLO(You Only Look Once)는 detection을 regression 문제로 재정의한다. 이미지를 S×S 그리드로 나누고, 각 그리드 셀이 B개의 bounding box 예측값(x, y, w, h, confidence)과 C개의 클래스 확률을 동시에 출력한다. 이미지를 딱 한 번 CNN에 통과시키면 끝이다.
실제로는 각 그리드 셀에서 anchor box 개념을 사용해서 다양한 크기의 물체를 처리한다. 이미지 전체를 한 번에 보기 때문에 맥락 정보를 활용할 수 있어서 false positive가 줄어드는 장점도 있다.
속도가 매우 빠르다. 초창기 YOLO는 45fps가 가능했고, Fast YOLO는 155fps. 정확도가 Two-Stage 대비 낮지만, real-time detection이 필요한 상황에 쓸 수 있다는 게 큰 장점이다.
SSD
SSD(Single Shot MultiBox Detector)는 YOLO처럼 single-stage지만 다중 해상도 feature map을 사용한다. CNN의 다양한 layer에서 feature map을 뽑아서 각 해상도에서 독립적으로 detection을 수행한다. 앞쪽 layer는 해상도가 높아서 작은 물체를, 뒤쪽 layer는 해상도가 낮아서 큰 물체를 잡는 데 유리하다. 이 덕분에 YOLO보다 정확도와 속도의 균형이 더 좋다.

▲ Two-Stage vs Single-Stage Detector 비교 (출처: cs231n Lecture 11)
결국 trade-off다. Two-Stage는 정확하지만 느리고, Single-Stage는 빠르지만 정확도가 다소 낮다. 어느 쪽이 맞냐는 정답이 없고, 자율주행처럼 실시간성이 생사를 가르는 상황이면 single-stage, 의료 영상처럼 한 픽셀 오차도 용납 안 되는 상황이면 two-stage가 선택지가 된다. 요즘은 두 방식의 경계가 점점 흐려지고 있긴 하지만.
• • •
6. Instance Segmentation: Mask R-CNN
Object Detection은 물체 위치를 bounding box로 표현한다. 근데 박스는 물체 모양을 정확히 담지 못한다. Instance Segmentation은 한 발 더 나아가서 물체의 정확한 픽셀 마스크까지 예측한다.
11강의 마무리는 Mask R-CNN이다. 이름 그대로 Faster R-CNN에 mask prediction 브랜치를 추가한 구조다.
Mask R-CNN 구조
Faster R-CNN의 두 번째 stage를 떠올려보자. RoI Pooling 후에 classification head와 bbox regression head가 있었다. Mask R-CNN은 여기에 세 번째 head, 즉 mask prediction head를 병렬로 추가한다.
mask head는 각 RoI마다 28×28 크기의 binary mask를 클래스 수만큼 출력한다. 클래스별로 독립적인 마스크를 예측하고, 최종 클래스 예측은 별도의 classification head가 담당한다. 이렇게 분리하면 classification과 segmentation 사이의 간섭이 줄어든다.

▲ Mask R-CNN: Faster R-CNN + 병렬 Mask Head 구조 (출처: cs231n Lecture 11)
RoI Align
Faster R-CNN에서 RoI Pooling은 feature map 좌표를 정수로 snap한다. 즉, proposal 좌표를 가장 가까운 정수 픽셀로 반올림해버린다. bounding box 예측에서는 이 오차가 크게 문제가 안 되지만, 픽셀 단위 마스크 예측에서는 이 작은 misalignment가 정확도를 크게 낮춘다.
Mask R-CNN이 제안한 해결책이 RoI Align이다. 정수로 snap하지 않고 bilinear interpolation으로 정확한 픽셀 값을 계산한다. 이 작은 변화가 mask quality를 크게 개선한다.
확장성
Mask R-CNN의 또 다른 강점은 확장성이다. mask head 대신 keypoint head를 붙이면 사람 자세 추정(pose estimation)도 가능하다. 각 관절 위치를 one-hot map으로 예측하는 head를 추가하면 Faster R-CNN 프레임워크 안에서 detection + pose estimation을 동시에 할 수 있다. 실제로 논문에서 COCO keypoint 벤치마크에서도 당시 최고 성능을 냈다.

▲ Mask R-CNN 결과: 각 인스턴스마다 별도의 마스크와 bbox 출력 (출처: cs231n Lecture 11)

▲ Mask R-CNN의 확장: keypoint head를 추가하면 동일 프레임워크에서 pose estimation도 가능하다 (출처: cs231n Lecture 11)
11강을 한 줄로 압축하면, "이전 걸 재활용하고 조금 더 붙인다"는 패턴의 반복이다. R-CNN에 feature sharing을 붙이면 Fast R-CNN, 거기에 RPN을 붙이면 Faster R-CNN, 또 mask head를 붙이면 Mask R-CNN이 된다. 각 논문이 전 논문의 병목 하나씩을 정확히 짚어서 해결했다는 게 인상적이다. CV 태스크 자체도 Classification에서 시작해서 Localization, Detection, Segmentation 순으로 점점 공간 정보를 더 세밀하게 다루는 방향으로 확장되는데, 각 단계의 핵심 아이디어가 다음 단계의 재료가 된다.
• • •
핵심 요약
| Task | 출력 형태 | 핵심 방법 |
|---|---|---|
| Semantic Segmentation | 픽셀별 클래스 레이블 (H×W) | FCN, Downsampling + Upsampling (Transpose Conv) |
| Classification + Localization | 클래스 + bbox 좌표 4개 | Multitask Loss (cls + regression) |
| Object Detection | 가변 개수의 bbox + 클래스 | R-CNN → Fast R-CNN → Faster R-CNN (Two-Stage) / YOLO, SSD (Single-Stage) |
| Instance Segmentation | bbox + 픽셀 마스크 (인스턴스별) | Mask R-CNN (Faster R-CNN + Mask Head + RoI Align) |
| 방법 | Stage | 특징 | 속도 vs 정확도 |
|---|---|---|---|
| R-CNN | Two-Stage | Selective Search + 개별 CNN forward | 느림 (47s/img), 높은 정확도 |
| Fast R-CNN | Two-Stage | Shared feature map + RoI Pooling | R-CNN 대비 213× 빠름 |
| Faster R-CNN | Two-Stage | RPN으로 proposal 생성, end-to-end | 5fps, 높은 정확도 |
| YOLO | Single-Stage | Grid 기반 regression, 이미지 1회 forward | 45+fps, 정확도 다소 낮음 |
| SSD | Single-Stage | 다중 해상도 feature map 활용 | 속도-정확도 균형 |
| Mask R-CNN | Two-Stage | Faster R-CNN + Mask Head + RoI Align | 5fps, Instance Seg 가능 |
• • •
참고
- cs231n Lecture 11 - Detection and Segmentation (YouTube)
- Girshick et al., "Rich feature hierarchies for accurate object detection and semantic segmentation" (R-CNN, CVPR 2014)
- Girshick, "Fast R-CNN" (ICCV 2015)
- Ren et al., "Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks" (NIPS 2015)
- Redmon et al., "You Only Look Once: Unified, Real-Time Object Detection" (CVPR 2016)
- Liu et al., "SSD: Single Shot MultiBox Detector" (ECCV 2016)
- He et al., "Mask R-CNN" (ICCV 2017)
- Long et al., "Fully Convolutional Networks for Semantic Segmentation" (CVPR 2015)
• • •
다음 포스팅: 챕터 12 - Visualizing and Understanding
CNN이 실제로 무엇을 보는지, 학습된 feature를 시각화하는 방법을 다룬다.