ジョイジョイジョイ

ジョイジョイジョイジョイジョイ

HashedNets

HashedNets [1] を chainer で実装しました。

HashedNets の説明

ニューラルネットワークのパラメータ数は非常に多く、パラメータは冗長な表現になっていることが多いです。

そこで、自由なパラメータの数を減らして、正則化と軽量化を達成するための手法の一つとして HashedNets が考案されました。

HashedNets では、ハッシュ関数を使って、同じハッシュ値となる辺どうしを重み共有します。

具体的にはまず層ごとに自由なパラメータの数  K を決めて  K 次元のパラメータ  w を用意します。

次に、ネットワークの辺から  \{ 1,..\ K \} へのハッシュ関数  h \{ -1, 1 \} へのハッシュ関数  \xi を定めます。

順伝播させるときには、辺  i の重みは  \xi(i) \cdot w_{h(i)} として計算します。

重み共有する辺の決定にハッシュ関数を使うことで、ランダムに割り付けができ、対応関係の情報を陽に持つ必要が無いので容量の削減が実現できます。

実装

Python 3.5.3 + chainer 2.0.1 で実装しました。

gist.github.com

簡単のため  \xi は実装していません。

 \xi があれば同じパラメータ数でももう少し表現力が上がったかもしれません。

逆伝播の計算では numpy.bincound を使うと便利でした。

実験

 K の値を変えて MNIST の分類を 3 層の全結合ニューラルネットワーク行いました。

元のニューラルネットワークにおいてはパラメータ数はそれぞれ  78400 \sim 2^{16.26}, 10000 \sim 2^{13.29}, 1000 \sim 2^{9.97} です。

f:id:joisino:20170724190837p:plain

このときの  K = 2^{10} 程度あれば正解率 0.95 くらいまで出ています。

容量の圧縮率はパラメータの数だけ見る単純計算で  (78400+10000+1000) / (1024 \cdot 3) \sim 29.10 倍くらいです。

最後に

何か間違いや質問などがあればお願いします。

最後まで読んでいただきありがとうございました。

参考文献

[1] W. Chen. et al. (2015) Compressing Neural Networks with the Hashing Trick