ニューラルネットのメモリ消費を小さくする類の手法

ちょっと前に論文読んだので備忘録としてメモしておく.

前置き

  • 本格的なニューラルネットはパラメータ数が多いのでモデルサイズが大きくなってしまうことが多い
  • このようなモデルでも普通のマシンで動かす場合には(GPUのメモリを使い切らない限り)問題にならないことも多いが,モバイル端末などメモリ容量が制限されたハードウェア上で動かしたい場合には問題になる.
  • これをなんとかする論文をいくつか読んだ.

Deep Learning with Limited Numerical Precision (ICML2015)

  • 普通はNNのパラメータは32bit浮動小数点数で保持されているが,小数の精度を落とす(たとえば16bitとか8bitとかにする)ことでメモリ消費を単純に1/2とか1/4にできる.
  • 16ビット幅の固定小数を使ってNNを学習のフェーズから行う.
  • 小数を丸めるときに,単に一番近い値に丸めるのではなく,切り上げか切り下げかをその値によって確率的に選ぶと良い感じになる,と主張している.
    • 更新のときに小さい値が何度も足されるふうになる時に,一番近い値に丸めるのだと全く更新されないけど,確率的にやるとたまにちゃんと更新されて良い感じになるというイメージ.
    • この丸め方の違いで学習性能が大きく変わることが実験結果から示されている.
  • 後半に,それ用のハードウェアをFPGAで構成する話も載っている(未読)
  • 感想
    • 確率的に丸めることでまともになるというのは結構妥当な感じがするしNN以外の手法でも使えそうな気がする.ある良い感じの条件下(たとえば目的関数が凸とか)だったら高確率で高精度小数で計算した時から結果がずれないみたいなことは言えても不思議じゃない気もする.ちゃんと考えたわけじゃないので雑な意見だけど….
    • 小さいモデルでしか実験してないけど最近の10層以上のネットワークでも同じような結果は得られるか気になった.
    • しかしメモリが制限された環境で学習したい状況というのがどんな状況なのかあまりイメージが沸かなかった.学習自体は富豪環境でやってテストだけ貧民環境でやりたいことのほうが多いんではないか.
      • GPUのメモリに入りきらないくらいでかいモデルを訓練したい時には良いのかもしれない?

Fixed Point Quantization of Deep Convolutional Networks (ICLR2015 under review)

  • レビュー中だけど引用されていたので読んだ.
  • これも,精度を落とした固定小数点数でNNを学習のフェーズから行う.
  • この論文では,NN全体で同じビット幅の固定小数を使うのではなく,レイヤーによって幅を変えるともっと消費メモリを抑えられるということを主張している.
  • 適切なビット幅を求めるために,SQNR(signal-to-quantization-noise ratio)という量を考える.
    • SQNR については知らなかったが,量子化した際に元の値からの誤差がどれくらい大きくなるかの期待値(の対数)を表す(という理解でいいんかな…)
    • 量子化幅を求めるには,量子化したい値がある分布に従っていると仮定して,SQNRが最小になるような幅を求めることにする.
    • 分布が正規分布だとどれくらいにすればいいかというのが大体知られている.実際のCNNに渡される入力を見ると,おおむねどのレイヤーの重みの分布もactivation valueも正規分布っぽいかんじになっていると分かるので,そう仮定する.
    • CNNでのSQNR(の逆数)は各層でのSQNR(の逆数)の和になる.これを最小化しようとすると閉じた式が得られる.
  • 提案手法によると,入力に近い層ほど高い精度の小数を使うべきで,出力に近い層ほど精度を落としても良いということになるらしい
  • Fine-tuning は重要
    • CIFAR10のCNNを使った手法のベースラインの精度は7%程度だが,実験を見るとFine-tuningすると全層4ビットでも1~2%程度悪くなるだけで済むらしい.Fine-tuningしないとひどくなる.
    • …と書かれているのだけど細部があんまり書かれていないような.普通に勾配法実行するのだとして丸め方はどうするのかとか.
  • 感想
    • 単にモデルの容量削減という目的で性能だけ見るとそんなに良くなってないけど,
    • 下のレイヤーのほうが上のレイヤーより小数精度が高くないといけないというのは,特徴量の最低限必要な量子化粒度がレイヤーによって違うということを示唆していて面白いかもしれない.

Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding(ICLR2015 under review)

  • これもレビュー中だけど紹介されたので読んだ
  • 小数の精度を落とす以外にも色々工夫して最近のモデルを50倍くらい圧縮する.工夫としては3つくらいある.
    • その1.値が小さい重みを0につぶして,畳込みの重み行列を疎行列として扱う.(図2)
      • これだけでもだいぶ効き目がある.(10倍くらい圧縮される)
      • ただ,閾値をいくらにするかはどこにも書いてなくて謎だけど適当でいいのか…
    • その2.非零の重みを量子化して何種類かにして,重みをHashedNetsみたいに共有させる.そこからさらに再学習も行う.
      • HashedNetsはハッシュによって重みを共有する要素を決めていたが,この手法は学習済みのモデルからどの要素を共有させるかを重みのクラスタリングによって決めている.
    • その3.重みの分布と,疎行列で表す際のlocation indexの分布は偏っているのでハフマン符号化して表すとよりメモリ消費を抑えられる.
  • 感想
    • オーソドックスな圧縮手法を一通り使ったら良くなったという話っぽい.
    • 実験を大きいモデルでちゃんとやってて性能もかなり出てるので実用的そう.