コンテンツにスキップ

正則化

キーワード:L1正則化、スパース表現、L2正則化、weight decay、ドロップアウト、ドロップコネクト、早期終了、バッチサイズ、学習率の調整

要点

  • 正則化は、訓練データへの当てはまりを多少犠牲にして、未知のデータへの性能(汎化性能)を上げる工夫の総称。過学習(訓練誤差だけが下がり、検証誤差が上がる)を抑える。
  • 損失に重みの大きさのペナルティを足す:L2(weight decay)は重みを小さく保ち、L1 は重みを 0 にして(スパース)特徴を選ぶ。
  • ネットワークをランダムに欠けさせるドロップアウト(推論時は \(q\) 倍で補正)、検証誤差で学習を止める早期終了、バッチサイズ・学習率の選び方(陰的な正則化)もある。

過学習と正則化の種類

学習が進むと、訓練誤差は下がり続けるが、検証誤差はやがて上がり始める。この開きが過学習で、パラメータが多く、データが少ないほど起きやすい。

種類 方法 効き方
明示的:ペナルティ L2(weight decay)、L1 重みの大きさを損失に入れて制約する
明示的:確率的 ドロップアウト、ドロップコネクト 学習中にランダムに欠けさせ、特定のノードへの依存を防ぐ
明示的:データ・ラベル データ拡張、ラベル平滑化、ノイズ付加 見かけのデータを増やす・目標をなだらかにする
明示的:構造 重み共有(CNN・RNN)、ボトルネック パラメータの自由度を減らす
陰的 早期終了、バッチサイズ、学習率、正規化層 学習の進め方が、結果として解を制約する
アンサンブル バギング等 複数モデルの平均でばらつきを減らす

パラメータノルムペナルティ

損失 \(L\) に、重みの大きさ \(\Omega(\mathbf{W})\) を足した \(L_{\mathrm{total}}\) を最小化する。\(\lambda>0\) は罰則の強さを決めるハイパーパラメータ。

\[ \begin{aligned} &\text{L2} && L_{\mathrm{total}}=L+\frac{\lambda}{2}\|\mathbf{W}\|_2^2,\qquad \frac{\partial L_{\mathrm{total}}}{\partial\mathbf{W}}=\frac{\partial L}{\partial\mathbf{W}}+\lambda\mathbf{W} \\[3mm] &\text{L1} && L_{\mathrm{total}}=L+\lambda\|\mathbf{W}\|_1,\qquad \frac{\partial L_{\mathrm{total}}}{\partial\mathbf{W}}=\frac{\partial L}{\partial\mathbf{W}}+\lambda\,\mathrm{sign}(\mathbf{W}) \end{aligned} \]
  • \(\|\mathbf{W}\|_2^2=\sum_{i,j}W_{ij}^2\)(全要素の二乗和)、\(\|\mathbf{W}\|_1=\sum_{i,j}|W_{ij}|\)。全層の重みをまとめて足す。
  • L1 は 0 で微分できない。\(W=0\) では \([-1,1]\) の中の値(劣勾配)を使う。
  • バイアスには課さないのが普通。バイアスは大きくなっても過学習に結びつきにくく、罰を課すと表現力を落とす。層ごとに別の \(\lambda\) を使ってもよい。
  • \(\lambda\) が大きすぎると、重みが小さくなりすぎて過少適合になる。

weight decay(重み減衰)

L2 の勾配を SGD の更新に入れると、

\[ \mathbf{W}\leftarrow\mathbf{W}-\eta\left(\frac{\partial L}{\partial\mathbf{W}}+\lambda\mathbf{W}\right)=(1-\eta\lambda)\,\mathbf{W}-\eta\,\frac{\partial L}{\partial\mathbf{W}} \]
  • 毎ステップ、重みが \((1-\eta\lambda)\) 倍に減衰してから勾配で動く。これが weight decay の名前の由来。
  • 実装は、損失に \(\frac{\lambda}{2}\sum W^2\) を足す(損失の値に反映)ことと、勾配に \(\lambda\mathbf{W}\) を足すこと(更新に反映)の2か所。
  • SGD では L2 正則化と weight decay は同じ。Adam のような適応的な手法では同じにならないため、分離する AdamW を使う(最適化)。

L1 と L2 の違い

L2 L1
ペナルティ \(\frac\lambda2\sum w^2\) \(\lambda\sum\lvert w\rvert\)
重みが小さいときの縮める力 \(\lambda w\)(小さくなると弱まる) \(\lambda\)(一定)
結果 全体が小さくなるが、0 にはなりにくい(なめらかな縮小) 多くの重みがちょうど 0(スパース、特徴選択)
事前分布(MAP 推定) ガウス分布 ラプラス分布
等高線 円 ひし形(角が軸の上)
  • 損失の曲がりが \(h_i\) の単純な場合(\(L=\frac12\sum h_i(w_i-w_i^*)^2\))、解は L2:\(w_i=\dfrac{h_i}{h_i+\lambda}w_i^*\)(比例して縮む)、L1:\(w_i=\mathrm{sign}(w_i^*)\max\bigl(0,\,|w_i^*|-\lambda/h_i\bigr)\)(一定量を引き、負になったら 0。ソフトしきい値処理)。
  • 損失の等高線が最初に触れる点が解になる。L1 のひし形は角が軸の上にあるので、そこで接しやすく、片方の成分が 0 になる。
  • L1 と L2 を混ぜたものが Elastic Net(線形回帰・正則化)。

動かしてみる

  • L1 に切り替えて \(\lambda\) を 0 から上げると、まず \(w_2\) が 0 になり(軸にぶつかる)、解がひし形の角に張り付きます。曲がりの小さい成分(\(h_2=1\))のほうが先に 0 になります。
  • L2 のまま \(\lambda\) を大きくしても、\(w_1,w_2\) は 0 に近づくだけで、ちょうど 0 にはなりません。点線の軌跡も原点に向かってなめらかに曲がります。
  • \(w_1^*,w_2^*\) を動かすと、データ損失の最小点が変わります。L1 では、\(|w_2^*|\le\lambda/h_2\) の間は \(w_2\) が 0 のままです。

スパース表現

高次元のベクトルや行列の多くの成分を 0 にして、表現を軽く・解釈しやすくすること。

  • 重みのスパース化:L1 正則化。使わない入力への結合が消える。
  • 表現(層の出力)のスパース化:ReLU は負の入力を 0 にするので、自然にスパースな出力になる。出力に対してノルムペナルティを課す方法もある。

重み共有

位置ごとに別々のパラメータを持たず、1つのパラメータを共有する(畳み込み層のカーネル、RNN の時間方向)。パラメータ数が減る反面、自由度が制限されるので、構造による正則化ともみなせる。


確率的削除

ドロップアウト

学習中、各ノードの出力を確率 \(p\) で 0 にする(ドロップ)。毎回違う部分ネットワークで学習することになり、ノード同士が互いに頼り合う共適応を防ぐ。

\[ \begin{aligned} &\text{マスク} && r_j\sim\mathrm{Bernoulli}(q),\qquad q=1-p\ \text{(残す確率)} \\[2mm] &\text{学習時} && \tilde{y}_j=r_j\,y_j,\qquad u_i^{(l+1)}=\sum_j W_{ij}\,\tilde y_j+b_i \\[2mm] &\text{推論時} && \text{ドロップせず、重みを } q \text{ 倍する:}\ \mathbf{W}_{\mathrm{test}}=q\,\mathbf{W} \\[2mm] &\text{逆伝播} && \frac{\partial L}{\partial y_j}=r_j\,\frac{\partial L}{\partial\tilde y_j}\qquad\text{(残したノードだけ勾配を通す)} \end{aligned} \]
  • 推論時に \(q\) を掛けるのは、学習時の出力の期待値 \(\mathbb{E}[r_jy_j]=q\,y_j\) に合わせるため。掛けないと、全ノードがそろうぶん出力が \(1/q\) 倍に大きくなる。
  • 実装では、学習時に \(r_j y_j/q\) としておく inverted dropout がふつう。推論時は何もしなくてよい(その場合、逆伝播は \(r_j/q\) を掛ける)。
  • 記号に注意:原論文は残す確率を \(p\) と書く。ここではドロップする確率を \(p\)、残す確率を \(q\) とした。PyTorch の Dropout(p=0.5) の \(p\) はドロップする確率。
  • 共適応が防がれ、\(2^n\) 通りの部分ネットワーク(重みを共有)を平均したアンサンブルのように働く。推論時の \(q\) 倍は、その平均の近似。
  • 基準の値は、隠れ層で \(p=0.5\)、入力層で \(p=0.2\) くらい。出力層には入れない。
  • CNN の畳み込み層では、隣り合う画素が似ているので、1つ落としても周りから補われて効果が小さい。ドロップアウトは主に全結合層に入れる(畳み込み向けには、領域ごと落とす DropBlock などがある)。
  • バッチ正規化と併用すると、学習時と推論時で分散がずれて性能が落ちることがある。

動かしてみる

  • 「マスクを引き直す」を押すたびに、落とされるユニットと出力 \(u\) が変わります。\(u\) は 2000 回のマスクで広くばらつきます(これが学習時のノイズ)。
  • 灰の点線(2000 回の平均)は、いつも紺の縦線(推論時の \(q\sum_j w_jy_j\))とほぼ重なります。推論時に \(q\) を掛けると、学習時の平均と一致することが分かります。
  • \(p\) を 0.9 に上げると、残るユニットが少なく、出力のばらつきも大きくなります。\(p=0\) では \(u\) は常に同じ値で、ばらつきはありません。

ドロップコネクト

ノードではなく、重み(結合)をランダムに 0 にする。ドロップアウトの一般化にあたる。

\[ \mathbf{y}=f\bigl((\mathbf{M}\odot\mathbf{W})\,\mathbf{x}+\mathbf{b}\bigr),\qquad M_{ij}\sim\mathrm{Bernoulli}(q) \]
  • ドロップアウトは「行(出力ノード)または列(入力ノード)まるごと」を落とすのに対し、ドロップコネクトは要素ごとに落とす。より細かい確率的削除。
  • 推論時は、近似としてドロップアウトと同様に \(q\) 倍にするほか、多数のマスクの出力を平均する方法がある。
  • 同様の発想に、ブロックごと層ごと落とすもの(DropBlock、Stochastic Depth)がある。

陰的正則化

損失に項を足さなくても、学習の進め方が解に制約をかけて汎化を良くすることがある。

早期終了

検証誤差が最小になった時点(訓練誤差が小さくなった時点ではない)で学習を止め、その時点のモデルを使う。

  1. 各エポックの後に、検証データで損失(または性能)を計算する。
  2. 改善したらモデルを保存し、カウンタを 0 に戻す。
  3. 改善しなければカウンタを 1 増やす。
  4. カウンタが patience に達したら学習を止める。
  5. 保存した最良のモデルを最終モデルとする。

  6. 学習の無駄な計算を省ける上、過学習の前に止まる。patience はハイパーパラメータ。

  7. 検証損失は揺れるので、patience が小さすぎると、まだ下がる途中で止まってしまう。大きすぎると、止まるまでに過学習が進んで時間も使う。
  8. 2次関数の損失を単純な勾配降下法で最適化し、初期値を原点付近に取ると、早期終了は L2 正則化とほぼ同じ効果になる。学習ステップ数 \(t\) と学習率 \(\eta\) の積 \(\eta t\) が \(1/\lambda\) に対応する(大きい \(\eta t\) =弱い正則化)。パラメータを初期値の近くに留める、という制約を課している。

動かしてみる

  • patience を 1 にすると、検証損失が最初にわずかに上がっただけで止まり、最良のエポックよりかなり手前で終わります。
  • patience を 10 くらいに上げると、揺れを乗り越えて最良のエポックを見つけます。大きくしすぎると停止が遅れ、最良との差(戻るエポック数)が増えます。
  • ノイズを 0 にすると検証損失がなめらかになり、小さな patience でも最良のエポックの近くで止まります。

バッチサイズと学習率

  • バッチサイズ:小さいほど勾配のノイズが大きく、鋭い谷より平坦な谷に落ち着きやすく、汎化が良い傾向がある。大きいほど速い(並列)が、汎化が落ちる傾向(汎化ギャップ)がある。
  • 学習率:大きい学習率はノイズが大きく、正則化のように働く。一方で大きすぎると発散する。学習の後半で下げて収束させる(学習率のスケジュール)。
  • バッチサイズを増やすときは、学習率も増やして(線形スケーリング則)、効果の差を小さくする。

そのほか

手法 一言 ページ
データ拡張 回転・反転などで訓練データを増やす データ拡張
ラベル平滑化 正解ラベルをなだらかにして過信を抑える 出力層と損失関数
バッチ正規化 ミニバッチの統計のノイズが、弱い正則化になる 正規化
アンサンブル 複数モデルの平均 アンサンブル・ハイパーパラメータ
入力へのノイズ付加 入力に小さなノイズを足して学習する。小さいノイズなら L2 に近い —

試験の着眼点

  • L1 はスパース(特徴選択)、L2 は滑らかな縮小。勾配は L1:\(\lambda\,\mathrm{sign}(w)\)、L2:\(\lambda w\)。事前分布は L1=ラプラス、L2=ガウス。
  • weight decay は SGD で L2 正則化と同じで、更新は \((1-\eta\lambda)\mathbf{W}-\eta\,\partial L/\partial\mathbf{W}\)。バイアスには課さない。
  • ドロップアウトは学習時だけランダムに落とし、推論時は落とさず \(q\) 倍(または学習時に \(1/q\) 倍)。\(q\) は残す確率。
  • ドロップアウトは全結合層に入れる。CNN の畳み込み層では効果が限定的。
  • ドロップコネクトは重みを落とす。ドロップアウトはノードを落とす。
  • 早期終了は検証誤差が最小の時点で止める。patience を超えて改善がなければ停止し、最良のモデルを使う。L2 正則化の一種とみなせる。
  • 重み共有(CNN・RNN)、スパース表現、バッチサイズ・学習率の調整も正則化の効果を持つ。

参考