본문 바로가기
논문 리뷰/Classification

[논문 리뷰] DenseNet(2017) 설명

by inhovation97 2022. 2. 5.

논문 한편을 전부 번역하다시피 통째로 리뷰하니까 너무 힘든 것 같아서 Abstract만 자세히 살피고, 핵심 부분을 정리하여 리뷰하겠습니다. 

DenseNet 논문링크

DenseNet도 CNN에서는 매우 유명한 모델 중에 하나죠. 

굉장히 다양한 task에서 Dense block을 차용하여 많이 이용합니다. 

해당 논문을 보면, DenseNet 저자들이 ResNet을 많이 언급하고 비교도 많이 합니다. 아마 ResNet을 거의 counterpart로 두고 연구를 많이 진행한 것(?) 같습니다. 제가 리뷰한 ResNet 논문 리뷰를 같이 읽으시면, 도움이 많이 되실 겁니다!

ResNet 논문리뷰

 

1. Abstract
2. Dense block 구조
3. DenseNet 전체 구조도 & 실험
4. ResNet과의 차이점과 장점
5. DenseNet AveragePooling의 이유 (개인적인 생각)

 

 

Abstract

 

당시 CNN의 연구가 구조적으로 더 깊고, 더 정확한 성능을 낼 수 있는 방법에 대해서 input layer 와 output layer가 direct하게 연결될 수 있는 shorter connection 개념에 집중하여, 효율적으로 train하는 형식으로 발전하고 있습니다.

(resnet이 굉장한 성능을 보여주었음.)

 

따라서 이 논문은 당시 연구주제에 초점을 맞추어 feed forward 방식에서 각 레이어들이 모든 다른 레이어와 connect를 두는 DenseNet을 소개합니다. 이제까지는 layer가 그 다음 하위 레이어와의 연결 구조를 갖는 CNN과는 달리 DenseNet은 L(L+1)/2개의 direct connection을 갖는 새로운 구조입니다.

( 등차 수열 합 공식임을 보아 첫 layer ~ 마지막 layer까지 전부 연결되어 있음을 직감할 수 있음. )

앞 layer에서 얻은 모든 feature map은 계속해서 뒤 layer의 입력으로 입력되는 구조입니다.

 

DenseNet의 큰 장점

1. vanishing gradient를 방지할 수 있다.

2. feature propagation을 강화할 수 있다.

3. feature의 재사용이 권장된다.

4. 파라미터 수를 많이 줄일 수 있다.

 

4개의 대표적인 데이터셋(cifar-10, cifar-100, SVHN, ImageNet)에서 모두 좋은 성능을 거두었으며, 당시 state-of-the-art의 성능이면서도 엄청난 계산 복잡도를 낮추었습니다. 

 

 

 

 

 

DenseNet의 구조

 

논문을 펼치면 바로 보이는 Dense block의 구조도입니다. input부터 output까지 전부 L(L+1)/2개의 connection이 보이는 걸 확인할 수 있습니다. 

우선 ResNet과의 가장 큰 차이점은 connection 방식입니다.

Residual block connection

ResNet은 Conv layer를 거쳐 나온 output Feature map의 값들과 Conv layer를 거치기 전 input Feature map의 값들을 서로 element wise하여, 같은 자리의 값끼리 add하는 방식으로 connection을 해주어 다음 layer의 입력값으로 넣어주는 구조를 취했습니다. 

(그렇게 잔차를 학습하는 형태를 만든다고 하여, ResNet이라는 이름이 붙었던 것입니다.)

 

 

Dense block connection

위 figure1을 보면서 DenseNet을 이해해봅시다.

input값 x0부터 순차적으로 보면,

x0가 H1 (BN-ReLU- 3x3 Conv)을 거쳐서 초록색의 feature map 4장 x1을 생성합니다. 

이때 x1이 H2의 입력값으로 들어가기 전에 x0와 x1을 concatenate해줍니다.

(add해주는 resnet과는 다른 방식)

feature map간의 concat이기 때문에 H2 layer의 입력값은 (H x W x 10) (x0 6장 + x1 4장)이 되는 겁니다.

이렇게 계속 h layer를 거칠때마다 이전에 입력값이었던 output feature map들을 계속 concat하여 입력해주는 것입니다.

이때 각 dense block에서 몇 개의 feature map을 뽑을지 결정하는 하이퍼 파라미터는 논문에서

 

growth rate 'k'라고 하며, 이 값은 모델의 파라미터의 수에 직접적인 영향을 갖는 인자입니다.

위 figure 1의 경우 k=4를 예로 든 것을 알 수 있습니다. 원래는 깊이가 깊어질수록 conv block 한 번에 상당히 많은 개수의 feature map을 뽑지만, 논문에서는 이번 실험에 block 마다 k = 12개로 설정하여 아주 효율적인 구조라고 설명합니다. 

(모델 구조상 k를 크게 둘 필요가 없는거죠.)

 

-> ResNet과는 마찬가지로 반드시 같은 사이즈의 feature map끼리 connection이 통하고, 마지막 Dense block으로 output이 나오면, 끝에 보이는 Transition Layer로 진입합니다.

 

Transition Layer는 1x1 Conv layer -> 2x2 avgPooling(2stride) 로 구성돼있습니다.

transition layer는 Dense block에서 down sizing을 할 수 없으니,

1x1 Conv layer로 일단 한번 feature들을 정리해준 뒤 Pooling을 통해 half size로 줄이는 역할을 해줍니다. 

독특하게 avg pooling을 해주는 것을 알 수 있습니다.

여기서도 하이퍼 파라미터 0 <θ ≤1가 존재합니다. 

θ 는 dense block에서 featrue map m개를 입력받았다면, transition layer가 출력하는 feature map 개수를 조정하는 인자로서 m*θ 로 출력 channel을 맞추어 줍니다.

논문에서는 0.5로 두어 실험을 진행했다고 합니다.

-> avg pooling에 대해서는 제가 끝에 다시 한 번 언급하여 제 생각을 나름대로 정리해보겠습니다. 

 

 

 

 

DenseNet 전체 구조도 & 실험

위에서 설명한 Dense block과 transition layer를 결합하여 최종적으로 위 fig와 같은 아키텍쳐가 만들어집니다.

 

이미지 넷 데이터셋을 제외한 데이터셋에서는 growth rate = 8인 dense block을 3개로하였으며, 첫 dense block으로 가기전 Conv layer는 16 channel의 feature map을 뽑아냅니다.

세개의 dense block은 각각 {32x32}, {16x16}, {8x8}사이즈의 feature map을 출력해내고(내부에서는 제로 패딩으로 사이즈를 맞춰줌), 끝에는 Global avg Pooling뒤 classifier가 이어집니다. 

{L=40, k=12}, {L=100, k=12}, {L=100, k=24}, {L=250, k=24}, {L=190, k=40}의 여러 아키텍쳐로 실험을 진행

 

 

imagenet 데이터의 모델 구조

이미지 넷은 위 데이터셋과는 달리 스케일이 굉장히 크기 때문에 table1의 아키텍쳐로 실험을 진행합니다.

Densenet-121만 떼서 보면, growth rate = 32로, 각 dense block 마다 conv block이 2개씩 있기 때문에 파라미터 layer 수를 세보면, 2*(6+12+24+16) = 116 layer입니다. 가장 상단의 7x7 Conv layer 1개, transition layer의 1x1 conv layer 3개, 최하단 1000D fc layer 1개를 더해주어 121 - layer architecture임을 알 수 있습니다.

ResNet에 비해 상당히 좋은 결과를 얻은 걸 알 수 있습니다.

 

 

 

 

 

 ResNet과의 차이점과 장점

 

사실 ResNet을 이해하는 데에는 시간이 조금 걸렸습니다.

이전의 입력값을 더해주어서 입력으로 넣어주는 방식이 직관적이지는 않았습니다. 모델도 받아들일때 계속해서 잔차의 차이를 줄이는 방식으로 진행한다고하지만 그 잔차는 batch마다 epoch마다 계속해서 달라질 수도 있다는 생각을 했었죠. 

 

하지만 DenseNet은 상당히 직관적입니다. 이전의 입력값을 넣어주고 그 입력값이 dense block을 거쳐 바뀐 값을 concat하여 원본 값과 바뀐 값을 함께 넣어 인코딩이 이루어지죠. 

 

즉, resnet은 add함으로써 보존해야할 정보를 change하여 다음 layer에 전해줍니다. 

그에 비해 DenseNet은 정보를 바꾸지 않으면서도 굉장히 direct하게 하위의 모든 layer에 뿌려주죠.

information flow가 매우 잘되는 겁니다!

심지어 이 방식의 장점은 information flow뿐만 아니라 gradient flow도 원만하게 해줍니다.

입력값을 뿌려주는 저 connection 하나하나가 사실 gradient의 flow이기도 한거죠. 모델이 깊어질수록 초반부까지 gradient가 흘러가기가 무척 힘들텐데 최상단의 입려값이 최하단의 입력값에도 존재하니 gradient flow가 매우 좋은 겁니다. 

이렇게 정보와 기울기가 잘 보존될 정도로 효율적이니 computational cost도 적은겁니다.

 

 

 

 

DenseNet AveragePooling의 이유(개인적인 생각)

 

이 부분은 지극히 개인적인 의견입니다.

보통은 maxpooling을 넣지만 DenseNet 특이하게도 avg pooling을 이용하여 downsmapling을 진행합니다. 자세한 이유가 기재되어 있지는 않습니다.

DenseNet은 앞에서 나온 output을 계속해서 입력값으로 가져오는 feature Reuse방식입니다. feature map에서 어떤 개체가 있거나 하는 아주 강한 픽셀값(큰 값)은 conv를 계속 거쳐도 살아있을 겁니다.

따라서 같은 사이즈 내에서 계속해서 reuse한 feature map이 concat 되어 있는 output을 max pooling하면 같은 특징들이 뽑힐 확률이 높을 것 같다는 개인적인 생각입니다.

따라서 maxpooling으로 강한 값만 가져오면 비슷한 특징들이 뽑히니, 각 feature map들의 평균값을 가져오는 방식이 더 나은 결과를 얻어내지 않았을까? 싶습니다.

저자들도 아마 이 부분을 실험을 통해서 얻지 않았을까? 싶은데..

 

이것에 대해서는 제가 자료를 좀 더 찾아보고 실험이 없다면 직접 실험해보면 재밌겠다는 생각이 듭니다 ㅎㅎ...

 

댓글