scalalang2

Bag-of-Tricks — 딥러닝 성능을 높이기 위한, 다양한 꿀팁들

딥러닝 연구 분야 중에서도 특히 이미지 분류는 그동안 많은 아키텍처가 제안되었고 높은 성능을 보여주었다. 대표적으로 2012년에 발표된 AlexNet과 이후에 제안된 VGG, Inception Layer, Residual Block, DenseNet, NASNet 등이 있다. 이 접근법의 특징은 네트워크 모델을 수정하거나 새로운 모델을 만들어서 다양한 관점에서 성능을 높인다.

이번 포스팅에서 소개 하려는 꿀팁은 새로운 모델이 아닌, 딥러닝에서 사용되는 “이름 없는 꿀팁”들이다. 예를 들면 학습단계에서 특정 컨볼루션 레이어에서 Stride 크기를 변경하거나 학습율을 변경하는 스케쥴을 조정하는 기법 등이 있다. 이 트릭들은 개별적으로는 너무 단순해서 별로 주목받지 않지만, 사실 네트워크 성능 향상에 엄청난 도움을 주는 것들이다. 이를 이용하면 완전히 새로운 구성을 가진 네트워크보다 더 높은 정확도를 낼 수 있다.

이렇게 학습에 도움을 주는 트릭을 모아서 집대성하고 분석한 논문이 있다. AWS(Amazon Web Services)에서 발표한 Bag of Tricks[1]이다. 이 논문은 2018년에 처음 공개되었고 2019년에 CVPR 에서 발표되었다. (포스팅에서는 꿀팁이라고 적었지만, 이제부터는 논문에서 사용하는 용어인 트릭을 사용하겠다)

본 글의 구성에 대해서 말하자면, 먼저 트릭이 적용 되었을 때와 적용되지 않았을 때의 차이점을 명확히 구분 하기 위해 기준점으로 사용되는 기준 모델을 설정한다. 그 다음에는 대규모 배치-학습에서 사용되는 트릭들과 모델을 변경하는 트릭, 마지막으로 학습 단계에서 사용되는 트릭을 차례로 소개하고 결론으로 마무리 짓는다.

구성

기준 모델 설정

Bag-of-Tricks 논문에서는 트릭을 적용했을 때와 적용하지 않았을 때의 차이를 비교하기 위해서 기준 모델(비교 모델)을 설정하였다. 이미지 전처리 및 학습 장비, 알고리즘, 배치 사이즈 크기, 초기값 설정 등 많은 작업이 있지만 이 포스팅에서는 자세히 다루지 않기 때문에 궁금하신 분들은 아래 레퍼런스[1]를 참고해주길 바란다. 아래 [표 1]은 논문에서 나온 기준 모델의 성능이다. 학습 데이터는 ILSVRC2012[2]를 사용하였다.

[표 1] 기준 모델의 학습 정확도

배치-학습 트릭 (Large-batch training)

학습 단계에서 Mini-batch SGD를 이용할 때, 배치사이즈를 가능한 최대로 키우는 것이 병렬성을 높이고 커뮤니케이션 비용을 낮춘다고 알려져 있다[3].하지만 배치 사이즈를 키우면 Convex Problem에서 수렴성을 낮추기 때문에 일반화된 지식을 학습하기 어려워 진다. 논문에서는 이 문제를 해결하기 위해 5가지 트릭을 소개한다.

1. Linear scaling learning rate

배치 사이즈를 키우면 SGD의 기댓값은 동일하지만, 분산이 크게 줄어 기울기의 노이즈가 감소한다. 그래서 가장 먼저 배치 사이즈를 키우면서 동시에 Learning Rate(LR)를 증가시키는 방법을 생각해볼 수 있다. 본 논문에서는 LR의 초기값을 0.1로 설정 하고 아래 수식을 이용하여 LR을 증가 시키는 방법을 이용한다. [0.1 x b/256] 여기서 b는 배치 사이즈의 크기이다.

2. Learning rate warmup

모델을 생성할 때 모든 weight값을 랜덤값으로 초기화 하기 때문에 처음부터 LR을 크게 설정하면 학습이 잘되지 않는다. 운동 초기에 몸을 풀어주기 위해 간단한 스트레칭을 하듯이 모델도 [1번] 트릭을 이용하기 위해 적절히 웜업을 해주면 좋다. 학습 초반에 LR값을 0에 가까운 값부터 시작해서 우리가 원하는 값까지 천천히 올려주면 초반 학습에 도움이 된다.

3. Zero Gamma

ResNet의 Residual Block은 마지막 레이어에 배치 정규화(BN)레이어를 둔다. BN레이어는 감마와 베타값을 이용하는데, 초기에 각각 1, 0으로 설정하고 학습을 진행한다. 여기서 우리는 감마값을 0으로 설정하여 BN레이어의 아웃풋값이 인풋값과 동일하게 만든다. 이 트릭은 학습해야 하는 레이어의 수를 줄임으로서 초반 학습에 도움을 주기 위함이다. 교수님께서 과제를 너무 많이 내주면 학생들의 머리가 아프기 때문에 과제를 조금 줄여주신 것과 같은 원리로 이해할 수 있을 것 같다.

4. No bias decay

학습에서 가중치(weight)가 필요 이상으로 커지면서 발생하는 과적합(Over-fitting) 문제를 해결하고자 가중치 값이 커지는 것을 의도적으로 억제하는 weight decay라는 방법이 있다. 이를 L2정규화 라고 부른다. 텐센트의 Xianyan Jia의 연구[4]에 따르면 편향치(bias)에는 decay방법을 적용하지 않는게 과적합 문제를 방지하는데 도움이 된다고 한다. 그래서 Bag-of-Tricks 논문에서는 컨볼루션과 Fully-Connected 레이어에서만 정규화를 적용하고 BN 레이어에서는 정규화를 적용하지 않는 방법을 이용한다.

5. Low-precision training

NVIDIA V100 장비는 32비트의 부동 소수점에선 14 테라플롭스의 성능을 제공하지만 16비트의 부동 소수점 연산을 사용하면 100 테라플롭스의 성능까지 사용할 수 있다. 그래서 딥러닝 학습을 할 때 부동소수점을 32비트에서 16비트로 변환하고 가중치 값이 유실되는 것을 방지하기 위해 스칼라 값을 곱해서 사용하면 학습할 때 2–3배 정도 성능을 높일 수 있다고 한다.

실험 결과

아래 [표 2]는 기준 모델과 위에서 소개한 5가지 트릭을 모두 적용했을 때의 학습시간과 정확도를 보여준다. 정확도 측면에서는 많이 증가한 건 아니지만 학습 속도는 확연히 빠른 것을 확인할 수 있다.

[표 2] 배치-학습 트릭을 이용한 모델과 기준 모델의 성능 비교

논문을 보면 각 트릭을 따로 적용했을 때도 성능 비교를 하였는데 많은 차이가 없었기 때문에 여기서는 따로 서술하지 않는다.

모델 정말 조금 바꿔서 성능 높이기 (Model Tweaks)

이번에는 모델을 정말 조금만 바꿔서 성능을 높이는 트릭을 소개한다. 여기서 조금만 바꾼다는 이야기는 Stride 사이즈를 변경하거나 Kernel 사이즈를 작게 만드는, 코딩 할 때 단어 하나 바꾸는 수준으로 이득을 볼 수 있는 것들이다. 논문에서는 ResNet을 기준으로 실험을 했기 때문에 Residual Block을 변경하는 것만 다루었는데 다른 모델에서도 충분히 적용 가능한 이야기다. 이 트릭들은 별도로 이름이 붙진 않았고 각각을 B, C, D의 알파벳으로 구분하였다.

[그림 1] ResNet와 ResNet-[B,C,D]의 그림

1. ResNet-B

기존 Residual Block에선 다운샘플링을 수행할 때 첫번째 컨볼루션 레이어의 커널 사이즈가 1이고 Stride값이 2로 설정되어 있었다. [그림 1]에서 Path A라고 적혀진 부분을 보면 나와있다. 하지만, Stride값이 커널 사이즈보다 크기 때문에 학습에서 아예 무시하는 픽셀값이 생기게 된다. ResNet-B는 이를 보완하기 위해 3x3의 커널을 사용한다.

2. ResNet-C

Residual Block 인풋값의 첫번째 컨볼루션 레이어가 7x7 커널을 이용하고 있는데 컨볼루션 연산의 특징상 커널 사이즈가 커지면 요구되는 연산력이 제곱으로 증가한다. 예를 들어, 7x7 커널의 연산력은 3x3 커널의 연산력보다 5.4배나 더 필요하다. 그래서 연산 속도를 높이기 위해 3x3 커널로 교체한게 ResNet-C 모델이다. 위 [그림 1]의 Figure 2. (b)를 보면 확인할 수 있다.

3. ResNet-D

ResNet-B와 동일하게 다운샘플링을 수행할 때 정보 유실을 방지하기 위해서 Path B에서 2x2 Average Pooling(AP) 레이어를 사용한다. 컨볼루션 레이어를 바로 통과 시키는 것보다 2x2 AP를 이용하면 연산력을 크게 아낄 수 있다고 한다. 각 모델을 수행했을 때 나오는 결과는 아래 [표 3]과 같다. 코드-레벨 에서 생각해보면 정말 한줄정도만 고쳐도 1% 까지의 정확도를 높이면서 연산 속도도 챙길 수 있는 꿀팁이라고 볼 수 있다.

[표 3] ResNet, ResNet-[B,C,D] 성능 비교

Model Tweaks 파트에서는 정말 간단하게 다루어서 논문을 읽으면서 조금 지루한 감이 있었는데 그 다음에 소개하는 학습 조정 전략(Training Refinements)에서는 재밌는 이야기가 나온다.

학습 조정 전략 (Training Refinements)

이 단원에서는 학습 단계에서 발생하는 트릭들을 소개하는데, Cosine Learning Rate Decay, Label Smoothing, Knowledge Distillation, Mixup Training 으로 총 네 가지 전략을 소개한다.

1. Cosine Learning Rate Decay

초반에는 학습울(LR)을 크게 잡아서 학습을 하고 학습 후반기에 갈수록 LR값을 점차 감소시켜 최적해로 안정적으로 수렴하게끔 만드는 전략을 쓰는데, 단순하게는 30 epoch마다 0.1씩 빼주는 방법 등이 있다. 하지만, 이렇게 하면 학습율의 변화가 매우 급진적으로 변하게 되는데 이를 보완하고자 Cosine Learning Rate Decay 기법을 사용할 수 있다. 이 방법은 SGDR 논문에서 소개되었다[5]. 아래 [그림 2]는 코싸인을 적용한 수식이다.

[그림 2] Cosine Learning Rate Decay

T는 전체 배치의 크기를 나타내고 t는 학습 회차를 나타낸다. cos(0)=1 이므로 처음에는 설정한 학습율 n과 같다가 점차 감소하게 된다. 아래 [그림 3]은 코싸인을 적용했을 때 학습율이 감소하는 그래프를 보여준다. 아래 그림에서 학습율이 초반에는 작다가 갑자기 커지는 현상은 위에서 소개한 학습율 웜업(Learning rate warmup)을 이용한 것이다.

[그림 3] Cosine Learning Rate Decay의 그래프

2. Label Smoothing

라벨 스무딩기법은 Inception-v2 논문[6] 에서 처음 소개된 기법이다. 논문에서는 수식으로 설명하지만 여기서는 결론만 말하자면, Softmax로 나온 확률값을 손실 함수에서 크로스-엔트로피를 적용하는 방법이 너무 극단적인 확률값을 만들고 이를 해결하는게 라벨 스무딩이다. 이런 극단적인 결과를 만드는 것을 우리는 Overconfident 하다고 말한다. 다른말로 Poorly-calibrated 되었다로고도 말하는데, 우리가 모델의 학습 결과로 원하는게 실제 데이터 분류의 확률분포를 잘 계산하는 것이라고 한다면 기존 방법은 실제 확률 분포와 잘 맞지 않는다고 말할 수 있다. 이를 처음으로 정의한 논문이 있으니 나중에 각잡고 제대로 보는게 좋을 것 같다[7].

[그림 4] 크로스-엔트로피와 라벨 스무딩의 최적해 예시

3. Knowledge Distillation

지식 증류(Knowledge Distillation)란 기존에 이미 잘 학습된 네트워크의 지식을 내가 새롭게 학습하고자 하는 네트워크로 전달하는 기술이다. 지식 증류의 원래 취지는 복잡하고 거대한 학습 네트워크의 지식을 단순하고 작은 네트워크로 전달하는 것이다. 앙상블 모델처럼 거대한 네트워크는 학습 시간과 서빙 시간이 상당히 느린데 이를 빠르게 하기 위해 상대적으로 작은 네트워크로 지식을 전달하는 게 지식 증류 방법이다. Bag-of-Tricks 논문에서는 이 지식 증류 방법이 성능 향상에 도움이 된다고 말한다.

4. Mixup Training

믹스업 기법[9]은 학습 단계에서 두 개의 인풋 데이터를 랜덤으로 샘플링해서 새로운 인풋을 적절히 섞어서 만드는 기법이다. 이 기법을 적용하면 네트워크는 여기서 샘플링한 값만을 인풋값으로 입력받는다. 아래 [그림 5]는 믹스업 기법에서 사용하는 수식이며, 람다값은 베타 분포에서 가져오는 값이다.

[그림 5] Mixup-Training

이 믹스업 기법을 적용하면 학습의 일반화에 도움을 준다고 한다. Mixup 논문[9] 에서는 이를 이론적으로 설명하기 때문에 직관적으로 받아들이기 어려운데, 이를 쉽게 설명한 포스팅[10]에 따르면 데이터를 일부러 식별하기 어렵게 만들어서 학습에 어려움을 주는 것이다. 예를 들어 누가봐도 100% 강아지인 사진보다 80%의 확률로 강아지인데.. 20% 확률로 고양이 인 것 같기도 한 사진을 만들어서 과적합 문제에 빠지는 것을 방지할 수 있다고 한다. 마치 맨날 하던 쉬운 코딩보다 조금 더 어려운 코딩을 도전하는게 실력을 높이는데 도움을 주는 것과 똑같은 원리인듯 하다.

믹스업은 ICLR 2018에서 발표되었다. 그리고 믹스업 논문을 보면 GAN학습의 안정화에도 많은 도움을 준다고 하니 생성모델을 관심있게 보신 분들이라면 참고해도 좋을 것 같다. 아래 [표 4]는 학습 조정 전략 파트에서 소개한 4가지 트릭을 적용했을 때의 정확도를 나타낸다. 많게는 2% 까지 정확도가 증가한 것을 알 수 있다.

[표 4] 학습 조정 전략을 적용한 모델과 기존 모델의 성능 비교

결론

결론으로 이 논문에서 소개한 모든 트릭을 적용했을 때의 효과는 아래 [표 5]와 같다. 기존 ResNet모델에서 최대 4%까지 정확도 높일 수 있었는데 이 논문에서는 새로운 아키텍처를 설계하지 않아도 잘 알려진 트릭을 사용하면 더 좋은 정확도를 낼 수 있다는 것을 보여주기 위해 다른 모델과 함께 비교하였다.

[표 5] 논문에서 소개한 모든 트릭을 적용한 결과

마지막으로 필자의 소감을 서술하자면, 대부분의 논문은 하나의 내용을 자세히 다루는 경우가 많다. 반면, 이처럼 해당 분야의 거시적인 시각을 제공해 주는 논문들도 있다. 아직 머신러닝 분야의 학습이 부족한 내게 이 논문이 딥러닝 분야 중 이미지 분류 문제에 대해서 많은 것을 알 수 있게 돼서 재밌게 읽었다.

레퍼런스

[1] Bag of Tricks for Image Classification with Convolutional Neural Networks, CVPR 2019, Tong He, Amazon Web Services
[2] Large Scale Visual Recognition Challenge 2012 (ILSVRC2012)
[3] SGD에서 배치 사이즈가 학습과 성능에 미치는 영향
[4] Highly Scalable Deep Learning Training System with Mixed-Precision: Training ImageNet in Four Minutes
[5] SGDR: Stochastic Gradient Descent with Warm Restarts
[6] Rethinking the Inception Architecture for Computer Vision
[8] On Calibration of Modern Neural Networks
[9] mixup: Beyond Empirical Risk Minimization
[10] Mixup data augmentation