びぼーろぐ

備忘録としての勉強のログです。淡々と学んだことをログって行くので、雑な記事が多いです。

BinaryConnet: Training Deep Neural Networks with binary weights during propagations

arxiv.org
2015
BinaryConnectの筆者らの実装 github.com

ベロンベロンで書いているので日本語になってないかも

一言でいうと

学習の順伝搬及び逆伝搬で重みを2値化(-1, 1)して、精度を維持しながらDNNの容量及び計算を少なくする。このBinaryConnectは正則化として振る舞い、(2015年当時の)SOTAレベルの結果を維持することができる。

2値化でも機能する理由:

  • ノイジーな重みでも互換性SGDに互換性がある。ランダムまたは確率的な丸めが偏りのない離散化をするのに使われる。
  • ノイジーな重みは正則化として汎化性能を高める。

結果

  • 2/3の演算が除去できた
  • 学習時間が3倍短くなった。
  • 16倍以上の必要メモリ量を削減(16bitの浮動少数から単ビット精度)

精度も維持

f:id:taku-buntu:20190117032019p:plain
エラー率

手法

+1 or -1

重みは-1か+1にする。 こうすることで、行列演算は単なる加算か減算になる。 固定ポイントアダーとして固定ポイント積算アキュムレータよりもエネルギーと面積が少ない。

決定論的2値化 vs 確率的2値化

決定論的:  w _ { b } = \left{ \begin{array} { l l } { + 1 } & { \text { if } w \geq 0 } \ { - 1 } & { \text { otherwise } } \end{array} \right.

確率的:  w _ { b } = \left{ \begin{array} { l l } { + 1 } & { \text { with probability } p = \sigma ( w ) } \ { - 1 } & { \text { with probability } 1 - p } \end{array} \right.
 \sigmaはハードシグモイド関数
 \sigma ( x ) = \operatorname { clip } \left( \frac { x + 1 } { 2 } , 0,1 \right) = \max \left( 0 , \min \left( 1 , \frac { x + 1 } { 2 } \right) \right)

決定論的にも2値化可能だが、中間層の複数の入力重みに渡って離散化したものを平均化したものを利用したほうが情報損失が少ない。

プロパゲーション vs アップデート

  1. まず順伝搬
  2. 次に逆伝搬。それぞれの層のアクティベーションに対する、ターゲットの勾配を計算。出力層側の求めて~入力層一歩手前の中間層へ。
  3. パラ更新。各層の重みパラの勾配を求める。勾配と過去の重みを使って更新。

↑を踏まえたBinaryConnectのパラ更新が以下

f:id:taku-buntu:20190117024643p:plain
BinaryConnectのSGD学習。

順伝搬、逆伝搬中に重みだけしか2値化しない。(step1, 2) SGDをうまくやるには重みパラの精度がある程度無いといけない。 勾配降下法で得られるパラ変化はごく小さな値。 値の更新(step 3)自体はそのまま実数重みで行っていることに注意。 クリッピングは、[-1, 1]で行う。

何度もちっちゃな更新させて、最終的には以下のパラメータ w ^ { * }を採用する。
 w ^ { * } = \operatorname { sign } \left( \sum _ { t } g _ { t } \right)  g _ { t }はノイジー推定器

ランダムに離散化することで精度を保ちながら異なる重みの離散化誤差を互いに相殺することができる。