正則化¶
キーワード: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)がある。
陰的正則化¶
損失に項を足さなくても、学習の進め方が解に制約をかけて汎化を良くすることがある。
早期終了¶
検証誤差が最小になった時点(訓練誤差が小さくなった時点ではない)で学習を止め、その時点のモデルを使う。
- 各エポックの後に、検証データで損失(または性能)を計算する。
- 改善したらモデルを保存し、カウンタを 0 に戻す。
- 改善しなければカウンタを 1 増やす。
- カウンタが patience に達したら学習を止める。
-
保存した最良のモデルを最終モデルとする。
-
学習の無駄な計算を省ける上、過学習の前に止まる。patience はハイパーパラメータ。
- 検証損失は揺れるので、patience が小さすぎると、まだ下がる途中で止まってしまう。大きすぎると、止まるまでに過学習が進んで時間も使う。
- 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)、スパース表現、バッチサイズ・学習率の調整も正則化の効果を持つ。
参考¶
- Dropout: A Simple Way to Prevent Neural Networks from Overfitting(Srivastava ほか, 2014)
- Regularization of Neural Networks using DropConnect(Wan ほか, 2013)
- Decoupled Weight Decay Regularization(Loshchilov, Hutter, 2019)
- On Large-Batch Training for Deep Learning: Generalization Gap and Sharp Minima(Keskar ほか, 2017)
- Deep Learning, Chapter 7 Regularization for Deep Learning(Goodfellow, Bengio, Courville, 2016)