DenseNet의 이해

박재한·2022년 3월 2일
1

Deep Learning

목록 보기
13/22

참고1
참고2
본 내용은 DenseNet으로 잘 알려져 있는 CNN architecture를 다룬 “Densely Connected Convolutional Networks”의 훌륭한 논문을 바탕으로 정리한 것이다.
2017년 CVPR Best Paper Award를 받았으며 아이디어가 참신하고 구현이 용이하다는 장점이 있다.(CVPR : Computer Vision and Pattern Recognition, 국제 컴퓨터 비전 및 패턴인식 학술대회)

1. ResNet에서 제기된 문제점

전통적인 Convolution Network의 모델을 식으로 표현 해 보자면
xl=Hl(xl1)x_l=H_l(x_{l-1})
이라고 할 수 있다.
이전 레이어에서 Conv layer을 포함한 합성함수의 Output을 다음 레이어로 넘기는 형태이다.
ResNet은 기존 Conv layer가 너무 많이 쌓이게 되면 필터를 너무 많이 거치게 되어서 모델이 한참 이전의 레이어와 이후의 레이어 간의 의미있는 논리를 합해서 전개하지 못한다는 것을 해결하기 위해 이전 레이어에서 다음 레이어를 바로 이어주는 추가적인 Connection을 만들어 주었다.
ResNet은 이를 식으로 다음과 같이 표현하였다.
xl=Hl(xl1)+xl1x_l=H_l(x_{l-1})+ x_{l-1}
하지만 이전 레이어의 output을 다음의 레이어의 output과 합해서 더한다는 점에서, 정보들이 이후의 레이어들로 온전히 흘러가는 것을 방해할 수 있다는 약점이 있었다.
(아무래도 이전 정보와 다음 정보를 각각 분리해서 분석할 수 없고, 그냥 통으로 합해버리는 부분 때문에 그런 것 같다.)

2. DenseNet의 구조

2.1 Dense Connectivity

Layer간의 정보가 흘러가는 것을 개선하기 위해, DenseNet에서는 ResNet과는 조금 다른 연결 패턴을 제안했다.
아래 그림처럼 DenseNet에서는 모든 이전 레이어의 output 정보를 이후의 레이어의 input으로 받아오는 방법을 사용했다.

그러니까, 결과적으로 ll번째 layer는 이전 모든 0,1,2...,l10,1,2...,l-1 번째의 output들을 입력으로 사용하게 되고, 그 결과인 xlx_l을 수식으로 표현하자면 다음과 같다.
xl=Hl([x0,x1,x2,...,xl1])x_l=H_l(\left[x_0, x_1, x_2, ..., x_{l-1}\right])
이전 layer들의 feature map을 계속해서 다음 layer의 입력과 연결하는 아이디어는 ResNet과 같은데 ResNet에서는 feature map끼리 더하기를 해주는 방식이었다면 DenseNet에서는 feature map끼리 concatenation을 시켜주는 것이 가장 큰 차이점이다. 물론 layer사이에 연결되는 방식도 다르다.(ResNet는 바로 직전의 Resudual block에서만 connection이 연결되었지만 DenseNet는 Dense Block 내에서는 ll번째 layer 이전의 모든 layer(l1,...,1,0l-1, ..., 1, 0)에 연결이 된다.)
[x0,x1,x2,...,xl1]\left[x_0, x_1, x_2, ..., x_{l-1}\right]은 모든 input을 이어붙인 것을 나타낸다.

그림은 이전 layer의 output을 concatenation하는 것을 보여준다.

그리고 조금 더 나아가서, 모든 모델을 이렇게만 구현하지 않고, 이렇게 이어붙인 Connection의 덩어리를 하나의 Block으로 만들어서 그 덩어리들을 이어붙인것을 총 하나의 모델로 만들었다.
이해를 돕기위해 아래의 그림을 예로 들어 설명하겠다.

Dense Block이라고 부르는 하나의 connection 덩어리를 만들어서 전통적인 CNN처럼 Convolution , Pooling layer과 함께 순차적으로 Dense Block들을 거쳐서 마지막에 Linear layer후 결과를 뽑아내게 된다.
이러한 구조를 통해 얻을 수 있는 이점은 다음과 같습니다.

  • Vanishing Gradient 개선
  • Feature Propagation 강화
  • Feature Reuse
  • Parameter 수 절약

2.2 Growth Rate

각 feature map끼리 densely 연결이 되는 구조이다 보니 자칫 feature map의 channel 개수가 많은 경우 계속해서 channel-wise로 concat이 되면서 channel이 많아 질 수 있다. 그래서 DenseNet에서는 각 layer의 feature map의 channel 개수를 굉장히 작은 값을 사용하며, 이 때 각 layer의 feature map의 channel 개수를 growth rate(k) 이라 부른다.
k값은 hyper parameter로 학습하기 전에 미리 설정해 줘야 하는데 보통 4로 설정한다.

위의 Figure 1 그림은 k(growth rate) = 4 인 경우를 의미하며 Figure 1 그림의 경우로 설명하면 6 channel feature map 입력이 dense block내의 4번의 convolution block을 통해 (6 + 4 + 4 + 4 + 4 = 22) 개의 channel을 갖는 feature map output으로 계산이 되는 과정을 보여주고 있다.

2.3 Bottleneck Layer

ResNet과 Inception 등에서 사용되는 bottleneck layer의 아이디어는 DenseNet에서도 찾아볼 수 있다.

3x3 convolution 전에 1x1 convolution을 거쳐서 입력 feature map의 channel 개수를 줄이는 것 까지는 같은데, 그 뒤로 다시 입력 feature map의 channel 개수(위 그림의 예에서는 256개) 만큼을 생성하는 대신 growth rate 만큼의 feature map을 생성하는 것이 차이 점이며 이를 통해 computational cost를 줄일 수 있다고 한다.
또한 구현할 때 약간 특이한 점이 존재하는데 DenseNet의 Bottleneck Layer는 1x1 convolution 연산을 통해 4*growth rate 개의 feature map을 만들고 그 뒤에 3x3 convolution을 통해 growth rate 개의 feature map으로 줄여주는 점이 특이하다.(256개가 아닌 k개, 앞에서 한번 언급했었음!) Bottleneck layer를 사용하면, 사용하지 않을 때 보다 비슷한 parameter 개수로 더 좋은 성능을 보임을 논문에서 제시하고 있다.
다만 4 * growth rate의 4배 라는 수치는 hyper-parameter이고 이에 대한 자세한 설명은 하고 있지 않고있다.

2.4 Transition Layer

다음으로 설명할 부분은 Transition layer이며 feature map의 가로, 세로 사이즈를 줄여주고 feature map의 개수를 줄여주는 역할을 담당하고 있다. 마지막 Dense Block을 제외한 나머지 Dense Block의 뒤에 연결이 되며 Batch Normalization, ReLU, 1x1 convolution, 2x2 average pooling 으로 구성이 되어있다.
1x1 convolution을 통해 feature map의 개수를 줄여주며 이 때 줄여주는 정도를 나타내는 theta 를 논문에서는 0.5를 사용하였으며 마찬가지로 이 값도 hyper-parameter이다. 이 과정을 Compression이라 논문에서 표현하고 있다. 즉 논문에서 제시하고 있는 transition layer를 통과하면 feature map의 개수(channel)이 절반으로 줄어들고, 2x2 average pooling layer를 통해 feature map의 가로 세로 크기 또한 절반으로 줄어든다. 물론 theta를 1로 사용하면 feature map의 개수를 그대로 가져가는 것을 의미한다.

2.5 Composite Function

DenseNet은 ResNet의 구조에 대해 분석한 “Identity mappings in deep residual networks, 2016 ECCV” 논문에서 실험을 통해 제안한 BatchNorm-ReLU-Conv 순서의 pre-activation 구조를 사용하였다.(이 부분은 ResNet에서 사용했었던 것과 동일하다.)

2.6 DenseNet Architecture

앞에서 개별적으로 설명한 것을 모아서 하나의 아키텍처로 설명한다.

위 그림은 최초 input으로부터 하나의 Dense Block과 Transition Layer을 거칠 때까지의 구조이다.
Dense Block에서 초록색 사각형과 검은색 사각형이 Bottleneck layer를 만들며 그림에서는 Bottleneck layer가 3개가 모여있다. Dense Block내의 Bottleneck layer는 깊이가 깊어질수록 concatenation되는 것을 볼 수 있다.
Dense Block이 끝나고 Transition Layer가 연결되어 있음을 알 수 있다.


위 그림은 DenseNet 전체의 구조를 나타내었다. Input이 있고 Dense block 다음에 Transition layer가 연결되어 있으며 마지막 Dense block 다음에는 Transition layer가 아닌 Classification layer가 연결되어 있는 것을 알 수 있다. Classification layer를 거쳐서 최종적인 output인 예측값이 나온다.
Dense block에는 이전 layer의 input 정보들이(h0h_0~hl1h_{l-1}) concatenation되고 있는 것을 볼 수 있고, Dense block내의 layer들은 Composite function에 의해 Batch Norm.-ReLU-Conv로 구성되어 있다. 그림에는 적용이 안되어져 있는데 Bottleneck이 적용이 되면 Batch Norm.-ReLU-Conv(1X1)-Batch Norm.-ReLU-Conv(3X3)의 구조가 된다.
아래 그림처럼 될 것이다.

논문에서 소개하는 DenseNet architecture

Table1.의 설명을 보면 k는 32 또는 48로 잡았고 Dense Block의 conv layer는 composite function이 적용되어 Batch Norm.-ReLU-Conv의 구조로 되어 있다.
DenseNet-121의 경우는,
Input conv, pooling : 1
Dense bolck(1) : 2X16=12
Transition : 1
Dense bolck(2) : 2X12=24
Transition : 1
Dense bolck(3) : 2X24=48
Transition : 1
Dense bolck(3) : 2X16=32
Classification : 1
1 + 12 + 1 + 24 + 1 + 48 + 1 + 32 + 1 = 121
이 된다.

3. 성능 평가

실험을 통해 ResNet과 DenseNet의 성능을 비교하였다.
학습 및 검증용 데이터는 ImageNet dataset를 이용하였다. ImageNet dataset는 keras의 MNIST, CIFAR dataset과 더불어 굉장히 유명한 dataset이다

ResNet에 비해 DenseNet이 동일한 error rate대비 계산에 필요한 파라미터 갯수가 ResNet의 1/3 정도로 더 적고 연산횟수(flops)도 더 적은 것을 볼 수 있다.
즉 ResNet과 비슷한 성능을 내면서 연산면에서는 훨씬 더 효율적인 것을 볼 수 있다.

profile
바쁘게 부지런하게 논리적으로 살자!!!

0개의 댓글