i) Object Measurement

이미지에 나타난 객체의 크기를 알고싶을 수 있다.
단지 pixel수를 세어서는 크기를 알아낼 수 없기에 객체의 크기를 정교하게 측정하는 방법이 필요하다.
 Imaginea Labs에서 제안한 방법에 따라 사진상의 객체를 측정하는 과정을 단계별로 알아보자.
🤔 Reference Object
client의 사진만으로 신발사이즈를 추천해보자.
발치수 예측모델의 추론 시, 다양한 발자국 이미지를 처리하기에 Augmentation이 필수적이다.
또한, 카메라와 종이의 거리같은 요인또한 존재하기에 효과적인 solution을 만들기란 쉽지않다.
이런 scale문제는 거의 모든 client가 갖는 참조객체(Reference Object)를 image에 포함시켜 간단히 해결할 수 있다.
고객 대부분은 표준크기의 카드를 갖고 있을 것이므로 이를 보정객체(calibration object)로 활용할 수 있다.
좌측보다 우측이 좀 더 확대된 이미지
즉, 참조대상을 추가시켜 이를 해당 객체와 발을 비교하는 것으로 단순화시키는 것이다.

 

🤔 Segmentation
모델은 먼저 image를 2가지로 세분화해 추출해야한다.
 ∙ 신용카드
 ∙ 발자국
이를 위해 Mask R-CNN을 사용한다.
Mask분기를 통해 발자국, 신용카드 각각에 대한 마스크를 예측해 위 그림 우측처럼 유사한 결과를 얻는다.

이제 우린 위의 예측된 마스크를 아래처럼 개별적인 각각의 마스크로 볼 수 있다.
이제, 올바른 측정값을 얻기 위해 Mask들을 정렬해야한다.

 

🤔 회전수정
Mask를 얻은 후 회전에 대한 정규화를 수행해야한다.
회전을 수정하기 위해 각 Mask에 대해 PCA로 Eigen Vector값을 얻는다.
가장 큰 고유벡터의 방향의 객체의 크기 = 객체의 길이.
PCA의 특성상2번째 주성분부터의 고유벡터는 분산에 대한 기여도가 점점 줄어든다.
PCA이전, Mask의 차원은 좌측그림처럼 원본 이미지에 대한 차원축을 갖는 vector space에 존재한다.
PCA이후, 고유벡터들이 다른 vector space basis에 위치, 축이 가장 큰 분산의 방향을 따른다(우측그림).
 원래 좌표축과 첫번째 고유벡터사이의 각도를 이용해 얼마나 회전보정해야하는지 결정할 수 있다.

 

🤔 비율 및 측정
회전수정된 Mask를 통해 이제 발자국 측정이 가능하다.
❗️ 발자국과 신용카드의 측정값은 cm가 아닌, pixel단위라는 점에 유의
신용카드의 정확한 치수만 알면 필셀치수와 카드의 실제치수 사이 비율을 통해 신발 치수를 예측, client에게 제공해줄 수 있다.

 

 

 

 

 

 

 

 

 

 

ii) Counting

🤔 Filter 분해
아래 사진에서 포도의 알은 몇개일까?
지금까지의 소개한 개념을 기초로, 아래 접근방식 중 하나를 취할 수 있다.
  • Detection Classifier를 훈련, 열매를 검출, Bbox개수세기
    (박스가 열매를 합쳐버릴 수 있다는 단점)

  • Segmentation방법으로 접근, 군집의 속성에 따라 열매개수결정.
    (열매가 너무 작거나 크면 잘못된 결과 초래.)
    즉, 참조객체를 활용하기 곤란.

  • Regression문제로 접근, image자체로써의 열매수 측정.
    Segmentation처럼 scale문제가 존재.
1,2의 경우, 올바르게 분류되어야 함을 유의해야하고
3의 경우 회귀는 위치를 무시하는데, 위치정보는 이미지에서 중요하기에 이를 유의.

Sol) 밀도추정기술

 

🤔 밀도 추정
객체가 작고 겹치는 상황을 위해 2010년 제안된 논문.
이 방법은 Detection, Segmentation을 수행하지 않고, 위치정보도 잃지 않는다.

[Main Idea]
이미지의 patch에 있는 객체의 밀도를 추정하도록 신경망을 학습!
밀도추정을 위해 밀도를 나타내는 라벨이 필요. → 여기서는 열매 중심을 라벨로 지정.
즉, 신경망이 이 라벨을 추정하는 법을 배우는 것이다.

다만, 일부 열매는 patch에 부분적으로 걸쳐있을 수 있다.
→ 모델에 대한 grid입력 > patch_size

 

 

 

 

 

 

iii) Pose Estimation

🤔 Pose Estimation이란?
사람의 자세를 식별하기 위해 팔꿈치, 무릎, 얼굴 등을 식별하는 것. 
사람이 앉아있는지, 서있는지 등의 자세판별이 가능해 다음과 같은 곳에서 활용가능하다.

Papandreous et al; 2018

🤔 PoseNet
[1단계]

∙ Detection모델을 사용해 Interest point의 Heatmap을 식별
(일반적인 Interest point: 관절(joint or landmark), 눈, 코 등)
(Heatmap: Detection모델 classifier head에서 출력되는 점수 = threshold지정 이전값)

[2단계]
∙ Detect된 각 joint를 기준, 근처 joint의 가장 가능성있는 위치 식별.

[3단계]
∙ Hough Transform이라는 Weighted Voting Mechanism으로 1,2단계에 따라 선택된 Joint기반, pose검출.
이때, 2,3단계는 다양한 joint탐지를 위해 단순 detection모델로는 충분치 않기에 필수적이다.
그렇기에 joint와 joints사이의 offset도 예측하는 것이다.

 

🤔 다중객체의 pose estimation
단일 이미지에서 여러사람의 pose estimation을 위해 위의 step에 몇가지 기술추가가 필요하다.

1. segmentation모델을 활용, 사람에 해당하는 모든 pixel 식별
2. joint조합을 참고해 가장 가능성 높은 신체부위 식별
3. 각 사람에게 사람 pixel을 할당.
(1에서 찾은 mask의 Pixel과 2에서 식별한 가능성높은 joint를 이용.)

 

🧐 Human Pose Estimation 방식

1) Top-Down 방식

: 사람을 먼저 Detect → Detect된 자세를 추정.

정확도가 Bottom-up방식보다 높음.
검출된 사람들을 순회하며 joint들을 찾기에 속도가 Bottom-up방식보다 느리다
보통 저해상도에서 고해상도로 과정이 수행

즉, object detector를 사용해, 개별 instance를 식별(identifying), localizing → 한 사람의 포즈를 추정. 

ex) AlphaPose, Mask-RCNN


2) Bottom-Up 방식

joint를 먼저 Detect → 서로 연결해 자세를 추정.
정확도는 Top-down 방식에 비해 떨어짐.

Object Detection 과정이 없어 속도가 빨라 실시간 처리에 사용 가능
보통 고해상도에서 저해상도로 과정이 수행

즉, 확인되지 않은(identity-free) 의미론적 실체(semantic entities)를 지역화→사람 인스턴스로 그룹화

ex) OpenPose

cf) Pose Estimation Guideline

 

Pose Estimation Guide - Fritz ai

Almost everything you need to know about how pose estimation works Pose estimation is a computer vision technique that predicts and tracks the location of a person or object. This is done by looking at a combination of the pose… Continue reading Pose Est

fritz.ai

 

 

 

 

 

 

 

 

 

 

 

iv) Image Search

[핵심아이디어]: 서로 유사한 이미지에 서로 가까운 embedding이 있다.

🤔 분산 검색
유사한 임베딩 검색을 위해선?
Dataset의 image embedding에 대한 Search Index를 생성해야한다.
이 embedding index를 대규모분산데이터웨어하우스에 저장한다 가정하자.
이때, embedding과 다른 모든 embedding간의 유클리드 거리를 계산하고 가장가까운 일치항목을 표시한다.

 

🤔 빠른 검색
위의 예제에서 대규모데이터웨어하우스는 효율적 검색이 가능하지만
latency가 긴 경향이 있기에 ms로 응답시간을 얻을 수 없다.

실시간 serving을 위해 더 나은 유사 embedding searching방법을 찾아야한다.
이를 위해 ScaNN(Scalable Nearest Neighbors)를 사용할 수 있다.

 

🤔 더 나은 임베딩
더 맞춤화된 embedding을 사용할 수 있다.
ex) 얼굴유사성을 검색할 때, 얼굴을 식별하고 확인하도록 훈련된 모델의 embedding이 일반 embedding보다 더 성능이 좋다.

FaceNet:
목적: facial search
embedding최적화를 위해 얼굴특징을 기반
정렬된 일치/불일치 얼굴패치의 삼중항(triplet)을 사용.
삼중항: 일치하는 얼굴섬네일 2개 + 일치안하는 얼굴섬네일 1개

Triplet Loss:
가능한 최대거리만큼 양성쌍과 음성쌍을 분리하는 것이 목표인 함수.
라벨로 함께 군집화한 embedding생성에 사용가능.

<아래 3개의 image>로 정의된다.
 anchor이미지, 같은 label의 다른 이미지(두번째 이미지와 anchor가 양성쌍을 형성)
 다른 label을 갖는 3번째 이미지(세번째 이미지와 anchor는 음성쌍을 형성)
세 이미지에 대해 삼중항 (a,p,n)손실은 거리 d(a,p)가 0을 향하고
거리 f(a,n)이 f(a,p)보다 일정한 여유만큼 더 크게 정의된다.
이때,&nbsp; &alpha; 는 margin(= positive와 negative의 거리)을 의미.
이 손실에 대해 음성은 3가지로 나뉜다.
 Hard Negative: 양성보다 앵커에 더 가까움
 Easy Negative: 앵커에서 아주 멀리 떨어져있음

 Semi-Hard Negative: 양성보다는 멀리있으나 여유거리내에 있음

Linear Layer추가 후, Semi-Hard Negative에 초점을 맞춰 해당이미지의 삼중항손실을 최소화하도록 모델을 훈련시켜 embedding을 개선시킬 수 있다.
결과적으로 결과 embedding이 유사한 label로 clustering된다.

 

 

 

 

 

 

 

v) ETC (InternImage)

 

[논문 review] - InternImage(2023): Exploring Large-Scale Vision Foundation Models withDeformable Convolutions

📌 InternImage [CVPR 2023] InternImage: Exploring Large-Scale Vision Foundation Models with Deformable Convolutions Paperswithcode 홈페이지에서 Detection, Segmentation 등 많은 Benchmark Dataset에서 최고의 성능(SOTA)를 달성한 (무친

chan4im.tistory.com

 

 

 

📌 목차

1. YOLO v3로 정지영상에서 Object Detection하기
2. YOLO v3로 비디오에서 Object Detection하기(랩탑 캠사용)

 

0.  파일준비 및 YOLO v3 공통코드

먼저 자신의 로컬 폴더에 다음 3개의 파일이 있어야한다.
'coco_names.txt' (이 파일은 1~80행까지 복사후 txt파일을 생성해 붙여넣는다.)
'yolov3.weights'
'yolov3.cfg'


이후 아래 코드에 대해 설명해보겠다.
- 5~13행: YOLO 모델 구성함수
- 15~38행: YOLO모델로 img영상에서 물체탐지 후 반환하는 함수
def construct_yolo_v3():
    f=open('coco_names.txt', 'r')
    class_names=[line.strip() for line in f.readlines()]

    model=cv.dnn.readNet('yolov3.weights','yolov3.cfg')
    layer_names=model.getLayerNames()
    out_layers=[layer_names[i-1] for i in model.getUnconnectedOutLayers()]
    
    return model,out_layers,class_names

def yolo_detect(img,yolo_model,out_layers):
    height,width=img.shape[0],img.shape[1]
    test_img=cv.dnn.blobFromImage(img,1.0/256,(448,448),(0,0,0),swapRB=True)
    
    yolo_model.setInput(test_img)
    output3=yolo_model.forward(out_layers)
    
    box,conf,id=[],[],[]		# 박스, 신뢰도, 클래스 번호
    for output in output3:
        for vec85 in output:
            scores=vec85[5:]
            class_id=np.argmax(scores)
            confidence=scores[class_id]
            if confidence>0.5:	# 신뢰도가 50% 이상인 경우만 취함
                centerx,centery=int(vec85[0]*width),int(vec85[1]*height)
                w,h=int(vec85[2]*width),int(vec85[3]*height)
                x,y=int(centerx-w/2),int(centery-h/2)
                box.append([x,y,x+w,y+h])
                conf.append(float(confidence))
                id.append(class_id)
            
    ind=cv.dnn.NMSBoxes(box,conf,0.5,0.4)
    objects=[box[i]+[conf[i]]+[id[i]] for i in range(len(box)) if i in ind]
    return objects

model,out_layers,class_names=construct_yolo_v3()		# YOLO 모델 생성
colors=np.random.uniform(0,255,size=(len(class_names),3))	# 클래스마다 색깔​

 

05~13행의 construct_yolo_v3 함수를 살펴보자.
∙ 06~07행은 COCO 데이터셋의 클래스이름을 담고 있는 coco_names. txt 파일에서 클래스 이름을 읽어 class_names에 저장한다.

09행은 YOLO v3 모델 정보를 파일에서 읽어 yolo_model 객체에 저장한다.

yolov3.weights 파일에서는 신경망의 가중치 정보를 읽어오고 yolov3.cfg 파일에서는 신경망의 구조 정보를 가져온다.

10~11행은 getUnconnectedOutLayers 함수를 이용하여 yolo 82, yolo 94, yolo_106 층을 알아내어 out_layers 객체에 저장한다.

13행은 모델, 층, 클래스 이름을 담은 객체를 반환한다.


15~38행의 yolo_detect 함수를 살펴보자.
16행은 원본 영상인 img의 높이와 너비 정보를 height와 width에 저장한다.

17행은 OpenCV의 blobFromImage 함수로 영상을 YOLO에 입력할 수 있는 형태로 변환해 test_img에 저장한다.
이 함수는 [0,255] 범위의 화솟값을 [0,1]로 변환하고 영상 크기를 448 X 448로 변환하며 BGR 순서를 RGB로 바꾼다.원본 영상은 img에 남아있다.

19행은 test_img에 저장되어 있는 영상을 신경망에 입력한다.

20행은 신경망의 전방 계산을 수행하는데, out layers가 출력한 텐서를 output3 객체에 저장한다.
이로 인해 Ouput3 객체는 아래 3가지 텐서를 갖는다.
14×14×85×3,
28×28×85×3,
56×56×85×3 

 22~34행은 output3 객체로부터 물체 위치를 나타내는 박스 정보와 함께 물체 클래스와 신뢰도 정보를 추출한다.
22행은 박스와 신뢰도, 클래스정보를 저장할 리스트를 생성한다.
23행은 세 개의 텐서를 각각반복 처리하며
24행은 85차원 벡터를 반복 처리한다.
85 차원 벡터는 (x, y, w, h,o, p1. p2, … p80)으로 표현되며
앞의 네 요소는 박스, o는 신뢰도, 뒤의 80개 요소는 클래스확률이다.

 25~27행은 뒤의 80개 요소 값에서 최고 확률에 해당하는 클래스를 알아내 클래스 번호는 class_id, 확률은 confidence에 저장한다.

 28행은 confidence가 0.5보다 크지 않으면 버린다.
0.5보다 크면 29~31행에서 [0,1] 범위로 표현된 박스를 원래 영상 좌표 계로 변환해
왼쪽 위의 위치를 x와 y, 너비와 높이를 w와 h에 저장한다.

 32~34행은 박스와 신뢰도, 클래스 정보를 리스트에 추가한다. 박스는 왼쪽 위와 오른쪽 아래 구석 좌표를 저장한다.


 22~34행으로 검출한 박스들에는 상당한 중복성이 있다.
즉, 이전시간에 설명한 그림에서 빨간색 유니폼 선수를 검출한 박스가 검은색 칸에만 나타나지 않고 그 주위에 여럿 나타나는 현상이다.

 36행의 NMSBoxes 함수는 박스를 대상으로 비최대 억제를 적용해 중복성을 제거한다.

 37행 은 비최대 억제에서 살아남은 박스의 위치, 신뢰도, 클래스 이름을 모아 objects 객체에 저장한다.

 38행은 objects를 반환한다.

∙ 40행은 contruct yolo_v3 함수로 YOLO 모델을 구성한다.

∙ 41 행은 물체 클래스를 고유한 색으로 표시하기 위해 컬러 목록을 만들어 colors 객체에 저장한다.

 

 

 


1. YOLO v3로 정지영상에서 Object Detection하기

메인 프로그램이 시작되는 
∙ 43행은 입력 영상을 읽어 img에 저장한다.
∙ 46행은 yolo_detect 함수로 원본 영상 img에서 물체를 검출해 res에 저장한다.
∙ 48~52행은 res에 있는 박스와 클래스 이름, 신뢰도를 영상에 표시한다.

프로그램 실행 결과를 보면, 왼쪽과 오른쪽 선수를 각각 100%와 94.1% 신뢰도의 person 클래스로 제대로 검출했다.
또한 축구공을 99.9% 신뢰도로 sports ball 클래스로 옳게 검출했다.
img=cv.imread('soccer.jpg')
if img is None: sys.exit('파일이 없습니다.')

res=yolo_detect(img,model,out_layers)	# YOLO 모델로 물체 검출

for i in range(len(res)):			# 검출된 물체를 영상에 표시
    x1,y1,x2,y2,confidence,id=res[i]
    text=str(class_names[id])+'%.3f'%confidence
    cv.rectangle(img,(x1,y1),(x2,y2),colors[id],2)
    cv.putText(img,text,(x1,y1+30),cv.FONT_HERSHEY_PLAIN,1.5,colors[id],2)

plt.imshow(img[...,::-1])

 

 

 

 

 

 

 

 

 

 

 

 


2. YOLO v3로 비디오에서 Object Detection하기 (랩탑 캠사용)

∙ 43~64행은 웹 캠에서 비디오를 읽어 디스플레이하는 코드에 YOLO를 적용한다.
∙ 50행은 비디오에서 획득한 현재 프레임을 yolo_detect 함수에 입력해 물체를 검출하고 결과를 res에 저장한다.
∙ 52~56행은 검출한 물체 정보를 영상에 표시한다. 
cap=cv.VideoCapture(0)
if not cap.isOpened(): sys.exit('카메라 연결 실패')

while True:
    ret,frame=cap.read()
    if not ret: sys.exit('프레임 획득에 실패하여 루프를 나갑니다.')
        
    res=yolo_detect(frame,model,out_layers)   
 
    for i in range(len(res)):
        x1,y1,x2,y2,confidence,id=res[i]
        text=str(class_names[id])+'%.3f'%confidence
        cv.rectangle(frame,(x1,y1),(x2,y2),colors[id],2)
        cv.putText(frame,text,(x1,y1+30),cv.FONT_HERSHEY_PLAIN,1.5,colors[id],2)
    
    cv.imshow("Object detection from video by YOLO v.3",frame)
    
    key=cv.waitKey(1) 
    if key==ord('q'): break

 

📌 목차

1. Metric (IoU(Jaccard Similarity) , mAP , PR-curve , ROC-curve)
2. Traditional Detection Method

3. CNN : RCNN 계열 (RCNN, fast RCNN, faster RCNN)
4. CNN : YOLO 계열
5. Transformer : DETR , SETR
6. Backbone Transformer : Swin Transformer

Object Detection기술 발전과정이 잘 정리된 추천 Survey논문

∙ [Liu 2018]

∙ [Jiao 2019]

∙ [Zaidi 2021]

 

 

 

 

 

 

 

 

 

 

 

 


1. Metric (IoU, mAP, PR-curve, ROC-curve)

preview

Detection모델은 영상의 물체(object)를 Bbox(Bounding_Box)라는 직사각형으로 지정한다.
이때, Box마다 classconfidence를 출력한다.

PASCAL VOC대회, COCO 대회 등에서 성능을 주로 mAP로 측정한다.
IoU→AP→mAP 순으로 계산이 되기에 IoU부터 알아보고자 한다.
추천 Survey 논문: [Padilla 2020]

 

 

1.1 IoU (Intersection Over Union)

AP(Average Precision)는 IoU를 기반으로 계산되므로 IoU에 대해 알아보자.
아래 식은 IoU에 대한 식을 정의한다.
IoU는 Jaccard Similarity, Jaccard Index라고도 불리는데, 이는 기본적으로 prediction과 target간의 percent overlap을 정량화하는 방법이다.
실제로는 Object에 Bbox가 여럿 나타나 복잡한 상황이 된다.
∙ 참값 하나가 여러 예측과 겹치거나
∙ 예측이 여러 참값과 겹치고 겹침이 없거나.

 

 

1.2 AP. &  mAP

AP (Average Precision)

AP는 위와 같은 상황(Bbox가 여럿 나타나는 상황)에서 계산한다.
AP계산을 위해 TP, FP, FN을 세야한다. cf) True = 맞춘것을 의미

AP 계산알고리즘:
① 신뢰도 임계값을 넘는 Bbox만 선택, 예측목록을 생성
② 예측목록에 있는 Bbox를 신뢰도로 정렬
③ Confidence값이 큰 순서대로 처리.
현재 Bbox가 IoU 임계값을 넘으면 TP로 판정, 아니면 FP로 판정


❗️이때, 2개 이상의 물체에 하나의 Bbox가 겹치게 된다면?
IoU가 최대인 쌍을 사용한다.
TP발생 시, 참값목록에서 TP_Bbox를 제거, 이중의 쌍을 맺는 것을 방지한다.
이때, 예측목록에 있는 Bbox를 모두처리후, 쌍을 맺지못한 채 남아있는 TP_Bbox는 FN으로 판정한다.

 

 

mAP (mean Average Precision)

AP를 각 물체 class에 대해 계산 → 이 AP를 모든 class에 대해 평균한 값이다.

아래 예시를 살펴보자.
먼저, Precision과 Recall은 아래수식처럼 구할 수 있다.

즉, True = 맞춘것을 의미하므로 Precision과 Recall은 아래처럼 설명할 수 있다.
∙ Precision = (맞춘것=TP) / (예측한 것 중 = ?P)
∙ Recall = (맞춘것=TP) / (실제 중)

먼저 mAP를 구하는 순서에 대해 설명해보겠다.
⓪ Confidence=0.6  &  IoU=0.5 로 설정

① Confidence임계값을 넘긴 Bbox로 예측목록 {a,b,d}를 생성

② 예측목록을 Confidence순으로 정렬 → {b,d,a}

③ 신뢰도가 가장 높은 b먼저 처리.
 ∙ b는 2,3과 겹침 → IoU가 더 큰 2와 쌍을 맺음
 ∙ b-2쌍을 TP로 판정 후, 2는 참값(Ground_Truth)목록에서 제외.

④ 2번째 신뢰도를 갖는 d를 처리
 ∙ d는 4와 IoU가 0.12(<임계IoU)이므로 FP로 판정

⑤ 마지막 Bbox예측목록원소 a를 처리
 ∙ a는 1과 IoU가 0.6(=임계IoU)이므로 TP로 판정 

⑥ Bbox로 생성한 예측목록을 모두 처리하였다.

⑦ 예측 Bbox 처리 후, 쌍을 못맺은 3과 4는 FN으로 판정.

⑧ 최종적인 Precision과 Recall은 다음과 같다.
 ∙ TP=2 , FP=1 , FN=2
 	∴ Precision = 2/3
 	∴ Recall = 2/4

⑨ Confidence임계값을 0.5로 낮추면, Precision과 Recall은 다음과 같다.
 ∙ TP=3 , FP=2 , FN=1
 	∴ Precision = 3/5
 	∴ Recall = 3/4

 

 

1.4  ROC / PR-Curve

PR-Curve

위의 PR-Curve에서 알 수 있는 사실은 Precision과 Recall은 서로 반비례 관계를 보인다는 점이다.
이때, PR곡선 아래부분면적이 의미하는 바가 바로 AP(Average Precision)이다.
AP는 [0,1]의 범위를 가지며, 1에 가까울수록 좋은 성능을 가짐을 의미한다.

추가적으로, class별로 AP를 구하고, 모든 class에 대한 평균(mean)을 계산한 것이 바로 mAP이다.

 

 

ROC-curve

ROC Curve는 양성 클래스와 음성 클래스의 비율이 균형적일 때 성능을 평가하는 데 유용하다.
즉, 클래스 불균형이 낮을 때, ROC Curve는 민감도와 특이도의 trade-off를 측정하여 모델의 성능을 평가한다.

좀 더 자세한 설명은 아래 필기로 대체한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


2. Traditional Detection Method

Detection의 초기연구는 사람얼굴에 국한되어 진행되어왔다.
PASCAL VOC대회 시작 이후, 여러 class로 확장되어 연구가 진행되어왔다. [Everingham2010]

Object Detection은 물체의 위치와 class를 모두 알아내야 해결이 가능한데,
어떤 물체가 어디에 있는지 한번에 알아내기 어렵다.
따라서 가능성이 있는 후보영역을 많이 생성하고, 영역을 classification algorithm으로 걸러내는 two-stage 접근방법을 주로 사용해왔다.
여기서 주의할 점은, two-stage 접근방법을 제대로 구현하려면
"후보영역을 가급적 적게 생성"하고,
"실제 물체를 놓치지 않아야하며",
"후보영역을 높은 정확률로 분류"할 수 있어야 한다.

 

 

HOG

Viola Algorithm. with. HOG(Histogram Of Gradients)
2004년, 성공적인 얼굴검출방법으로 Viola Algorithm이 있다.
여기서, Dalal은 HOG Feature Extraction을 제안하였다.
아래는 Dalal은 HOG Feature Extraction을 간단히 설명한 그림이다.


좀 더 자세한 사례로 예시를 들어보자.
먼저 위처럼 후보크기를 128×64로 변환한다.
이후 이 영역을 8×8크기로 나누면, 16×8개의 타일이 생성된다.
이후 각 타일에서 특징을 추출한다.

타일에 있는 64개의 화소에 각 수평방향과 수직방향의 edge연산자를 적용해 gradient방향을 계산하고
9개의 구간을 양자화한다.
이후, 양자화된 gradient방향으로 histogram을 구하면 9차원 feature vector가 된다.
이때, 명암변화에 둔감히 하기 위해 feature vector를 정규화한다.
정규화과정에서 4개타일의 특징벡터를 이어붙여 36차원의 벡터를 생성하고, 36개요소의 제곱을 합하면 1이 되도록 한다.

이때, 4개타일=window라 하는데, 가로방향으로 7번, 세로방향으로 15번 이동한다. (sliding_window방식)
결국 7×15×36 = 3780차원의 특징벡터를 얻는데, 이를 HOG Feature라 한다.

이후 HOG Feature를 SVM에 입력해 사람일 확률을 출력한다.

 

DPM

DPM (Deformable Part Model)
이후 등장한 DPM은 파트를 이용해 물체를 모델링한다.
그렇기에 part-based model로 불리기도 한다.

Object는 자세와 모양이 심하게 변하기에, DPM은 이런 특성을 반영하기위해 물체를 몇개의 부품으로 모델링한다.
위의 그림은 5개 part로 모델링을 한다.
∙ 좌측은 물체전체
∙ 중앙은 5개의 part
∙ 우측은 part가 발생할 위치에 대한 확률분포
이때, Feature Extraction으로는 HOG를 사용한다.

또한, DNN도입 이전이기에
Detection Model은 위의 그림처럼 학습으로 알아낸다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


3.  R-CNN 계열 (RCNN, Fast R-CNN, Faster R-CNN)

3.1  R-CNN

R-CNN은 후보영역을 생성하는단계와 후보영역을 분류하는 단계로 구성된다 [Girshick 2014].
R-CNN은 후보영역을 영역제안[Region Proposal]이라한다.

2-stage를 순차적으로 처리하기에 RCNN계열방법들을 2-stage방법이라 부른다.
아래 그림은 영역제안과 영역분류의 2-stage를 거치는 RCNN처리과정이다.

 영역제안과정

물체가 있을 가능성이 높은 영역을 찾는단계.
RCNN은 Selective Search Algorithm으로 image에서 2000여개의 후보영역을 생성한다.
Selective Search는 image를 super pixel로 분할 후, clustering과정으로 영역을 생성.

생성된 영역을 227×227크기로 정규화하고,
CNN에 입력해 4096차원의 특징벡터를 추출한다.


 영역분류과정

추출된 특징벡터를 분류해 물체의 클래스를 알아내는일은 SVM이 담당하며,
SVM은 Binary-classifier이기에 물체마다 SVM을 학습해야한다.

Pascal VOC는 20개 class가 있으므로 21개 SVM이 각 클래스확률을 계산
그림처럼 맨 오른쪽에 있는 클래스확률벡터를 출력한다.

cf) 21번째 SVM은 물체가 아닌 클래스를 의미.

최종적으로 2000여개 후보영역에 대해 위치와 클래스정보를 확보한 후,
21번 클래스를 버리고 나머지에대해 후처리를 거쳐 위치와 클래스를 최종적으로 출력한다.



즉, "Selective Search알고리즘 → RoI 생성 → CNN으로 특징벡터 추출 → SVM" 순이다.
다만, RCNN은 분류에 SVM을 사용하고 영역제안을 위해 고전방법을 사용하는 등 속도가 느리다는 결정적 단점이 있다.

이로인해 RCNN의 한계를 극복하는 fast RCNN과 faster RCNN이 등장했다.

 

 

 

 

 

3.2  Fast-RCNN

아래그림은 Fast-RCNN의 처리과정이다 [Girshick 2015].
 영역제안단계: Selective Search Algorithm 사용.
 영역분류단계: SVM을 Neural Net으로 대체.


RoI  투영

input image를 Conv에 통과시켜 Conv특징맵을 얻는다.
Conv특징맵에서 후보영역에 해당하는곳을 RoI(Region Of Interest)로 지정하는, RoI투영을 진행한다.
그림에서 좌측선수에 해당하는 RoI가 노란색인데, RoI에 RoI풀링층을 적용해 고정크기맵(녹색 7×7맵)을 출력한다.


RoI  특징벡터추출

이 특징맵을 2개의 FC층을 통과시켜 4096차원의 RoI특징벡터로 변환한다.
RoI특징벡터는 2갈래로 나뉜다.


분류 및 회귀과정을 모든 RoI에 적용

한곳은 분류를 담당하는 FC층을 통과, 클래스확률벡터를 출력하고
한곳은 회귀를 담당하는 FC층을 통과, 클래스별 박스정보(x,y,h,w)가 된다.

즉, "RoI투영 → RoI 특징벡터추출 → 분류 및 회귀과정을 모든 RoI에 적용" 한다.
물체없음으로 판정된 RoI는 버리고, 나머지는 후처리 후 박스정보와 클래스정보를 최종 Detection결과로 출력한다.

 


Fast-RCNN은 박스정보를 알아내는 회귀와 클래스를 알아내는 classification을 동시에 수행하기 때문에 하나의 Loss function으로 두 task를 달성해야한다.
∙ 손실함수: J = Jclassification + λJregression 형식
이런 손실함수를 다중과업손실함수(Multi-task Loss function)라 한다.
λ 두 task의 비중을 결정하는 hyper-parameter로 논문에서는 1로 설정했다.

다만, 여전히 영역제안단계에서 고전알고리즘(Selective Search)을 사용하기에 한장의 이미지처리에 CPU로 2초가량 걸린다 알려져있다.

 

 

 

3.3   Faster-RCNN

아래그림은 Faster-RCNN의 처리과정으로 Fast-RCNN에 비해 정확도와 속도를 획기적으로 개선하였다 [Ren 2015].
오직 CNN신경망으로만 Object Detection을 수행하는 지평을 열어버렸기에 매우 기념비적이라 할 수 있다.

∙ 영역제안단계:
영역제안모듈, RPN(Region Proposal Network)신경망 사용.
∙ 영역분류단계: Fast R-CNN 사용.

RPN

Pre-Trained VGG16을 앞에 배치해 특징맵을 추출(노란색 H×W맵)한다.
RPN은 이 특징맵의 각 pixel에서 3×3 filter로 512차원의 특징벡터를 추출한다.

특징맵에 서로 다른 2개의 1×1 convolution을 적용해 6개의 값들을 추출한다.
 ∙ 물체여부를 나타내는 2개의 값
 ∙ 박스정보를 나타내는 4개의 값.

위의 연산을 9번 적용해 크기와 가로세로비율이 다른 9개의 박스 (= Anchor)를 생성.
Anchor: 여러크기의 물체를 표현하는 Anchor를 생성함으로써 다중크기의 물체탐지능력을 갖춘다.

결과적으로 H×W의 pixel마다 9개의 Anchor가 생성되므로 H×W×9개의 Anchor가 생성된다.
여기서 NMS를 적용해 2,000여개의 Anchor만 남긴다.


즉, CNN으로 특징맵 추출 → 1×1 conv로 6개값 추출 9회 진행 → Anchor Box생성 순이다.


Fast R-CNN

Anchor들을 RoI으로 간주해 위 그림의 신경망의 뒷부분에 있는 Fast-RCNN으로 입력한다.
Fast-RCNN은 후보영역 각각에 대해 RoI투영 → RoI 특징벡터추출 → 분류 및 회귀과정을 적용한다.

물체없음으로 판정된 후보영역은 버리고, 나머지 후처리 후, 박스정보와 클래스정보를 최종 Detection결과로 출력한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 


4. YOLO 계열

YOLO는 RCNN계열에 비해 정확도는 떨어지나 속도가 월등히 빠른 장점이 있다. (물론, 이도 옛날얘기로 최근에는 YOLOv8, YOLOX계열 등으로 충분히 RCNN을 뛰어넘는 성능을 보이고 있으며, 정확도가 높은 모델을 필요로 하는 경우, InternImage나 DETR계열을 사용한다.)

2016년 최초 발표된 YOLO v1은 Titan X GPU에서 45FPS를 처리한다.[Redmon2016]
YOLO는 물체의 위치와 클래스정보를 Regression으로 한번에 알아내는, End-to-End방식을 고수한다.

 

 

YOLO v1의 특징

image를 s×s격자로 나눈다.
(실제 구현은 아래그림의 노란격자처럼 s=7로 설정해  총 49개의 칸이 존재한다; 빨간박스는 dataset에 라벨링된 참값이다.)

아래그림에서 검은칸을 예로들어 90차원의 벡터로 표현해보자.
빨간색의 좌측선수를 표시한 빨간박스의 중심은 검은칸에 놓이기에 검은칸이 이 박스를 책임진다.
벡터는 90차원인데 앞의 5개요소(x1, y1, w1, h1, o1)는 이 박스의 위치와 크기, 신뢰도를 의미한다.

박스의 위치와 크기는 영상좌표계를 [0,1]사이로 정규화하고 정규화좌표를 중심으로 표현한다.
x2,y2,w2,h2,o2는 또다른 박스를 표현할 수 있기에 한칸은 박스를 2개까지 책임질 수 있다.

p0~p80은 해당박스가 어떤객체클래스에 속하는지 나타내는 one-hot코드이다.
YOLO가 물체의 위치와 클래스를 표현하는 방식

YOLO는 RCNN계열에 비해 상당히 단순한데, 아래 그림은 YOLO가 사용하는 CNN의 구조이다.
∙ Conv층: 24개 / MaxPool층: 4개 / FC층: 2개 로 구성되며
  - input은 448×448크기로 변환되어 입력되고
  - output은 7×7×90의 출력텐서를 갖는다.
YOLO가 사용하는 Convolution신경망 구조
위 그림에서 신경망은 image를 입력으로 받아 7×7×90의 출력텐서를 참값으로 주어 통째로 학습한다.

참값텐서에 [float으로 표시되는 Bbox정보], [OneHot코드로 표현되는 클래스정보]가 섞여있기에
classification과 regression이 동시에 일어난다. 

 

 

YOLO의 Loss function

YOLO의 Loss function은 5개의 항으로 구성된 조금 복잡한 식을 갖는다.

∙ 1, 2항은 각 박스의 위치오류와 크기오류를 측정하는 Regression Loss이다.
∙ 3항은 물체가 있지만 없다고한 FN오류를 측정하는 Confidence Loss이고,
∙ 4항은 물체가 없지만 있다고한 FP오류를 측정하는 Confidence Loss이다.
∙ 5항은 class를 나타내는 OneHot코드의 오류를 측정하는 Classification Loss이다.

 

 

YOLO v3

YOLO v3는 여러 scale을 표현해 다양한 크기의 물체를 탐지하는 능력이 향상되었다 [Redmon 2018]. 
YOLO v3은 (object, class)의 85차원 벡터를 추출하는 층을 신경망 3곳에 배치한다.

∙ yolo_82층에서는 14×14격자로 나눠 14×14×85×3텐서를 출력한다. 따라서 14×14의 각 요소는 박스를 3개까지 출력한다.
∙ yolo_94층에서는 28×28격자로 나눠 28×28×85×3텐서를 출력한다. 
∙ yolo_106층에서는 56×56격자로 나눠 56×56×85×3텐서를 출력한다.

이 층들이 출력한 텐서를 객체정보로 변환하면, 다양한 크기의 객체를 탐지할 수 있다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


5. Transformer : DETR , SETR

고안 배경)

Image에서 객체를 탐지하는 신경망은 여러 Bbox를 예측해야해서 집합예측모델이라 할 수 있다.
모델의 예측과 정답에 해당하는 라벨이 모두 Box집합이기에 Hungarian Algorithm으로 최적의 매칭쌍을 알아내 손실함수를 계산한다.
고전방법과 딥러닝 모두 후보영역을 충분히 많이 생성한 후, 후보영역 각각에 대해 어떤 물체인지 분류하는 접근방법을 사용한다.
이후, 여러 Bbox가 중복검출되는 현상이 발생하면, 중복해소를 위해 비최대억제(NMS)로 후처리를 적용한다.


고안 배경)Transformer를 사용하면,
∙ 후보영역(RoI)을 생성하는 중간단계없이 Box집합을 직접예측할 수 있을까?
∙ 중복현상이 아예 일어나지 않게 할 수 있을까?
∙ Convolution기반의 Faster-RCNN이나 YOLO보다 좋은 성능을 얻을 수 없을까?

CNN은 유연하기에 Faster-RCNN과 YOLO v3의 구조를 자유자재로 설계가능하였다.

하지만 Transformer는 다소 고정적인데, 이유는 아래와 같다.
T × dmodel 크기의 tensor가 여러 encoder블록과 decoder블록을 흐르며 연산이 진행


Encoder만 사용되는 ViT와 달리(https://chan4im.tistory.com/163)
DETR는 영상을 입력으로 박스집합을 출력해야하기에 Encoder와 Decoder 모두 사용한다.
Decoder에 붙은 출력층은 T × dmodel tensor를 Box집합으로 변환해야한다.

손실함수는 Transformer가 예측한 Box집합과 label박스집합이 일치하는 정도를 측정하는 능력을 가져야한다.
Box는 직사각형을 표현하는 4개의 좌표(coordinate)와 물체 클래스를 나타내는 Class확률벡터(softmax)로 표현된다.

 

 

5.1 DETR (DEtection TRansformer)

Faster-RCNN같은 CNN기반 신경망Box집합을 바로 예측하기 어렵기에
RoI를 생성 후, 영역을 분류
하는 일종의 우회하는 방식을 사용한다.
즉, 기존문제를 대리문제로 바꾸고 대리문제를 푸는 셈이라 볼 수 있다.
[Carion 2020]은 transformer를 이용해 집합예측을 하는 DETR모델을 제안한다.


DETR은 RoI생성단계가 없고, NMS라는 후처리단계가 없다.
즉, End-to-End 학습이 가능하다.
위의 그림은 DETR모델구조로 DETR은 ~로 표시한 3가지 모듈로 구성된다.

모듈 

CNN을 통해 Feature Extraction을 진행.
또한, 1×1 convolution을 적용channel을 C에서 dmodel로 줄여 h×w×dmodel의 tensor로 변환한다.
이후 Flatten으로 pixel을 이어붙여 행에 배치한 hw×dmodel 행렬을 얻는다.
위 그림에서는 hw를 T로 표기하는데, 이는 최종적으로 transformer의 input으로 입력할 T×dmodel행렬을 얻음을 의미한다.

이 행렬의 각 행은 축소된 image의 pixel에 해당하며, Self-Attention계산 시 행이 Query로 참여하기에
축소된 pixel(= patch)간의 attention정보를 추출하는 셈이다.
즉, DETR은 Self-Attention을 반영한다 볼 수 있다.


 

모듈 

Encoder-Decoder로 구성된 Transformer로
모듈 에서 입력된 T×dmodel 행렬에 Position Encoding을 적용해 Encoder블록1에 입력한다.

Encoder블록1, ... , Encoder블록M을 통해 변환된 행렬은


Decoder의 MHA에 입력되어 Key와 Value의 역할을 한다.


Decoder를 좀 더 살펴보자.

기존 Transformer에서는 Decoder가 Auto-Regressive방식으로 작동한다.
즉, NLP에서 <SOS>토큰을 주면 첫번째 단어가 생성되고 
<SOS>토큰과 첫번째 단어를 주면 두번째 단어가 생성된다.
이런 AR방식을 객체탐지에 적용할 수 있을까?? → ❌ 
(Bbox는 순서없이 집합으로만 표현하기 때문.)


Decoder 입력을 보면 object queries라 표시된 K개 벡터가 있다.
K×dmodel크기의 행렬이 입력된다는 의미로 K는 탐지가능한 물체의 최대개수이다.
출력층은 물체가 아닌경우, 를 출력할 수 있기에 가변개수의 객체탐지가 가능하다.

그림의 예시에서는 2개의 박스와 3개의 를 출력했다.
Decoder의 최초 입력인 object queries는 Box에 대한 아무런 정보❌ 
Position Encoding, P를 갖고 출발해야하는데, DETR은 학습을 통해 알아낸 P를 사용한다.


모듈 

Decoder블록이 출력한 K×dmodel행렬의 각 행을 Feed-Foward에 통과시켜 박스정보로 변환한다.
이렇게 모델이 예측한 박스집합을 ŷ라 하고
정답에 해당하는 Ground_Truth Box집합을 y라 하자.

y에 박스를 추가해 ŷ처럼 K개 박스를 갖게 한다. 
ŷ과 y에 Hungarian Algorithm을 사용해 최적매칭쌍을 구한다.



📌 Loss Function
매칭된 참값박스 i와 예측박스 j쌍을 이용해 아래 처럼 손실함수를 정의한다.

첫번째 항은 class를 맞췄는지 측정한다. (p̂j(ci)는 class확률벡터에서 참값class에 해당하는 확률.)
두번째, 세번째 항은 물체위치를 얼마나 정확히 맞혔는지 측정한다. (2번째항: IoU ; 3번째항: L1 Distance)




Self-Attention Matrix식 = softmax(QKT / √dkey).
이 행렬은 image를 구성하는 여러 Q벡터가 상호주목하는 정도를 표현.

전술했듯, DETR에서 모듈 이 m×n크기의 기존image를 h×w로 축소하고
축소된 특징맵에서 화소각각을 Q벡터로 취하기에
Self-Attention Matrix는 축소된 pixel (= patch)가 상호주목하는 정도를 측정한다.

위의 그림에서 주황색 표시된 코끼리의 경우, 코와 발, 등, 꼬리에 주목하고 있는데,
이는 Bbox의 경계에 주목하고 있다는 사실을 확인할 수 있다.

이 사실을 바탕으로 Decoder의 역할을 추론해보면,
Decoder는 Bbox를 제대로 알아내기위해 Self-Attention Matrix를 통해 물체의 상하좌우 경계에 주목한다고 할 수 있다.

 

 

 

 

 

 

 

5.2 SETR (SEgmentation TRansformer)

DETR는 Object Detection의 목적으로 고안되었다.
이때, Transformer의 특성으로인해 분할을 할 수 있도록 쉽게 확장할 수 있다.
DETR Architecture
위의 DETR모델의 모듈 ③은 출력행렬을 해석해 Box정보로 변환하는, Detection용도의 Head이다.
따라서, Segmentation용도의 Head를 붙이면, 분할용도의 Transformer모델인, SETR이 된다.
즉, 요약하면 SETR은 Encoder(Transformer) - Decoder(CNN)의 구조를 띈다.


Segmentation Head축소된 해상도를 원래 해상도로 복구하기위해 UpSampling을 위한 Convolution층이 포함된다.
SETR Architecture
(a). 먼저 image(m×n×3)를 고정된 크기의 patch로 나누고
각 patch를 선형 임베딩한 다음 Position Embedding을 추가한 후,
결과 벡터 시퀀스를 표준 트랜스포머 인코더에 공급한다.
(이때, 픽셀 단위 분할을 수행하기 위해 다양한 디코더를 도입한다)


(b) Decoder는 점진적 UpSampling(resulting in a variant called SETRPUP)으로
여러 단계의 Convolution층을 쌓아 피라미드 형태로 쌓은 Decoder를 제안한다.

(c) multi-level feature aggregation (a variant called SETR-MLA).

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


6. Backbone Transformer : Swin Transformer

6.1 Backbone Transformer

CNN transfer learning은 DNN의 큰 이점이다.
보통 전이학습(transfer learning)에 널리 사용되는 Backbone model로는 VGG, GoogLeNet, ResNet, DenseNet121 등이 있었으며, 최근에는 EfficientNet 등이 있다.

Backbone model은 주로 input data에서 feature map을 추출하는 역할을 한다. 
주로 pretrained model을 사용하며, 다양한구조(CNNs, Transformers, ResNets)를 사용할 수 있다.

기존 NLP에서 Transformer가 사용이 되었기에(GPT, BERT), 초반에는 transformer도 transfer learning을 위한 Backbone model로 쓸 수 있을까? 라는 의문에서 출발했다.

지역정보를 추출하는 Convolution연산에 의존하는 CNN에 비해 Self-Attention에 의존하는 Transformer가 Transfer Learning에 훨씬 유리하다는 실험적 입증이 많이 발표되었는데,
Backbone으로 쓸 수 있는 Vision Transformer를 제작할 수 없을까? 라는 의문에서 Swin Transformer로 답을 해준다.

Backbone이 되려면 image의 feature를 충분히 반영한 구조를 설계해야한다.
기존 transformer는 문장처리목적으로 설계되었기에, 조금의 변형이 필요하다.
Backbone모델이 되려면 아래의 특성들을 잘 반영해 처리할 수 있어야 한다.
(문장을 구성하는 단어는 scale변화가 없으나 image를 구성하는 Object는 아주 다양한 크기로 나타나기에 scale변화가 심한편.)
(또한, 한 문장을 구성하는 단어는 수십∙수백개에 불과하지만, image를 구성하는 pixel은 수만~수백만 개이다.)
(문장의 단어는 띄어쓰기로 잘 분할되어있지만, image는 Object끼리 혹은 배경이 심하게 섞여있다.)

 

 

6.2 Hierarchical Feature map. &. Shifted Window

Swin Transformer는 image특성을 반영하기위한 핵심아이디어를 2가지로 설명한다.

Hierarchical  ViT

아래 그림(a)은 Hierarchical ViT(= Hierarchical Featuremap)을 사용해 객체의 scale변환에 대응하는 방법을 설명한다.
모든 window는 M×M개의 patch로 구성된다. (여기서 M=4)
맨 아래층은 작은 patch_size로 window가 4×4개가 있다.
가운데 층은 patch_size가 2배로 커져 2×2개의 window가 있고, 맨 윗층은 1개의 window가 있다.
이렇게 작은 patch부터 큰 patch로 구분해 처리하면, 여러 크기의 객체를 분류하거나 탐지할 수 있다.

그림 (b)의 ViT의 경우, 영상을 분류하는데 사용할 수는 있지만 객체탐지 및 분할에는 한계가 있다.


계층적 특징맵은 계산효율상에도 큰 이점이 존재한다.

단일해상도를 사용하는 ViT의 경우)
224×224 image를 16×16 patch(= 14×14개)로 나눈다 가정하자.
이 경우, T = 196인 행렬이 입력되는데, MHA는 T개 patch끼리 Self-Attention을 계산하기에 T2번 연산을 수행한다.
이때, 연산은 QKT의 행렬곱으로 이뤄진다.
Q와 K가 T×dkey행렬이므로 T2×dkey만큼 곱셈이 수행된다. 

다중해상도를 사용하는 Swin의 경우)
window별로 self-attention을 적용한다.
window는 M×M개의 patch로 구성되기에 한 window는 M2×dkey만큼 곱셈을 수행한다.

즉, ViT에비해 (T×T) / (M×M×window개수)배 빠르게 계산된다.
예를 들면 그림(a)의 맨 아래층에서는 window가 16개이므로 49배 빠르다.


Shifted Window

Swin Transformer의 이름이 Shifted WINdow에서 유래되었을 정도로 핵심아이디어이다.
ℓ번째 layer에서 이전처럼 window를 나누는데,
그 다음 ℓ+1층에서는 window를 절반크기만큼 수평과 수직방향으로 이동해 나눈다.


shifted window를 사용하면 window간의 연결성강화 및 다양한 크기의 객체를 처리할 수 있고,
객체의 상대적인 위치정보를 저장하는 등 이를 통한 성능향상이 가능하다.

 

 

 

 

6.3 Swin Transformer Architecture

아래그림은 Swin Transformer의 구조이다.

좌측에서 우측으로 흐르는 단계 1~4는
좌측그림의 (a)의 아래에서 위로 진행하며 patch는 커지고
window개수는 작아지는 방향에 해당한다.




예를들어, C=96으로 하고, m×n = 448×448 image가 입력될 때,
단계1) input tensor: 112×112×48 // output tensor: 112×112×96
단계2) input tensor: 112×112×96 // output tensor: 56×56×192
단계3) input tensor: 56×56×192 // output tensor: 28×28×384
단계4) input tensor: 28×28×384 // output tensor: 14×14×768

위 그림의 (a)는 이런 tensor변환을 어떻게 수행하는지 설명한다.
단계 2에서 patch합치기 적용시, 맨 아래층에서 맨 위층으로 진행하는 과정에 해당하는 것으로 단순히 이웃한 4개 patch를 하나의 patch로 합치는 과정을 의미한다.

모든 단계를 거쳐 얻은 특징맵에 classification을 위한 head를 붙이면 classifier가 되고,
Detection을 위한 head를 붙이면 detector가,
Segmentation을 위한 head를 붙이면 segmentor가 된다.
이런 방식으로 Swin Transformer는 Backbone 모델로 작용한다.

이제 단계 1~4에 노랜색 표시된 Swin Transformer Block의 동작을 그림 (b)를 통해 살펴보자.
(b)는 Encoder Block을 2개 쌓은 상황으로 현재 Block ℓ은 ℓ-1번째 Block에서 xℓ-1 tensor를 받아 Layer Normalization을 거쳐 W-MHSA층으로 Self-Attention을 적용한다.
이후, Add와 Norm, FF, Add를 적용해 x을 출력한다.

ℓ+1번째 Block은 x을 입력으로 받아 같은 과정을 거쳐 xℓ+1 tensor를 출력한다.
ℓ Block과 ℓ+1 Block의 Self-Attention을 W-MHA, SW-MHA로 표기했다.
W-MHA는 window를 분할하고 SW-MHA는 Shifted Window로 분할한다.

Backbone모델로써의 Swin Transformer

Swin Transformer는 Backbone으로 쓰이는 CNN인 ResNet등과 호환되도록 tensor모양을 설정했기에
기존 딥러닝모델에서 CNN-Backbone을 들어내고 Swin-Transformer로 쉽게 대치할 수 있다.

이미 일전 글들에서 classification관련해 많이 다루었기에 아래 링크를 남긴다.

https://chan4im.tistory.com/category/Deep%20Learning%20%3A%20Vision%20System/%EB%85%BC%EB%AC%B8%20review

 

'Deep Learning : Vision System/논문 review' 카테고리의 글 목록

컴퓨터과학, 인공지능에 대한 공부를 열심히 하는 공대생

chan4im.tistory.com

 

좀 더 자세한 CNN의 원리를 알고싶다면, 아래 링크를 추천한다.

https://poloclub.github.io/cnn-explainer/

 

CNN Explainer

An interactive visualization system designed to help non-experts learn about Convolutional Neural Networks (CNNs).

poloclub.github.io

 

 

📌 CNN 및 Vision 기본:
∙ CNN 원리:
https://chan4im.tistory.com/160
https://chan4im.tistory.com/133
∙ Auto-Encoder: https://chan4im.tistory.com/156

📌 AlexNet: https://chan4im.tistory.com/145

📌 VGGNet: https://chan4im.tistory.com/146

📌 Batch Normalization: https://chan4im.tistory.com/147

📌 GoogLeNet: https://chan4im.tistory.com/149

📌 ReLU에 관한 고찰: https://chan4im.tistory.com/150

📌 ResNet: https://chan4im.tistory.com/151

📌 ResNet-V2: https://chan4im.tistory.com/152

📌 DropBlock: https://chan4im.tistory.com/153

📌 Vision Transformer: https://chan4im.tistory.com/163
∙ Attention: https://chan4im.tistory.com/161
∙ Transformer: https://chan4im.tistory.com/162
∙ ViT: https://chan4im.tistory.com/164



📌 Semantic Segmentation:
∙ Intro: https://chan4im.tistory.com/158
∙ Model: https://chan4im.tistory.com/159

 

 

 

 

+ Recent posts