深層学習モデルの量子化

:::note warn
この記事の情報は2020年時点で調べた内容をもとに書いています。
:::
# はじめに

近年、エッジデバイスに機械学習モデルを実装し、エッジデバイスで予測を行うエッジAIが注目を集めている。エッジAIを用いることで、エッジデバイスとクラウド間の通信が不要になるため、通信遅延や通信障害の影響をなくすことができ、通信コストの削減にもつながる。

また、クラウドにアップロードできない機密情報や個人情報などを扱うというシーンを考慮すると、エッジデバイスで処理したいというニーズはますます高くなると予測される。

しかし、エッジデバイスはクラウドなどのGPUサーバと比べて処理能力が低いため、深層学習モデルを動かすためのリソースには限界がある。一般に、深層学習モデルは層を増やすことで性能を向上させてきたが、層が増えるということはパラメータ数が増えることになり、メモリ使用量や計算コストが増加してしまう。モデルの精度と計算量はトレードオフの関係である。そのため、モデルの精度を保ったままメモリ使用量を削減し処理時間を高速化することがエッジAIにおいて非常に重要なポイントになる。

## モデル圧縮手法

深層学習モデルを軽量化する「モデル圧縮」手法には、
- 枝刈り (Pruning)
- 量子化 (Quantize)
- 蒸留 (Distillation)

の3種類がある。

ここでは主に量子化についてまとめるが、枝刈りと蒸留について簡単に触れておく。

### 枝刈り Pruning

![Model Quantization.033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491923/9e676ad5-7ea2-8ee4-a9e0-a0e46316b149.png)

Pruningとは、ノード間の重みが小さい箇所や影響の小さいノードを削除することでパラメータ数を削減する手法である。重みの絶対値が小さいものを削除する手法が一般的である。

### 蒸留 Distillation

![Model Quantization.034.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491923/a6803a7d-5b72-c6c4-fdb3-22597b71c1fc.png)


Distillationとは、大きいモデルやアンサンブルモデルを教師モデルとして、その知識を小さいモデル(生徒モデル)の学習に利用する手法である。蒸留では、教師モデルの学習に用いる正解ラベルをhard target、教師モデルの出力(のSoftmax値)をsoft targetと呼ぶ。生徒モデルを教師モデルに近づけるように学習するときに、soft targetを用いる。これにより、hard targetに含まれない情報を含めて学習できるというメリットもある。学習時の情報量を増やすという観点からモデルを軽量化する手法である。

蒸留はモデル圧縮以外にも、Data Distillationにも応用される。データ蒸留は、正解ラベルのないデータに対する教師モデルの予測結果を正解ラベルとして生徒モデルを訓練する手法である。

## 量子化 Quantize

![Model Quantization.035.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491923/d3e5af47-601e-2454-2bf7-f4cf7b5bad7a.png)


Quantizeとは、重みなどのパラメータをより小さいビットで表現することにより、モデルの軽量化を図る手法である。使用するビットを制限することでネットワークの構造を変えずにメモリ使用量を削減できる。

TensorFlowやPyTorchなどのフレームワークでは、32ビット浮動小数点精度(float32)が使用されている。K. Guoらの研究[^1]では、8ビットの量子化であれば1%程度の性能低下であることが報告されている。

[^1]: K. Guo et al. A Survey of FPGA-Based Neural Network Accelerator. https://arxiv.org/abs/1712.08934, 2017.

もとの浮動小数点$x$と量子化された値$q$の間の関係は2つの量子化パラメータ$\rm offset$と$\rm scale$を用いて次のような式になる。

$$
q={\rm offset} + {\rm round}\left(\frac{x}{{\rm scale}} \right)
$$

ここで、$\rm offset$は整数、$\rm scale$は実数(浮動小数点数)で、これらのパラメータを決定するために様々なアルゴリズムが用いられている。例えば、量子化したい値の最大値と最小値が量子化後の最大値と最小値に対応するように、オフセットとスケールを計算する方法が最も単純でよく用いられる。

![](https://s3.us-west-2.amazonaws.com/secure.notion-static.com/cde5942b-e13b-4429-87a3-dd11cea109f6/quantization_%281%29.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20201021%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201021T082438Z&X-Amz-Expires=86400&X-Amz-Signature=d720d70e2238ac305696483898be8d1846810f6fdf4d842b69aad3e6a948adab&X-Amz-SignedHeaders=host)

量子化を行うことのメリットは以下の2つである。
- 実行時のメモリ消費量、保存時のファイルサイズの削減
- 実行の高速化、省電力化

量子化を行うことのデメリットは、モデルの性能低下につながることである。浮動小数点数で表現されていた数値をより少ないビット数の整数で表現するため、丸めによる誤差が発生する。量子化によって生じる誤差は層の数の増加に伴って増えていくため、モデルの出力では大きな誤差となってモデルの性能低下につながる。

### 量子化の分類

#### Quantized Format

量子化したあとの整数のビット数と符号つきか符号なしかという側面で分類できる。一般的に用いられるのは8ビットの整数であり、符号の有無に関してはどちらも使われる場合がある。

#### Symmetric or Asymmetric

符号つき整数に量子化する際に、元の浮動小数点数の0を量子化後の整数の0に対応させる方法をsymmetric(対称)、そうでない方法をasymmetric(非対称)という。対称な量子化は上記の式で$\rm offset$が0であるような場合である。一般に量子化したい値の範囲は0を中心に対称に分布するとは限らないので、非対称な方が元の値をより正確に表現できることが好ましいが、計算コストの観点からオフセットが0で固定されていた方がいいのでどちらも用いられる。

#### Per-tensor or Per-channel (per-axis)

量子化は一般にテンソル(weights, bias, activation)ごとに行う。このテンソルごとに量子化パラメータ(offset, scale)を決める方法(per-tensor)に対して、テンソル内のチャネルごとにそれぞれ別の量子化パラメータを決める方法(per-channel, per-axis)がある。チャネルごとに量子化することによって保存すべきパラメータはチャネル数倍増えるが、より正確に元の値を表現することができるので、量子化誤差が少なくなる。

#### Static or Dynamic

何を量子化するかは以下の2種類がある。
- 重み(weights)
- 中間層(activation); 活性化関数の出力だけでなく、畳み込み層や全結合層の出力も全て量子化される

モデルの量子化する場合、重みについては常に推論前に量子化される。これによってメモリ消費量やファイルサイズを小さくすることができる。

一方で、中間層については、あらかじめ量子化パラメータを計算しておく方法(静的量子化)と、推論時に動的に量子化パラメータを求める方法(動的量子化)がある。

静的量子化の場合、全ての中間層についてあらかじめ量子化パラメータが求められるため、ほとんど全ての計算が整数演算で完結し、高速に推論できる。しかし、量子化パラメータが全ての入力に対して固定されているので量子化誤差が大きくなる可能性がある。また、事前に量子化パラメータを決定するためには、代表データ(representative data, callibration data)と呼ばれる、入力空間全体を代表するような入力データの集合を用意する必要がある。

動的量子化の場合、各層が内部的に量子化、計算、浮動小数点数への変換を行うような実装になるので、量子化に対応した層と対応していない層を混ぜて使うことができる。また、代表データは必要としないので、手軽に試すことができる。しかし、層ごとに量子化を繰り返し実行するので、実行時のオーバヘッドが大きくなる。

#### Post quantization or Quantization-aware training

上記の分類は、学習後に量子化を行うことを想定しているが、量子化に合わせて重みの値を学習する方法があり、これをQuantization-aware training (量子化を考慮した学習)と呼ぶ。それに対して、学習後に固定されたネットワークを量子化する方法をPost quantizationという。

Quantization-aware trainingでは、浮動小数点数で従来通りに学習を行ったあと、fine-tuningしてforward時に量子化した値を伝播させ、勾配伝播は元の浮動小数点数を使って行うようなモデルに変換して学習を行う(fake quantization)。



## 量子化に関する研究

- N. P. Jouppi et al. (Google, Inc.). In-Datacenter Performance Analysis of a Tensor Processing Unit. *arXiv preprint arXiv:1704.04760*, 2017.
- M. Rastegari, V. Ordonez, J. Redmon and A. Farhadi. XNOR-Net: ImageNet Classification Using Binary Convolutional Neural Networks. *arXiv preprint arXiv:1603.05279*, 2016.
- J. Choi, Z. Wang, S. Venkataramani. P. I. Chuang, V. Srinivasan and K. Gopalakrishnan. PACT: Parameterized Clipping Activation for Quantized Neural Networks. *arXiv preprint arXiv:1805.06085*, 2018.
- R. Banner, Y. Nahsha, E. Hoffer and D. Soudry. Post-training 4-bit quantization of convolution networks for rapid-deployment. *arXiv preprint arXiv:1810.05723*, 2018.
- S. Zhou, Y. Wu, Z. Ni, X. Zhou, H. Wen and Y. Zou. DoReFa-Net: Training Low Bitwidth Convolutional Neural Networks with Low Bitwidth Gradients, *arXiv preprint arXiv:1606.06160*, 2016.
- S. Wu, G. Li, F. Chen and L. Shi. Training and Inference with Integers in Deep Neural Networks. *arXiv preprint arXiv:1802.04680*, 2018.
- M. Courbraiaux, Y. Bengio and J.-P. David. BinaryConnect: Training Deep Neural Networks with binary weights during propagations. *arXiv preprint arXiv:1511.00363*, 2015.
- M. Courbariaux, I. Hubara, D. Soudry, R. E. Yaniv and Y. Bengio. Binarized Neural Networks: Training Deep Neural Networks with Weights and Activations Constrained to +1 or -1. *arXiv preprint arXiv:1602.02830*, 2016.
- I. Hubara, D. Soudry and R. E. Yaniv. Binarized Neural Networks. *arXiv preprint arXiv:1602.02505*, 2016.
- C. Zhu, S. Han, H. Mao and W. J. Dally. Trained Ternary Quantization. *arXiv preprint arXiv:1612.01064*, 2016.
- P. Yin, S. Zhang, Y. Qi and J. Xin. Quantization and Training of Low Bit-Width Convolutional Neural Networks for Object Detection. *arXiv preprint arXiv:1612.06052*, 2016.
- D. Miyashita, E. H. Lee and B. Murmann. Convolutional Neural Networks using Logarithmic Data Representation. *arXiv preprint arXiv:1603.01025*, 2016.
- I. Hubara, M. Courbariaux, D. Soudry, R. E. Yaniv and Y. Bengio. Quantized Neural Networks: Training Neural Networks with Low Precision Weights and Activations. *arXiv preprint arXiv:1609.07061*, 2016.
- K. Ullrich, E. Meeds and M. Welling. Soft Weight-Sharing for Neural Network Compression. *arXiv preprint arXiv:1702.04008*, 2017.
- A. Zhou, A. Yao, Y. Guo, L. Xu and Y. Chen. Incremental Network Quantization: Towards Lossless CNNs with Low-Precision Weights. *arXiv preprint arXiv:1702.03044*, 2017.


## 参考文献

- [ディープラーニングを軽量化する「モデル圧縮」3手法](https://laboro.ai/column/ディープラーニングを軽量化するモデル圧縮/)
- [深層学習ライブラリと量子化](https://lab.mo-t.com/blog/quantization-frameworks)
- [ニューラルネットワークの量子化についての最近の研究の進展と、その重要性](https://developer.smartnews.com/blog/2017/03/neural-network-quantization/)