본문 바로가기
AIML 분야/Vision Transformer

Transformer와 CNN과 융합, 최강의 backbone 서베이 해보기? (EfficientNet V2, CMT, ViT, DeiT, Swin 등)

by 포숑은 맛있어 2021. 8. 4.
반응형

딥러닝 아키텍쳐 진짜 아무말.

디자인 하며 고민한 것과 서베이 내용을 다루는 글이다.

 

완전 딴 소리 TMI

더보기

성능 올리는 생각을 하면서 엉성하게나마 모델 고안을 하다보니, 요즘 관심사는 아무래도 'SOTA 모델들이 왜 성능이 좋은가?' 이다.

아키텍쳐 만들려고 하니까 연산 하나하나 단위가 중요했다. 학부때 처음 딥러닝을 접했을때는 Depthwise convolution같은거 그냥 검색해서 어떤 연산인지 보고 설명 이해하고 흘러 넘겼는데, 이젠 각각을 다시 봐야겠다는 마음이 들기 시작했다.

 

현재 풀고싶은 task가 있는데, SOTA 모델의 단점이 뭔지 생각해보고 개선할 수 있도록 하는게 목표다. 성능이 아직 높지 않은 어려운 task이기 때문이다. 그러려면 먼저 이미 있는 모델들을 서베이하고 이해해야하는데, 모델의 contrubution을 정말 제대로 이해하려면 논문만 읽는 게 아니라 생각을 해야만했다. 공식 코드 뜯어보고 연산 하나하나 단위를 생각하니까 이 모델이 왜 잘 동작하는지, 개선한다면 어떤 정보가 더 필요할지를 몹시 주관적이지만 그래도 알 수 있었다. 'ResNet 그거 그냥 skip connection 추가하면 되는거 아니야? attention 그거 그냥 가중치를 명시적으로 학습하게 만든거잖아? 어 이건 그냥 이것저것 시도하다가 잘 되는 알고리즘 발견해서 논문 냈나보네. 부럽다. 누구나 생각할 수 있는거 아닌가? 깃발 먼저 꽂는 사람이 임자인듯' 논문 읽다보면 약간 이렇게 오만하고 하찮은 생각을 하게 되었는데, 그 심플하고 직관적인 아이디어가 '어떻게' 나왔는지 저자의 입장에서 생각해보면 아득하다. 이전 연구들을 얼마나 깊게 이해하고 있으며 문제를 해결하기 위해 고민을 했을지. 내가 직접 모델을 만들려고 시도할때가 되어서야 이게 와닿았다.

 

아무튼 그렇게 고민하다가 저번달에 모델을 구현했지만 성능 증가가 딱히 없었다. 모델에 내 의도가 제대로 반영되지 않은거다. 꽤나 어이없지만 이 문제는 내가 고안한 모델의 특정 위치에 3D Conv 연산 딱 하나를 추가하는걸로 해결되었다. 내 가설이 틀린건지 의도대로 반영을 못한건지 생각하다보니까 문제를 발견했다. 만약 제대로 이해하지 않고 그냥 'ㅇㅇㅇ를 쓰면 더 좋아질테니까 추가해서 구현해야지 안되면 말고' 정도로 생각했다면 그냥 그 아이디어가 안되는 아이디어라고 생각하고 넘어가버렸겠지.

핵심만 보면 된다고 생각해서 메인 아이디어만 스르륵 보고 넘어갔던게 뼈아픈 실책이었다는 후회가 되는 요즘이다. 막상 뭔가 고안하려고 하면 머리가 텅 비어버리더라. 그동안 봐왔던 개념이 전부 따로 놀아서. 다시 복습하면 되겠지 뭐... 하면서 느는건니까

 

 

 

본론.

요즘 백본 모델들이 ViT로 핫하길래 의식의 흐름을 따라 찾아봤다.

 

마침 아카이브에 CMT라는 모델이 떴다. 7월 논문이라 나온지 한달도 안되었다.

Swin Transformer가 지금 imageNet 뿐만 아니라 segmentation이니 action이니 다 쓸어먹고 있는데 그새 더 새로운게 나왔다고? 나 아직 swin도 제대로 못봤는데

 

아무튼 CMT에서 성능테이블에 써놓은 것들을 보면 대표격 논문을 뭘 봐야할지 알 수 있을거니까 이것부터 가져왔다.

ResNet, Inception은 넘어가고 (언젠가 다시 보긴 해야겠지만 일단 오래되었으니) EfficientNet V1, ViT, DeiT, CeiT, TNT라는게 있나보다.

 

여기에 Swin Transformer가 요즘 시끄러우니 보도록 하고, EfficientNet 또한 V2가 나왔다는 소문이 자자하므로 추가하도록 하자.

 

ViT는 작년에 리뷰했어서 안보고 넘어간다.

자료 만든걸 언젠가 정리해서 백업해야하는데... 여기 안올렸던 것 같다.

내 기억으로는 SOTA급은 아니더라해도 vanilla transformer 정도임에도 준수한 성능을 보였다는거다.

그리고 CNN 기반이 local 정보를 고려한다는 inductive bias때문에 vision task에 이점이 있는지라 당연히 수렴이 빠르지만, 학습 하다보면 나중에는 그 갭이 사라지는 것 또한 인상적이었다.

 

아무튼 ViT가 판도라의 상자를 열어버려서 이후에 많은 응용이 나왔고, 아키텍쳐적으로도 왜 잘 되는지에 대한 고민도 많이 보였던 것 같다.

  • 처음에는 필요성 자체에 대해 회의적인 시각이 많았다. 지금이야 paperswithcode를 보면 많은 task에서 SOTA 찍은게 transformer 기반이긴 하다만. 특히 어떤 논문에선 다른건 몰라도 초반 레이어에는 CNN연산이 중요하다고 언급했다.
    내 주관적인 의견으로는, 이 논문이 CNN을 초반 중반 후반 각각 사용해보는 ablation을 안 한걸로 알고있다. 그러면 초반에 CNN이 필요한게 아니라, locality가 중요하다는(=CNN의 inductive bias 강점) 의미로 받아들였다.
  • ViT에서 self-attention이 핵심인가?
    그럼 attention을 없앤 MLP를 만들면 어떨까?
    -> attention이 없음에도 ViT와 유사한 성능을 내는 모델이 나왔던걸로 기억한다. 다만 downstream task의 경우에는 손해였던가... 기억이 가물가물한데 MLP Mixer같은거 다시 보면 될것같다.
  • 아니면 position embedding이 중요한건가?
    방식이 다른건 성능에 큰 변화 없지만, positional embedding 없으면 성능이 안좋다고 ViT appendix에서 봤던 것 같다.
    Rethinking position embedding이랑 비슷한 제목을 아카이브에서 본 듯 하니 찾아봐도 좋을 듯
  • 수렴이 빠르고 학습이 쉽다는 장점이 있으면, 그냥 CNN 쓰면 되는거지 왜 transformer를 쓰는가?
    -> transformer가 robustness가 강하다는 장점을 발견한 논문도 있다. corruption에 CNN보다 훨씬 강력했다!
    crop해버려서 안보이는 구간이 있으면 다른 곳에 주목해서 추론하도록 학습하는걸로 보였다.
  • CNN의 Inductive bias가 비전에서는 강점인데, 그러면 attention을 학습하는데에 줄 수 있지 않을까?
    -> TransGAN에서 봤다. 처음에는 local한 범위 내에서만 어텐션을 배우는데, 학습 에폭이 늘어나면서 global attention이 되도록 점진적으로 늘리는 기법이 있었다.
  • 아직 찾아보진 않았는데, Swin transformer도 attention 주는 것에 어떤 변화를 준걸로 알고있다. 얼핏 들었음
    기존 어텐션의 quadratic한 연산을 줄이기 위함이었는지, 위에서 말한 CNN의 inductive bias를 주는 기법인지, 다른 방법인지는 아직 안봐서 모른다. CMT도 light-weight attention을 쓴걸로 알고있어서, attention 연산에 배리에이션을 준 것으로 알고있다.
  • 응용1: backbone에 넣어서 CNN을 대체하려는 노력이 아니라, detection 모델에서 bbox 찾는데 쓴 활용도 획기적이었다. end-to-end 학습이 가능해진다.
    이를 비디오로 확장하면, 유사하게 action detection에서도 TubeR라는 논문이 있다.
  • 응용2: 최근거 안봐서 모르는데, image generation하는 GAN에서 Generator를 잘 만드는법이 없나 궁금했었는데 마땅히 못봤다. TransGAN이랑 이거 이후에 나온 한편 (열심히 깠던거) 말고는 모르겠다. 와아 블루오션 발견!

ViT 유행 타고 작년 말부터 Swin Transformer 나오기 전까지는 트랜스포머 굉장히 열심히 깠었는데, 줄줄이 적어보니까 난 그저 까빠였구나... 언제 이렇게 많이 봤지;

걍 떠오르는거 적은거라 인상적인거 찾으면 추가하려고 한다. 안 적어놓으니 기억이 전부 증발해버린다.

 

 

 

DeiT도 스르륵 훑었다. 굉장히 많이 언급되는 논문 중 하나다.

  • 이 논문은 knowledge distillation을 사용한다. class token처럼 distillation 토큰을 함께 추가했다.
    distillation 토큰 추가해서 뭐... 싶지만 (BERT때의 데자뷰) 학습된 CLS token과 Distill token이 correlation이 0.06정도라고 한다. 이 얘기는 둘이 거의 orthogonal하다는거니까 일단 의미있는걸 배우는건 맞다는 소리.
  • KD할때 Teacher로 CNN을 쓸수도 있고, transformer 기반을 쓸수도 있다. 둘다 실험했다.
  • fine tuning은 몰라도 pretraining에서 optimizer를 SGD를 쓰는게 안좋다는게 여기서 나온다. AdamW 써야한다.
  • Augmentation, Regularization도 여러가지 실험해놨다. 특정 기법들은 사용하지 않으면 pretraining 학습이 거의 안되는 수준이기도 해서 인상적이었다.

DeiT가 EfficientNet보다 성능이 좋아보인다. (Distillation 사용한 것 기준)

ViT는 EfficientNet과 비교하기 뭐했는데, 이때부터 어...? 싶었지만 KD 기반이니 그런거라고 애써 외면했었다.

 

 

EfficientNet V1, V2.

 

V1은 NAS랑 엮어서 compound scaling이 주로 언급.

depth(d), width(w), resolution(r)를 모두 고려하도록 하는데, 여기에 전부 pi배(리소스)를 하도록 아키텍쳐를 만들었다.

파이에 1,2,3,4,5,6,7 이런식으로 넣어서 만든게 EffNet 시리즈다.

그러면 초기모델인 EfficientNet V0는 어떻게 얻는가? (=d,w,r 얻는법?)

논문 안읽어서 모르는데, MNasNet이랑 비슷한 방법으로 NAS 기법으로 찾는 것 같다.

NAS 할때 원래 성능 좋은 쪽으로 아키텍쳐 가중치(어떤 연산이 중요하다는 값)들을 학습하는데, 그러면 성능이 좋다는게 뭘 의미하는가?

정의하기 나름인데, 단순 accuracy만 쓴건 아니고 FLOPS도 고려하여 둘다 좋아야 좋은 모델이라고 정의하고 d,w,r를 찾는거다.

아래는 MNasNet에서도 optimization target으로 사용한 식이다. EffNet V1에서도 사용했다.

ProxylessNAS랑 DARTS는 직접 커스텀 해봤는데, MNasNet은 논문을 읽지도 돌려보지도 않아서 잘 모르니 그냥 그런가부다 넘어감..

 

연산은 바꾸는게 없으니 좋은 백본을 써야겠지.

-> MBConv를 주로 쓰기땜에 이것도 보면 좋다. mobilenet에서 사용한 구조로, inverted bottleneck.

이 MBConv를 알려면 Depthwises separable convolution(MobileNet V1에서 나옴)과 SE (squeeze and excitension)을 알아야한다.

https://lynnshin.tistory.com/53 이 블로그 보고 공부함

 

<< 읽거나 말거나 >>

Depthwise Separable Convolution

: Depthwise conv + Pointwise convolution으로 Conv연산을 효율적으로 줄인 것이다.

Depthwise는 말그래도 각 depth별로 연산하기 때문에, 특정 채널에서 [H*W]크기 커널 사용.

Pointwise도 말그대로 위와 반대로, 여러 채널에 걸치는데 특정 위치에서 연산하기 때문에 [1*1] 크기 커널이 사용된다.

pointwise는 그러면 원하는 채널수로 바꿀 수 있게 된다! 이 이유로 채널수 줄이거나 맞출 때 많이 사용하는 연산이다. (1*1 conv라고 불리는 그것)

이게 왜 효율적인가?

보통 비전에서는 depth가 깊어지는게 성능에 상당히 중요하다고 한다. conventional wisdom.

그런데 depth가 깊어지면 채널이 너무 늘어나서, 뒷부분 레이어에 파라미터가 많이 필요하게 된다. 연산이 많이 들어.

그런데 pointwise를 통해 채널을 마음대로 줄일 수 있으니 효율적.

 

Inverted Residual Bottleneck?

앞에 depthwise separable conv에서 pointwise conv가 연산 비중이 크다고 한다. 그래서 depthwise 부분 비중을 크게 함.

채널 수를 1*1 conv(pointwise)로 늘리고, depthwise로 계산하고, 다시 1*1으로 채널을 줄인다. skip connection도 더해주고.

 

Squeeze-Excitension

먼저, H*W*C -> 1*1*C로 줄임. GAP 사용.

재조정 (recalibration)을 하기 위해서 FC 2개 거쳐서 나온 가중치를 가지고 원래 H*W*C에 곱해준다고 한다.

<< 여기부턴 다시 본론>>

 

 

적당히 EfficientNet V2로 넘어가볼까.

논문 https://arxiv.org/pdf/2104.00298.pdf

https://seing.tistory.com/164 <- 사실 논문 제대로 안봤고 이 글 위주로 읽었다.

 

V2는 progressive learning가 핵심이다.

성능도 좋은데 학습이 획기적으로 빠르다는걸 강조하고있다.

어떻게 가능한가?

 

이미지 사이즈가 작으면 regularization의 강도가 약한게 좋고, 이미지가 크면 반대로 강한 게 좋다고 한다.

그래서 regularization의 강도를 학습중에 조정하는 것이 좋다고 하면서 그렇게 모델을 학습했다.

이미지 사이즈를 처음에는 작게 학습하다가, 에폭이 커지면 이미지도 키운다.

이와 동시에 augmentation 강도 또한 점점 강하게 조절하는 것.

읭...? 스럽다. 인풋 크기가 다르면 아키텍쳐가 달라지지 않나? 가능한 일인가?

 

논문에서 아래 글을 인용하는데, 요즘 코드 구현에서 adaptive average pooling 많이 쓰는데 이거는 output 크기만 지정해주면 알아서 사이즈 맞추도록 conv 하이퍼파라미터를 계산해주니까 이미지 크기를 바꾸면서 학습할 수 있다는 것 같다.

https://www.fast.ai/2018/04/30/dawnbench-fastai/

 

그래도 224*224를 보는거랑 128*128을 보는건 각 연산의 (3*3 conv 같은) 입장에서 보면 스케일이 달라진건데.. 학습중에 받아들여야할 시맨틱이 달라질 것 같은데 그래도 되나?

뭐... 지적한대로 그렇긴 하지만 아무튼 최종 성능은 더 좋다는 것 같다.

 

 

그 외에 V1의 아키텍쳐 단점 몇가지를 보완했다.

  • 이미지가 작은데서 학습하는게 성능 좋음
  • Depthwise conv가 모델 초기 레이어에서는 안좋음
    -> Fused MBblock을 사용하도록 함
  • 모든 블록을 동일하게 스케일링하는 것이 아니라, 모델 뒷부분이 더 커지도록 점진적으로 확장되는 구조 사용

 

학습 빠른건 너무 넘사벽이라 안 가져왔고, 아래는 파라미터나 플롭수 효율을 다른 논문과 비교할때 보려고 긁어왔다.

보면 의아한점이 있는데, ViT보다 DeiT가 더 나중에 나왔기 때문에 성능도 DeiT가 더 좋은걸로 알고있는데 (위에 있는 그래프 참고), trade-off는 고사하고 왜 accuracy값 자체가 더 낮은거지? 이해가 안간다.

DeiT가 EffNet V1(검은색)보다 원래 더 좋은걸로 알고있어서 EffNet v2와 비교가 기대되었는데 이게 뭐지...

=> 잘 보면 아래에 distill, ensemble 안 썼다고 한다. (그냥 DeiT는 그냥 ViT에 regularization만 썼다는 소리..;;;)

 

Swin Transformer

https://arxiv.org/pdf/2103.14030v1.pdf

얼마전 백본에 이거 쓰겠다고 mmsegmentation 업데이트 하느라 조금 애먹었다.

여담이지만 resnest + deeplab v3plus를 사용할때는 문제가 없었는데, swin으로 넘어오니까 파워 문제로 GPU가 사망하고 있다. 기껏 셋업했는데...ㅠ V100 써야겠음

 

아키텍쳐는 CNN없이 그냥 원래 익숙한 ViT처럼 생겼는데, self-attention layer 대신에 Swin block + Patch merging 구조이다.

저기서 W-MSA는 원래 알고있는 멀티헤드 어텐션이니까 SW-MSA를 보는 게 핵심이겠다.

그림만 봐서 잘 이해가 되진 않지만, patch 단위로 전부 어텐션을 하는게 아니라 window partition으로 묶어서 함으로써 연산을 줄였을 것 같다. 

슬프게도 그래프가 없다. 테이블로 되어있어서 비교하기 불편함

하지만 괜찮다. CMT에 있으니까!

아래는 segmentation 결과인데, 파랗게 긁어놓은 셋팅에서 UperNet+Swin으로 갈아탔으니 터질 수 밖에 없구나 싶다. 어쩐지 자꾸 파워가 튀더라. 메모리도 메모리고 FLOPS 자체가 어마어마하다...  성능은 확실히 좋다.

 

 

CMT

https://arxiv.org/pdf/2107.06263.pdf    

사실 이거 이번달에 팀원분이 발표해주신대서 그때 들으려고 안읽었지만 대충 적어본다.

 

CNN + Transformer.

앞에 설명한 고려사항, 연구 흐름에서 언급되었던 몇가지가 반영되었다.

일단 성능부터 서열정리 하고 들어가자.

Swin은 FLOPS 측면에서 보면 EfficientNet보다 안좋다.

유사한 성능이라고 가정한다면 CNN 기반에 비하면 transformer 기반이 inference는 빠른데, 파라미터수와 FLOPS 측면에서 안좋다는 특징이 있었다. 아까 테이블을 보면 Swin만의 특징은 아닌 것 같다.

 

그런데 그 FLOPS를 기준으로 봤음에도 CMT는 EfficientNet보다 잘나온다.

역시 하이브리드가 대세인건가 융복합형 인재

 

그럼 어떻게 CNN + Transformer 했을까.

모델 초반에 CMT Stem이 보이는데, 초반에 conv를 쓰자고 stem을 고안한건 ViT 후속연구 나열할때 언급했던 그 논문에서 나왔었다.

중간에 이미지 크기는 2*2 conv (stride=2)로 줄이는 것 같고. CMT 블록이 핵심인듯

  • LightWeight MHSA에선 attention 연산을 줄이는데에 초점을 둔 듯 하다. spatial 크기를 k로 나눠서 계산한걸로 보인다.
    swin처럼 슬라이딩 윈도우같은 그런건 아니다.
  • EfficientNet V1처럼 compound scaling을 적용했다.
    다만 transformer에 맞춰 약간 다르다.
    참고로 NAS로 서치하지는 않았고, 실험을 통해서 알파 베타 감마값을 설정했다고 한다.

 

멋진 실험결과.

근데 역시 DeiT의 Distillation 쓴건 깍두기 취급되어서 여기서도 슬픈 대우를 받고 있다.

 

결론

EfficientNet V2가 최강인걸로 보인다.

FLOPS와의 trade-off 그래프가 EffNet V2와 CMT에 둘다 있어서 비교하기가 좋은데, EffNet V2는 성능이 너무 많이 올랐다.

CMT까지 나왔지만 차이가 압도적인듯. 현재 시점 기준.

 

 

 

 

-

뭔가 자세히 쓰면 글이 너무 길어질 것 같다... 쫌쫌따리 추가해야지

반응형

댓글