スパースモデルを取得するために、Kerasのニューラルネットワークパラメーターにkeras.regularizers.l1(0.01)
を使用してL1正則化を採用しています。私の係数の多くはcloseゼロに近いものの、実際にはゼロになっているものはほとんどないことがわかりました。
正則化のソースコード を見ると、Kerasが単にパラメーターのL1ノルムを損失関数に追加していることがわかります。
L1正則化で意図されているように、パラメーターが(浮動小数点エラー内で)ゼロになることはほとんどないため、これは正しくありません。パラメータがゼロの場合、L1ノルムは微分可能ではないため、最適化ルーチンでパラメータがゼロに十分近い場合はパラメータがゼロに設定される劣勾配法を使用する必要があります。ソフトしきい値演算子max(0, ..)
ここ を参照してください。
Tensorflow/Kerasはこれを行いますか、それとも確率的勾配降下法を行うのは非現実的ですか?
編集:また ここ は、L1正則化のソフトしきい値演算子を説明するすばらしいブログ投稿です。
したがって、@ Joshuaの回答にもかかわらず、言及する価値のある他の3つのことがあります。
0
のグラデーションに関連する問題はありません。 keras
は、relu
の場合と同様に、自動的に1
に設定します。1e-6
未満の値は、実際には0
と等しいことに注意してください。これは、float32
の精度です。ほとんどの値が0
に設定されていないという問題は、勾配降下ベースのアルゴリズムの性質による計算上の理由(および高いl1
値の設定)が原因で発生する可能性があります。勾配の不連続性が原因で発生します。与えられた重みw = 0.005
に対して学習率が0.01
に等しく、主損失の勾配が0
w.r.tに等しいことを理解するために。 w
へ。したがって、体重は次のように更新されます。
w = 0.005 - 1 * 0.01 = -0.05 (because gradient is equal to 1 as w > 0),
2回目の更新後:
w = -0.005 + 1 * 0.01 = 0.05 (because gradient is equal to -1 as w < 0).
ご覧のとおり、l1
正則化を適用しても、w
の絶対値は減少していません。これは、勾配ベースのアルゴリズムの性質が原因で発生しました。もちろん、これは単純化された状況ですが、l1
ノルム正則化を使用すると、このような振動動作が頻繁に発生する可能性があります。
KerasはL1正則化を正しく実装しています。ニューラルネットワークのコンテキストでは、L1正則化は、パラメーターのL1ノルムを損失関数に追加するだけです( CS231 を参照)。
L1正則化はスパース性を促進しますが、出力がスパースになることを保証するものではありません。確率的勾配降下法によるパラメーターの更新は、本質的にノイズが多くなります。したがって、任意のパラメータが正確に0である確率はほとんどありません。
ただし、L1正則化ネットワークのパラメーターの多くは0に近いことがよくあります。基本的なアプローチは、小さな値を0にしきい値設定することです。スパースニューラルネットワークを生成するより高度な方法を調査する研究があります。 この論文 では、著者はニューラルネットワークのプルーニングとトレーニングを同時に行い、多くのよく知られたネットワークアーキテクチャで90〜95%のスパース性を実現しています。
TL; DR:ディープラーニングフレームワークの定式化は正しいですが、現在、SGDまたはそのバリアントで正確に解決するための強力なソルバー/オプティマイザーはありません。ただし、近位オプティマイザーを使用すると、スパースソリューションを取得できます。
あなたの観察は正しいです。
劣勾配降下は、目的全体の劣勾配を見るだけで問題の構造を完全に無視するため(最小二乗適合と正則化項を区別しないため)、ラッソ目的などの滑らかでない関数の収束特性が非常に低くなります。 。直感的には、(劣)勾配の方向に小さなステップを踏むと、通常、座標が正確にゼロに等しくなることはありません。
tf.train.ProximalAdagradOptimizer
)はまばらな解決策につながる可能性がありますが、試してみることができます。もう1つの簡単な回避策は、トレーニング後または各勾配降下ステップの後にスパース性を強制するために、小さな重み(つまり、絶対値<1e-4)をゼロにすることです。これは便利なヒューリスティックアプローチであり、理論的に厳密ではありません。
KerasはL1正則化を適切に実装していますが、これはLASSOではありません。 LASSOの場合、元の投稿で正しく指摘されているように、ソフトしきい値機能が必要になります。 keras.layers.ThresholdedReLU(theta = 1.0)と同様の関数で非常に便利ですが、f(x) = x for x> thetaまたはf(x) = x for x <-theta、f(x) = 0それ以外の場合。LASSOの場合、シータは学習率に正則化係数を掛けたものに等しくなります。 L1関数。