数年前、Kerasを初めて触ったとき、重みの初期化をしようと、APIドキュメントで「weight」を探しても見つからなくて、少し戸惑ったことがありました。その後、Kerasでは「重み」は「kernel」と表現されている箇所があることに気付いたわけですが、初心者には分かりにくいですよね。同じように混乱する人のために、このブログ記事を(手早く=手抜きで)書いて情報共有することにしました。
まずKeras(やTensorFlow 2.x)で重みの初期化を行うには、Dense
レイヤーのコンストラクター(厳密には__init__()
メソッド)の引数kernel_initializer
を使います。他にも「kernel」と命名された引数には、正則化を行うための引数kernel_regularizer
や、重み行列に制約を課すための引数kernel_constraint
などがあります。
なんで「weights」ではなく「kernel」? 実用上は問題ないので放置してそのまま使っていましたが、ずっとこの謎が気にかかっていました。最近、情報をあさっていて、Keras作者が直接言及しているGitHub Issues:
を発見したので、その内容を紹介します(※本文通りではない超訳です)。
- 質問者:
Dense
レイヤーのパラメーターにkernel_initializer
、kernel_regularizer
、kernel_constraint
、と「kernel(カーネル)」という名前が付けられていますが、「重み」ですよね。分かりにくいです。 - 質問者: これってCNNの畳み込み(
Conv
)レイヤーとの整合性のために名付けられたのですか?( → 返答内容から見て基本的に「Yes」) - Keras作者: レイヤーの「重み」には、特徴(行列)とバイアス(ベクトル)の両方が含まれます。
- Keras作者: カーネルとバイアスを区別する正確な方法が(レイヤー全種で共通化するために)必要でした。
- Keras作者: そこで「カーネル/バイアス」という名称を採用しました。
- Keras作者:
Dense
レイヤーは、「入力サイズ」のウィンドウを持つConv
レイヤーの特殊なケースと見ることができます。つまりいずれも「カーネル」を参照するということです。 - Keras作者: この表記法は、KerasとTensorFlow全体で使用されているため、ディープラーニングコミュニティの大多数が認識しています。つまり「カーネル/バイアス」はデファクトスタンダードなんですよ。
- 質問者: なるほど~。でも研究論文では「カーネル」と書いているのは見たことないです。私の中では、重みの中にバイアスは含まれていないです。「カーネル」は言い過ぎなので、この命名には反対ですね。
個人的にはすっきりしました。「重み」の初期化って言いつつ「kernel」とコードに記述するのは一致しなくて違和感あるので、「weights」って単語も入れてほしかったですが。
重みの中にバイアスが含まれるのって、重み行列を書くときに、バイアスを$w_0$と書いてその重みテンソルの中に含めるからですよね(たぶん)。でも概念的には重みとバイアスって、(直線で言うと)傾きと切片なんだから別物な気がします。
個人的には質問者に賛成なんだけど、ライブラリ制作者サイドとしては、引数などの「共通化」や「整理された美しさ」などの考えが入って、こういう結果になっているんだろうなと、今のところ納得しています。