논문 리뷰/others

[간단 리뷰] RepOptimizer (RepOpt-VGG)

curious_cat 2023. 6. 29. 09:13
728x90
728x90

개요

논문 링크: https://arxiv.org/abs/2205.15242

이전 글: [간단 리뷰] RepVGG: Making VGG-style ConvNets Great Again

제목: RE-PARAMETERIZING YOUR OPTIMIZERS RATHER THAN ARCHITECTURES

  • RepVGG 같은 경우 train 할 때 3x3 conv, 1x1 conv, identity branch를 분리해서 block을 만들어서 사용하고, inference 할 때 3개의 branch들을 1개의 convolution operator로 합쳐서 사용한다.
  • 이렇게 했을 때 문제 중 하나가 quantization이 잘 안 된다는 것이다 (간단하게 설명하자면 RepVGG에서 각 branch의 셩격이 다르다 보니 branch들의 kernel weight 통계가 상이하고, 3개의 branch에 해당되는 kernel weight들을 모두 합쳐서 보면 variance가 높다. Quantization이 잘 되려면 kernel weight 값의 범위가 좁아야 한다).
  • 본 논문에서는 RepVGG처럼 block structure을 train/inference 할 branch를 분리하는 대신 gradient descent 하는 방식을 수정해서 RepVGG의 장점을 살리되 quantization이 잘 안 되는 문제를 해결한다.
  • 이렇게 optimize 하는 방식을 RepOptimizer이라고 부르고, RepVGG architecture을 RepOptimizer로 학습한 모델을 RepOpt-VGG라고 부른다.

 

방법

  • 요약본은 Figure 1 참고
  • 우선 간단한 예를 생각해보자. RepVGG의 핵심 아이디어는 branch를 나눠서 학습한 것을 inference 할 때 한 개의 branch로 합쳐서 계산을 병렬화한다는 것이다. 간단하게 2개의 branch (A,B)로 나뉘는 상황을 생각해 보자 
    • Branch가 나뉜 convolution block은 다음과 같이 적을 수 있다 :
      \( Y_{CSLA} = \alpha_A (X * W^{(A)}) + \alpha_B (X * W^{(B)})\)
      여기서 * = convolution,  W = filter, X = input, Y = output, \( \alpha_{A,B}\) = 나중에 의미가 명확해질 상수
      CSLA: constant scale linear addition 약자. 다른 branch들을 상수로 곱한 후 더해줬다는 의미
    • 이 두 branch를 다음과 합칠 수 있다 (notation 의미는 위 상황과 기본적으로 같다):
      \( Y_{RG} = X * W'\)
      밑에 설명하겠지만 gradient descent를할 때 학습 방식을 잘 선택하면 \( Y_{CSLA}\)와 \( Y_{GR}\)이 같아진다. 
      GR: gradient reparametrization 의 약자 (밑에 설명할 학습방식 참고)
    • 학습 방식: initialization과 gradient 를 다음과 같이 하면 동일하다 (증명은 논문 참고)
      1. Initialization:
      CSLA의 초기 값이 \( W^{(A,B)(0)}\)이면
      GR의 초기 값은 \( W'^{(0)} = \alpha_A W^{(A)(0)} + \alpha_B W^{(B)(0)}\)
      2. Gradient: \( \lambda \) = learning rate 
      CSLA의 gradient descent가 \( W^{(i+1)(A,B)} = W^{(i)(A,B)} - \lambda \frac{\partial L}{\partial W^{(i)(A,B)}}\)이면
      GR의 gradient descent는 \( W'^{(i+1)(A,B)} = W'^{(i)(A,B)} - \lambda (\alpha_A^2+\alpha_B^2) \frac{\partial L}{\partial W^{(i)(A,B)}}\)
  • 위 예시에서 초기 값과 gradient 값을 scaling 해줌으로써 2개의 branch를 1개의 branch인 것처럼 학습이 가능한 것을 보였다. 이 아이디어를 RepVGG에 적용하면 RepOptVGG가 된다
    • 1. RepVGG block에 있는 batch norm들을 제거 2. 3x3 conv, 1x1 conv, identity를 1개의 CSLA 블록으로 합친다 3. CSLA block 뒤에 batch norm 추가 (Figure 1의 (b)와 (c) 참고)
    • 위에서 사용한 예시에서는 \(\alpha_{A,B} \)라는 상수를 도입해서 \( \alpha_A^2 + \alpha_B^2\)라는 값을 gradient에 곱하면 된다는 것을 알아냈다. 비슷하게 RepOptVGG에서는 식 3에 있는 M이라는 값을 gradient에 곱하면 된다. 이렇게 하면 1x1, 3x3, identity branch 로 나뉘는 효과를 갖는다. 참고로 initialization도 3x3, 1x1, identity block structure을 갖도록 해줘야 한다, 뒤에 식 4 참고.

  • M에 등장하는 s,t factor들은 hyperparameter search를 통해서 얻는다
    • s,t를 학습 가능한 parameter로 바꿔서 작은 데이터셋에 학습을 한다 (CIFAR-100 사용)
    • 이렇게 얻은 값을 고정시키고 다른 학습 task에 그대로 사용
    • 참고로 W를 initialization할 때 s,t 값들을 다음과 같이 사용한다 (식 4 참고)

Quantization 관련

  • 그림 3을 보면 알겠지만 RepVGG 같은 경우 kernel weight의 variance가 높지만 RepOpt-VGG는 이런 문제가 없다. 3x3, 1x1, identity branch structure을 initialization & gradient reparametrization을 통해서 보존을 하지만 결국 1개의 branch처럼 학습을 하기 때문에 (특히 1개의 batch norm을 사용; RepVGG같은 경우 3개의 batch norm을 학습할 때 사용) 이런 문제가 없는 것으로 보인다. 자세한 discussion은 논문 appendix C 참고

728x90
728x90