HeNormalとは
重み係数の初期化手法の1つで、別名"MSRA"とも呼ばれます。Kaiming Heらの論文で使われており、論文著者とMicrosoft Researchが名前の由来になっていると思われます。
HeNormalでは重み係数$W$を標準偏差$\sqrt{2/N}$の正規分布に従う乱数で初期化します。ここで$N$は入力の大きさで、links.Linear
の場合は入力ベクトルのサイズ、links.Convolution2D
の場合はチャンネル数×カーネル高さ×カーネル幅になります。
wscale指定ではだめなのか?
HeNormalで初期化する方法として、linkのインスタンス生成時にwscale
にmath.sqrt(2)
が指定されることがあります。
例えばchainer.links.Linear(100, 100, wscale=math.sqrt(2))
のような指定を行います。
ChainerのImageNetサンプルにあるNetwork-in-Networkモデルでもこの方法が使われています。
しかしながらwscale
の動作がv1.9.0から意図せず変わっていることがわかりました。
すでにissue登録もしています。
wscale doesn't have backward compatibility
明示的にHeNormalを使いたい場合にはこの問題が解決されるまでwscale
による指定は避けたほうがよいでしょう。
例えばChainer実装を使った結果を公開する際に「HeNormalで初期化した」と述べたり、他のチームの研究でHeNormalを使っていてその再現をするために初期化方法を揃えたいといった場合には、以下に述べるようにWeight Initializerを使うのがよいと思います。
Weight Initializerの使い方
ChainerではWeight Initializerを使うことで重み係数の初期化方法を指定できます。
Initializerを使って初期化するにはlinkのinitialW
にinitializerのインスタンスを指定すればよいです。
例:
class MLP(chainer.Chain):
def __init__(self, n_in, n_units, n_out):
initializer = chainer.initializers.HeNormal()
super(MLP, self).__init__(
l1=L.Linear(None, n_units, initialW=initializer), # n_in -> n_units
l2=L.Linear(None, n_units, initialW=initializer), # n_units -> n_units
l3=L.Linear(None, n_out, initialW=initializer), # n_units -> n_out
)
...
参考文献
- Kaiming He el al. Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification, (2015)