🤍 전 강의 25% 할인 중 🤍

2024년 상반기를 돌아보고 하반기에도 함께 성장해요!
인프런이 준비한 25% 할인 받으러 가기 >>

  • 카테고리

    질문 & 답변
  • 세부 분야

    컴퓨터 비전

  • 해결 여부

    해결됨

안녕하십니까 Retinanet에 대한 전반적인 이해를 질문하고자 합니다.

21.04.07 17:04 작성 조회수 306

1

안녕하십니까, 현재 RetinaNet을 구현해보고자 Retitanet paper를 읽고

케라스 공식홈페이지의 Retinanet 예시 코드(https://keras.io/examples/vision/retinanet/#implementing-smooth-l1-loss-and-focal-loss-as-keras-custom-losses) 를 이해하고자 하는데

제가 전반적인 흐름을 이해하질 못하고 있습니다.

본 강의에 있는 Fast RCNN 파트에서, 예측 박스가 Ground Truth 좌표값을 따라가는 것이 아닌 Anchor Box 중에서 Ground Truth와 IOU 높은 Positive Anchor Box를 따라간다고 하였습니다.

그렇다면

1. RetinaNet이 작동하기 전 과정이,

우서적으로 Anchor box들 생성하고 그 중에서 Ground Truth와의 IoU>= 0.5인 Positive Anchor Box 찾기

가 맞는지요.

2. 그리고 RetinaNet 구조를 보면 FPN 에서 나온 P3 ~ P7(Retinanet paper 기준) feature map을 class subnet과 box subnet으로 각각 들어가게 되고, 위 케라스 공식 홈페이지 예제 코드 

이때, box subnet의 결과값이 W x H x (4 x 9) 꼴인데, Positive Anchor Box의 좌표는 (x, y, w, h)로 4개인데 어떻게 regression 계산이 되는지 궁금합니다.

class subnet에 들어가게 되면 W x H x (num_classes  x 9)  꼴의 결과값이 나오는데, 이는 2번질문과 마찬가지로 class labeling은 0,1,2,...과같은 정수형이거나 벡터형으로 나타날텐데 어떻게 regression 계산이 되는지 궁금합니다.

3. 또한, Positive Anchor Box를 제외한 나머지 Anchor Box들은 결국에는 직접적인 학습에 사용되지 않는 것인지요?

만약 사용된다면 Negative Anchor Box(IoU < 0.4)와 Ignorance Anchor Box(0.4 <= IoU < 0.5)가 어떤식으로 사용되는 지에 대해 설명 부탁드립니다.

4. 또한, 한 이미지에 서로 다른 객체가 2개 이상일 때, feature map이 class subnet에 들어가서 도출된 결과값( (num_classes) X 9)이 어떤 방식으로 해당 객체의 레이블과 대응하여 학습되는지 궁금합니다.

예를 들어, 사과(0), 고양이(1), 강아지(3) 클래스가 3개인 데이터셋에서, 사과(0)와 고양이(1)가 존재하는 특정 이미지를 RetinaNet에 training시키게 되면,

P3 ~ P7의 feature map이 class subnet으로 들어가서 W x H x (3 x 9)꼴의 결괏값이 나올텐데, 이때 해당 결괏값이 사과(0)인지, 고양이(1)인지 어떤 값이 대응하여 학습해야할 지에 대해서 알 수가 없어 이렇게 질문드립니다.

대략적인 이론을 알고 있다고 생각하여 직접 코딩을 하려했지만, 막막하여 keras 예제를 통해 역으로 이론을 이해하려 시도했습니다. 하지만 코드 자체가 이해가 되질 않고, 어떤 식으로 데이터가 흘러가지는에 대해서도 파악할 수가 없었습니다..

혼자서 해결해보려 했으나 며칠동안 해결되지 않고 오히려 이해가 되지 않는 부분이 많아져서 이렇게나마 질문을 드립니다...

답변 6

·

답변을 작성해보세요.

0

답변 달고 잠자러 가려다 다시 생각해 보니 이미지가 label 이 없으면 negative anchor 로 학습되겠군요. Keras 소스코드의 해당 부분을 보지는 못했지만 negative를 negative로 했으니 loss는 0 그리고 동일한 normalize 규칙을 적용하면  될것 같습니다 

양민욱님의 프로필

양민욱

질문자

2021.04.09

늦은 시간에 답변 정말로 감사합니다. 주무시러 가기 전까지 답변해주셔서 감사하다는 말을 하고 싶었는데, 혹여나 알람이라도 가서 잠을 방해할까봐 이제서야 답니다. 해주신 조언을 참고하여, 병변없는 정상인 데이터를 제외하기로 하였습니다.

0

일반적인 object detection은 학습법하고는 차이가 있군요.

일단 label이 없으면 학습 데이터로 입력되지 않습니다. 해당 image는 무시 되도록 대부분의 object detection application들이 구현 되어 있습니다

이 경우에는 정상 chest xray는 학습 되지 않으므로 object detection을 하지 않을 것입니다(너구리만 학습한 모델은 사람이 나오면 object detection하지 않습니다)

굳이 normal 데이터를 학습 데이터로 넣으실 필요는 없어 보입니다. 다만 너무 비슷한 이미지라 모델이 어떻게든 detect 하려고 노력할 수 있습니다. 그래서 잘못된 detection이 될 수도 있습니다. 그럴 경우는 normal 데이터를 label작업을 수행해서 normal로 detect 할 수 있을 필요도 보입니다.

코로나 걱정 해주셔서 너무 감사드립니다. ^^

0

양민욱님의 프로필

양민욱

질문자

2021.04.08

답변 정말 감사합니다.

제가 positive anchor가 없는 경우를 언급한 이유가, 위에서도 언급했듯이 chest X-ray data에서 병증을 detection하고자 함인데, 데이터 중에서 normal 데이터는 병증이 없기에 레이블이 없습니다. 그래서 이러한 데이터에는 positive anchor 또한 존재하지 않아서 질문을 드려보았습니다.

이러한 경우에도 loss를 negative anchor 수로 나누어주면 될까요?

아직도 코로나가 기성인 이 시기에 부디 건강하시길 바랍니다. 감사합니다.

0

positive anchor가 존재하지 않는 데이터는 거의 없을 거라 생각됩니다만, 존재하지 않는다면 그때는 Negative anchor로 할당되어야 할것입니다.

anchor가 작은것 부터 큰것 까지 있기 때문에 엄청나게 높은 IOU를 적용하고 이미지가 꽉차는 오브젝트가 아니고서는 Positive anchor가 존재 하지 않기란 어려울 것 입니다. (IOU가 0.7정도라면 이미지 사이즈를 고려할때 Positive anchor가 존재하지 않는것 어려울 것 같습니다만...)

굉장히 작은 object가 있다면 이는 anchor box와 IOU가 작기 때문에 Negative anchor로 할당되듯이 엄청나게 높은 IOU를 적용해서 Positive anchor될 수 없는 anchor들은 negative anchor로 분류되어야 할것 같습니다.

0

양민욱님의 프로필

양민욱

질문자

2021.04.08

답변 정말로 감사합니다!

추가적으로 제 상황을 말씀드리자면 Imagenet으로 학습한 resnet 50을 backbone으로 하여 chest X-ray에서 병증 detection을 하고자 하여, 모델을 custom하여 fine-tuning을 해야하는 상황입니다.

위의 질문을 등록한 이후로 해당 강의 질문 게시판에서 Anchor Box 관련 질문을 찾아본 결과

https://www.inflearn.com/questions/109566

여기에 "BACK HO KIM" 님께서 올려주신 설명으로 인해 subnet을 통과하여 나온 output들이 무엇을 의미하는지 알게 되었습니다.

현재 질문을 추가적으로 올렸다가 개인적으로 질문에 대한 해답을 찾아서 지우고 새로운 의문점이 있어 질문합니다.

object detection에서 loss function 구성이 classfication loss + box regression loss로 구성되어있는데, 이 때 마지막에 loss를 positive anchor 수만큼 나눠주는 normalization 과정이 있는 것으로 알고 있습니다.

이는 위에 언급한 Keras 예제 코드에서도

normalizer = tf.reduce_sum(positive_mask, axis=-1)

clf_loss = tf.math.divide_no_nan(tf.reduce_sum(clf_loss, axis=-1), normalizer)

box_loss = tf.math.divide_no_nan(tf.reduce_sum(box_loss, axis=-1), normalizer)

이렇게 나오며,

선생님께서 강의 중에서 사용하신 fizyr의 retinanetd  losses.py에도 나오는 개념인데

이 때 드는 의문점이

만약 positive anchor가 존재하지 않는 데이터라면 loss를 어떻게 처리하는가 입니다.

Keras 예제 코드에서는 tf.math.divede_no_nan 함수를 사용하여 positive anchor 수가 0이라면 loss를 0으로 처리하는데

이렇게 되면 학습시에  영향이 없는지 궁금합니다. 

항상 친절하고 좋은 답변에 감사드립니다.

0

안녕하십니까,

1. 작동하기 전 과정이 어떤 과정인지 잘 이해는 못했지만, Ground Truth와 IOU 높은 Positive Anchor Box는 학습시에 Train data로 배치건수만큼 RetinaNet 모델에 전달되어 학습합니다. (Negative anchor box도 학습 시에 전달되어야 합니다.)

2번과 4번은 같이 말씀드리겠습니다.

bbox regression과 classification이 Dense layer가 아니라  Conv layer를 두번 적용했습니다. 마지막 conv는 fiter수를 regression의 경우 9x4로, classification의 경우 9xclassification수로  해서 적용했습니다. def build_head()에 보시면 잘 나와 있습니다(보통 Object Detection 모델에서  bbox regression, classification을 최종 수행하는 layer들을 head라고 합니다.)

그리고, 이 head 단에서 예측값을 여러 레벨로 만들어내지만, 최종적으로는 Non Max Suppression으로 최종 bounding box 위치와 Classification값을 결정합니다.

3. 논문에도 나와 있듯이 ignore anchor box(즉 posive도 아니고 negative도 아닌 애매한)는 학습시 제외 됩니다. negative anchor box는 positive anchor box와 마찬가지로 학습에 사용되어 loss가 계산 됩니다. 다만 해당 keras의 소스 코드가 얼핏 positive anchor box만 가져가는 걸로 보이지만, 나중에 loss 계산할 때는 전체 anchor box에서 ignore box 빼고, positive box 빼고, 나머지를 negative box로 계산해서 loss를 계산하는 걸로 보입니다(소스 코드를 완벽하게 이해하지는 못해서 확실한건 아닙니다)

감사합니다.

채널톡 아이콘