3.1. 勾配降下法
誤差関数(2章の復習)
訓練データ $ D = { (x_1, d_1), ... , (x_N, d_N) } $ に対する回帰問題での誤差関数
$$
E(w) = \frac{1}{2} \sum_{n = 1}^{N} ||d_n - y(x_n; w)||^2
$$
$x_i$は入力データ, $d_i$は目標出力データ, $w$はネットワークパラメータ(重みとバイアス), $y$は出力関数
他クラス分類問題での誤差関数
$$
E(w) = - \sum_{n = 1}^{N} \sum_{k = 1}^{K} d_{nk} \log y_k (x_n; w)
$$
$$
d_n = [d_{n1} ... d_{nK}]^t
$$
$y_k$はk番目のユニットの出力(ソフトマックス関数)
学習のゴール
誤差関数$E(w)$を最小にする$w = { argmin }_w E(w)$を求めること
勾配降下法
上記$w$を求める簡単な方法
勾配
$$
\nabla E \equiv \frac{\partial E}{\partial w} = [ \frac{\partial E}{\partial w_1} ... \frac{\partial E}{\partial w_M} ]^t
$$
$M$は$w$の成分数,
勾配降下法は現在の$w$を負の勾配方向($-\nabla E$)に少し動かし、これを何度も繰り返す。つまり現在の重みを$w^{(t + 1)}$, 動かした後の重みを$w^{(t)}$とすると
$$
w^{(t + 1)} = w^{(t)} - \epsilon \nabla E
$$
$\epsilon$は学習係数,
初期値$w^{(1)}$を適当に決めて再帰的に計算すればよい。$\epsilon$が十分に小さければ$t$の増加に伴って$E(w^{(t)})$を減少させる。よって$t$を十分に大きくすれば極小点にいつかは到達する。ただし、$\epsilon$が大き過ぎると$E(w)$が増加してしまうこともあるし、$\epsilon$が小さ過ぎると極小点到達までに必要な反復回数が増加し学習にかかる時間が大きくなる。
勾配降下法と同じような最小化手法としては2次微分を利用するニュートン法やその派生方法(準ニュートン法など)がある。ただ、ディープネットの学習は2次微分の計算が難しいため勾配降下法を用いている。
3.2 確率的勾配降下法(SGD)
前節では全訓練サンプル$n = 1, ... , N$に対して計算される誤差関数$E(w)$を最小化することを考えた。
$$
E(w) = \sum_{n = 1}^{N} E_n (w)
$$
前節の$w$の更新式では、この$E(w)$を用いる。この方法をバッチ学習と呼ぶ。
これに対しサンプルの一部を使ってパラメータの更新を行う方法を確率的勾配降下法(SGD)と呼ぶ。
$$
w^{(t + 1)} = w^{(t)} - \epsilon \nabla E_n
$$
次の$w^{(t + 1)}$の更新の際は別のサンプル$n'$を取り出し
$$
w^{(t + 1)} = w^{(t)} - \epsilon \nabla E_n'
$$
バッチ学習に対する確率的勾配降下法のメリット
- 訓練データの冗長性の影響を受けない
- 局所的な極小解に陥りにくい
- パラメータの更新が小刻みに行われるので学習の途中経過をより細かく監視できる
- オンライン学習が可能
その他の$w^{(t + 1)}$の更新方法としてはMomentum, AdaGrad, Adam等がある。
3.3 「ミニバッチ」の利用
重みの更新をサンプル1つ単位ではなく、少数のサンプルの集合をひとまとめにし、その単位で重みを更新する。そのひとまとめにしたサンプル集合をミニバッチと呼ぶ。
t回目の更新に用いるミニバッチを$D_t$, $N_t$を$D_t$のサンプル数とする。$D_t$の含む全サンプルに対する誤差
$$
E_t (w) = \frac{1}{N_t} \sum_{n \in D_t} E_n (w)
$$ を計算し、その勾配の方向にパラメータを更新する。なお、このように$E_t (w)$を$N_t$で正規化するとミニバッチのサイズを変えた時に学習係数を調整しなくてよい。
通常ミニバッチ$D_t(t = 1, 2, ...)$は学習前に作成し固定しておく。ミニバッチのサイズは大体10〜100前後。他クラス分類の問題ではミニバッチ間の重みの更新のばらつきを平準化するために、ミニバッチそれぞれに各クラスから1つ以上のサンプルを入れるのが理想。
なお、ミニバッチのサイズをあまり大きくすることは確率的勾配降下法のよさを損なうことになる。
3.4 汎化性能と過適合
訓練誤差
訓練データに対する誤差
前節までは訓練誤差の最小化を考えてきた
汎化誤差
「まだ見ぬ」サンプル$x$に対しての推定誤差、正確にはサンプルの母集団に対する誤差の期待値
本当の目的は汎化誤差を最小化すること。しかし、統計的な期待値なので訓練誤差のように計算できない。よって、訓練データとは別のサンプル集合を準備し、これに対する訓練誤差と同じ方法で計算される誤差を汎化誤差の目安とする。この目的で用意するデータをテストデータ、テストデータに関する誤差をテスト誤差と呼ぶ。
学習曲線
教科書参照。訓練誤差およびテスト誤差のエポック数に対するグラフ。訓練誤差は小さくなっているが汎化誤差(テスト誤差)が大きく乖離した状態を過適合/過剰適合/過学習と呼ぶ。学習にともなってテスト誤差が増加するようならそれ以降の学習は有害なのでその時点で学習を終了する。これを早期終了/早期打ち切りと呼ぶ。
過適合を起こすことなくテスト誤差(汎化誤差)を小さくできるかがニューラルネット学習の鍵
- ネットワークの層数
- ユニット数
- 学習係数
- 正則化の方法
- 学習のためのトリック
等を利用して実現する
3.5 過適合の緩和
3.5.1 正則化
学習時に重みの自由度を制約する
3.5.2 重みの制約
重み減衰(weight decay)
誤差関数に重みの二乗和(二乗ノルム)を加算し、これを最小化する
$$
E_t (w) = \frac{1}{N_t} \sum_{ n \in D_t } E_n (w) + \frac { \lambda }{ 2 } || w ||^2
$$
$\lambda$はこの正則化の強さを制御するパラメータで一般に0.01〜0.000001の範囲から選ぶ。この項の追加により学習時により小さい重みが選好されるようになる。
実際勾配降下法の更新式は
$$
w^{(t + 1)} = w^{(t)} - \epsilon ( \frac{1}{N_t} \sum \nabla E_n + \lambda w^{(t)} )
$$
$- \epsilon \lambda w^{(t)}$と重みは自身の大きさに比例した速さで常に減衰するように修正されている。このことからこの方法は重み減衰(weight decay)と呼ばれる。
なお重み減衰は通常ネットワークの重み$w^{(l)}$だけに適用し、バイアス$b^{(l)}$には適用しない。
- バイアスは総数が少ない -> 過適合しにくい
- 大きな値をとる必要がある
重み上限
重みの大きさの上限を制約する方法
$l$層のユニット$j$について、これが$l-1$層のユニット$i = 1, ... , I$からの出力を受け取るとする。その間の結合重み$w_{ji}$が
$$
\sum_{i} w_{ji}^2 < c
$$
を満たすように重みを制約する。それには、この不等式が満たされていない場合は$w_{j1}, ... w_{jI}$に1以下の定数を掛けて満たされるようにする。
これは比較的最近提案された方法で重み減衰を上回る効果があり後述するドロップアウトとともに用いると特に高い効果があることが報告されている。
3.5.3 ドロップアウト
多層ネットワークのユニットを確率的に選別して学習する方法
ネットワークを多数独立に訓練し、推論時にそれらの結果を平均するのと同じ効果があると考えられている
類似手法
- ドロップコネクト -> ニューロセルの結合を一定の確率で無視する
- 確率的最大プーリング -> replace the conventional deterministic pooling operations with a stochastic procedure, randomly picking the activation within each pooling region according to a multinomial distribution, given by the activities within the pooling region
3.6 学習のトリック
3.6.1 データの正規化
訓練データが偏りを含む場合、それが学習の妨げになることがある。そのような場合に偏りがなくなるように訓練データを変換する前処理。なお、訓練データに何らかの前処理を加えて変換した場合にはテストデータおよび推論時の各データにも同じ前処理を施す必要がある。
データの正規化あるいはデータの標準化は最も基本的な前処理で、各サンプル$x_n$に線形変換を施し、その成分ごとの平均や分散を揃える。
$x_n$の各成分$x_{ni}$から各成分$x_{ni}$の平均$\overline{x_i} \equiv ( \sum_{n = 1}^{N} x_{ni} ) / N$を引いて
$$
x_{ni} \leftarrow x_{ni} - \overline{x_i}
$$
と変換後のサンプルの平均を0にする。次に標準偏差$\sigma_i \equiv \sqrt{\frac{1}{N} \sum_{n = 1}^{N} (x_{ni} - \overline{x_i})^2}$で割って
$$
x_{ni} \leftarrow \frac{x_{ni} - \overline{x_i}}{\sigma_i}
$$
と変換後のサンプルの分散を1にする。
データによっては特定の$i$成分$(x_{ni})$のみ分散が0ないし極めて小さいことがあり、その場合は$\sigma_i$の代わりに$\max (\sigma_i, \varepsilon)$で割る。また、その変動の小さい成分に元々さほど意味がないという場合はこのように分散を揃えずそのままにした方がよい場合もある
3.6.2 データ拡張
訓練サンプルの量が足りないことは過適合を起こす最大の原因
大量のサンプルを集められない場合に手持ちのサンプルデータに何らかの加工を施し、量を「水増し」するのがデータ拡張(data augmentation)
サンプル$x$に何らかの変更を加えて$x'$を作り、それを新しいサンプルとして扱う。教師あり学習では通常$(x, d)$から$(x', d)$を作る
画像の場合
- 平行移動
- 鏡像反転
- 回転変動
- 幾何学的変形
- 濃淡
- 色に若干の変動
- ガウス分布に従うランダムノイズを一律に加える
など
3.6.3 複数ネットの平均
複数の異なるニューラルネットを組み合わせると一般に推定精度を向上させる
具体的には同じ入力を複数のニューラルネットに与え、そうして得られる複数の出力の平均を答えとする。各ニューラルネットは同じ問題を解くために訓練されたもので、入力層と出力層の構成は同じとする。これをモデル平均(model averaging)と呼ぶ。機械学習全般において有効な考え方(集団学習)
組み合わせるニューラルネット
- 構造が異なるネットワークを同じ訓練データで訓練したもの
- 同じ構造のネットワークで学習開始時の初期値を変えて同じ訓練データで訓練したもの
- 入力に異なる変換を施したネットワーク
など
3.6.4 学習係数の決め方
初期ほど大きな値を選び、学習の進捗とともに学習係数を小さくする
たとえば、学習係数をパラメータの更新数に比例して小さくする
$$
\epsilon_t = \epsilon_0 - \alpha t
$$
あるいは、最初に定数$\epsilon = \epsilon_0$をセットし、ある程度学習が進んだ時点でその値を$\frac{1}{10}$
$$
\epsilon = \frac{\epsilon}{10}
$$
にしてパラメータの更新を継続し、場合によってはこれを数回繰り返す
層ごとに異なる値を使う
各層の重みの更新速度がなるべく揃うように各層の重みを設定するのがよいといわれている
学習係数を自動的に定める方法
誤差関数の勾配を$g_t \equiv \nabla E_t$, このベクトルの成分を$g_{t, i}$とすると普通の勾配降下法では更新量の$i$成分は$- \epsilon g_{t, i}$だが
AdaGradでは
$$
- \frac{\epsilon}{\sqrt{\sum_{t' = 1}^{t} g_{t', i}^2}} g_{t, i}
$$
とする
3.6.5 モメンタム
重みの修正量に前回の重みの修正量のいくばくかを加算する方法
ミニバッチ$t-1$に対する重み修正量$\Delta w^{(t-1)} \equiv w^{(t)} - w^{(t-1)}$とし、ミニバッチ$t$に対する更新を
$$
w^{(t+1)} = w^{(t)} - \epsilon \nabla E_t + \mu \Delta w^{(t-1)}
$$
と定める。$\mu$はハイパーパラメータで、通常0.5〜0.9程度の範囲
前述の式は
$$
\Delta w^{(t)} \equiv w^{(t)} - w^{(t-1)} = \mu \Delta w^{(t-1)} - \epsilon \nabla E_t
$$
と書き換えられ、$- \epsilon \nabla E_t$を「重みの修正量の修正量」とみなせる
$\nabla E_t$がしばらくの間一定だとすると
$$
\Delta w^{(t)} \rightarrow \frac{- \epsilon \nabla E_t}{1 - \mu}
$$
と収束する。$\mu = 0.9$だったとするとこれは学習係数を10倍したことに相当する
3.6.6 重みの初期化
重みの初期値を決める一般的な方法はガウス分布(正規分布)から生成したランダム値を初期値とする方法$(w_{ji} 〜 N(0, \sigma^2))$である。このガウス分布の標準偏差$\sigma$をどう選ぶかは学習結果に影響を与える。例えばこれを大きくし重みのばらつきを大きくすると、初期の学習は速く進むものの誤差関数の減少が早く停止してしまう傾向がある。なお、バイアスの初期値は0とするのが普通
ユニットの活性化関数にロジスティック関数など値域に上下限のある関数を用いる場合、入力の重みを初期化する$\sigma$の範囲は制約される。$\sigma$がちょうどよい大きさでないと活性化関数の出力がその値域の中でちょうどよい範囲に来なくなるからである。まず$\sigma$が小さ過ぎると等しく0を初期値とするのと変わらなくなる。反対に大き過ぎるとユニットへの入力の総和$u_j = \sum_i w_{ji} x_i$のばらつきが過大となり、このユニットの出力は値域の上下限のいずれかの値をとることが多くなる。そうなると誤差関数の$w_{ji}$による微分は0に近い値しかとらなくなってしまい学習がうまく進まない
以上を踏まえると、ユニットへの総入力
$$
u_j = \sum_i w_{ji} x_i
$$
がちょうどよい分散を持つように$\sigma$を決めるのがよいといえる
重みを定数と見なし、またユニットへの各入力$x_i$が互いに独立だと仮定すると、$u_j$の分散は
$$
V(u_j) = \sum_{i = 1}^{M} w_{ji}^2 V(x_i)
$$
となる。$M$はこのユニットの入力側結合の数
入力$x_i$の変動を正規化してあり$(V(x_i) = 1)$、総入力の分散を$V(u_j) = \sigma_u^2$にしたいとすると
$$
\sigma = \sigma_u / M^{1/2}
$$
とすればよい
3.6.7 サンプルの順序
SGDを使う場合訓練サンプルをどの順で取り出すかには自由度がある
ミニバッチを使う場合どんなサンプルを組み合わせてミニバッチを作るかと作ったミニバッチの提示順に任意性がある
一般的にはネットワークが「見慣れない」サンプルを先に提示すると学習が最も効果的に進むといえる。そこで誤差が大きいサンプル、つまりいまだよく学習されていないサンプルから順に提示する方法がある