モバイルに載せるなら、モデルのサイズは小さいほうがいいと思う。
量子化とは、重みパラメータを、例えばFloat_32からFloat_16にして早めの桁で切り上げるようにすること。
実際のモデルを量子化して、どれくらいサイズが小さくなるのか、精度はどう変わるのか、をやってみた。
deeplabv3のxeptionバックボーンバージョンでセマンティックセグメンテーションを比較(背景ぼかし)。
xeptionバックボーンのdeeplabv3のmlmodelのサイズは165.1MB。
MobileNetバックボーンだとModelが8.6MBなので、xeptionの方が精度はずっといいとはいえ、さすがにもうちょっと小さくしたいところ。
CoreMLModelの量子化の方法
from coremltools.models.neural_network import quantization_utils
# 可能な値はnbits = 16, 8, 7, 6, ...., 1
nbits = 16
quantized_model = quantization_utils.quantize_weights(model, nbits)
coremltools.utils.save_spec(quantized_model, 'quantizedDeepLab.mlmodel')
# Tips: 量子化したmlmodelは、なぜか.save(Path)メソッドが使えないので、coremltools.utils.save_specで保存します。
結果
モデル | サイズ(MB) | 速度(s) | 使用メモリ(MB) |
---|---|---|---|
Float32 | 165.1 | 315 | 477 |
Float16 | 82.6 | 2.72 | 477 |
Float8 | 41.8 | 2.77 | 477 |
モデルのサイズは見事に半分半分になった。
しかし、実行速度と使用メモリは変わらなかった。
さて、セグメンテーションの精度はというと・・・
左から【オリジナル】 【Float32】 【Float16】 【Float8】
165MB 82MB 41MB
おわかりいただけたであろうか?
32と16ではほぼ全くセグメント精度は変わらない。
「8だとさすがに雑になるでしょ」と思いきや、あにはからんや、これもほとんど変わらない。
よく見ると右下の花をぼかしが少し侵食しているが、これくらいなら十分32と同じように使える。
バンドルするモデルのサイズを小さくしたければ、量子化は有効な選択肢になると思う。
他のタスクでどう違ってくるのかは試してないけど。
*今回はLinearというデフォルトの量子化方法を使った。Coremltoolsの引数で別の種類も選択できるらしい。
🐣
お仕事のご相談こちらまで
rockyshikoku@gmail.com
Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。