이 글은 다음 영상을 참조합니다.

https://www.youtube.com/watch?v=4iq-d2AmfRU&list=PLQY2H8rRoyvzIuB8rZXs7pfyjiSUs8Vza&index=2


Quantization이 무엇인가?

Quantization은 모델이 표현하는 바를 일부 제한시켜서 모델의 파라미터를 감소시키는 방법이다. 이 방법은 모델의 크기를 감소시켜서 프로그램을 빠르게하고, 파워 소비를 감소시킵니다. 또 마지막으로 메모리 요구를 감소시켜 하드웨어 측면에서도 이점을 취할 수 있습니다.

왜 어려운가?

장점이 많은만큼, 어렵다.
(1) 이 방법을 표현하기 어렵다. 표준이 없다는 이야기이다.
(2) 완전한 적용을 위한 메타 데이터가 충분하지 않다.
(3) 신경망의 고질적인 문제인 것처럼, 결과를 해석할 수 없다. 그래서 이 방법은 효과적이지만 정교하게 해석할 수 없기에 이를 목표로 잡고있다고 언급한다.

어떻게 사용하는가?

가장 쉬운 방법은 프로그램이 활용하는 수의 범위에서 min-max를 결정해서 clipping하는 것이다. 이 방법은 효과적일 수 있지만, 어떤 모델에서는 유용하고, 또 어떤 모델에서는 유용하지 않을 수 있기 때문에 주의해야 한다. 

이 방법은 주로 전처리 과정이나 또는 경우에 따라 사후 처리에서 사용해서 값의 범위를 제한시키고 모델에 입력시켰는데, 최근에는 모델의 학습 과정(예를 들면 backward)에서 사용한다.

학습 과정에서 사용하면 더욱 잘 adjust할 수 있지만, 재사용, 유지보수 불가, unstable, 다루기 어려움과 같은 주의점이 존재한다.

Neural connection pruning

우리가 흔히 하는 Model pruning과 동일한 이름인 것 같다. 이 방법은 신경망의 개별 connection을 끊어주는 것을 의미한다. 예를 들면, dense한 tensor에서 sparse한 tensor로 만들어주는 것이다.
sparse한 tensor가 되기 위해서는 기존의 값을 0으로 채워넣으면 되겠죠?

그래서 TensorFlow는 이를 위해 어떤 tool을 제공하는가?

텐서플로우는 2019년에 이를 위한 Model Optimization Toolkit을 배포했다.
(Quantization, Sparsity를 수행해서 이미지가 어떻게 변화하는지는 영상의 [15:14]에서 볼 수 있다.)

https://github.com/tensorflow/model-optimization

텐서플로우에서는 세 가지의 Quantization 방법을 제공한다.
- TensorFlow Lite용
- 학습 과정 중에 사용할 수 있는 방법
- 사후 처리 과정 중에 사용할 수 있는 방법

먼저 quantization 방법은 bit로 표현할 수 있는 범위를 제한시키는 것이 대표적인데,
텐서플로우는 float형태--> float + int 형태 --> only 8-bit int 형태의 quantization 방법을 제공한다.
(자세한 설명은 동영상을 참고하세요)

중요한 것은 keras API를 활용해서 쉽게 적용가능하다.

import tensorflow_model_optimization as tfmot

model = MyModel()

model_to_quantize = tfmot.quantization.keras.quantize(model)

model_for_pruning.fit()

왜 마지막 모델의 이름이 model_for_pruning 인지는 뒤에서 알 수 있다.

 

TF Lite에서도 매우 쉽게 활용할 수 있는 것을 보면, 감탄사가 나온다. 
convert하는 과정에서 converter의 옵션을 다음과 같이 설정하기만 하면 된다.

converter.optimizations = [tf.lite.Optimize.DEFAULT]

동영상에서는 CPU를 통해 얼마만큼의 속도 향상이 이루어졌는지 결과를 보여준다(무려 4배, RNN 계열은 3배).
보통 속도와 성능은 trade-off 관계인 것을 알고 있을 것이다. 동영상에서는 이에 대한 실험결과도 보여주는데 기본 baseline과 quantization을 수행한 결과 차이가 거의 업다!

케라스를 활용하여 사용하는 과정은 다음과 같다.

  1. 케라스 모델을 구성한다.
  2. 텐서플로우에서 제공하는 optimization API를 활용해서 pruning을 적용한다.
  3. 학습한다.
  4. 모델은 sparse한 tensor 보유를 통해 크기가 감소할 것이다.

적용 과정을 더욱 구체적으로 살펴보자면,

import tensorflow_model_optimization as tfmot

model = MyModel()

pruning_schedule = tfmot.sparsity.keras.PolynomialDecay(
				inital_sparsity = 0.0, final_sparsity = 0.5,
                begin_step = 2000, end_step = 4000)
                
model_for_pruning = tfmot.sparsity.keras.prune_low_magnitude(model,
								pruning_schedule=pruning_schedule)

여기서 final_sparsity 인자값을 강조하고 있다. 이 인자를 통해 각 layer에서 weight를 얼마나 감소시킬 것인지를 결정할 수 있는데, 여기서는 0.5이므로 50%를 선택한 것이다.
인자값의 선택은 0.5 ~ 0.8 즉, 50% ~ 80% 정도가 가장 효율적이라고 실험을 통해 설명한다.