過学習
- 過学習とは学習データに対して適応しすぎることにより、未知のデータの誤差が大きくなってしまう現象のこと
- 過学習を防ぐ方法としてL1正則化・L2正則化、ドロップアウトがあげられる。
L1正則化・L2正則化
- 重みが大きいと過学習になりやすいことから、重みに制限をつけることで過学習を防ぐ。それがL1正則化・L2正則化といわれる手法
- L1正則化とは各重みの絶対値の和を誤差関数に加えて最小化する方法
- L2正則化とは各重みの絶対二乗和を誤差関数に加えて最小化する方法
# L1正則化
for idx in range(1, hidden_layer_num+1):
grad['W' + str(idx)] = network.layers['Affine' + str(idx)].dW + weight_decay_lambda * np.sign(network.params['W' + str(idx)])
grad['b' + str(idx)] = network.layers['Affine' + str(idx)].db
network.params['W' + str(idx)] -= learning_rate * grad['W' + str(idx)]
network.params['b' + str(idx)] -= learning_rate * grad['b' + str(idx)]
weight_decay += weight_decay_lambda * np.sum(np.abs(network.params['W' + str(idx)]))
loss = network.loss(x_batch, d_batch) + weight_decay
# L2正則化
for idx in range(1, hidden_layer_num+1):
grad['W' + str(idx)] = network.layers['Affine' + str(idx)].dW + weight_decay_lambda * network.params['W' + str(idx)]
grad['b' + str(idx)] = network.layers['Affine' + str(idx)].db
network.params['W' + str(idx)] -= learning_rate * grad['W' + str(idx)]
network.params['b' + str(idx)] -= learning_rate * grad['b' + str(idx)]
weight_decay += 0.5 * weight_decay_lambda * np.sqrt(np.sum(network.params['W' + str(idx)] ** 2))
loss = network.loss(x_batch, d_batch) + weight_decay
- 下の図で右側がL1正則化、左側がL2正則化を表している。(楕円形の部分が誤差関数、丸と四角の部分が正則化項)
実装演習
考察
- 最初の学習では訓練データの正解率が1となり過学習を起こしている
- L2正則化を実行してみると過学習を抑制することができたが良い結果が得られなかった
- L1正則化もL2正則化と同様、過学習を抑制できているが良い結果は得られていない
- L2正則化、L1正則化共にλを大きくすると正則化が強すぎて、正解率が変化しなくなる。λを小さくすると正則化が弱すぎて過学習をおこしていることが確認できた
- 正則化だけでは過学習を抑制できてもよい結果を得ることができない可能性があると考えられる
ドロップアウト
- 過学習の原因の1つとしてノードの数が多いことがあげられる。ドロップアウトとはランダムにノードを削除して学習を行うことで過学習を防ぐ方法である。
- 削除するノードは重みの更新をするたびに変える
- 複数のネットワークを作成し、平均をとることで精度が向上することが一般的に知られている。ドロップアウトを行うことで計算量を減らしつつ、複数のネットワークでの学習を実現していると言える
実装演習
考察
- ドロップアウトを行った結果、過学習を起こさず比較的良い結果を得ることができた
- ドロップアウト率大きくするとうまく学習が進まず、小さくすると過学習を起こしてしまった
- ドロップアウト率をそのままに各学習率最適化法を使うと、過学習を起こしやすくなった。学習率を最適化する場合は過学習の対策を強める必要があると考えられる
- 学習率最適化法を使いつつ、ドロップアウト率を大きくすると過学習は起こさなかったが、良い結果は得られなかった
- ドロップアウトとL1正則化を組み合わせた場合が一番良い結果を得ることができた。学習の速さ、過学習を起こしているかどうかなどを総合的に判断し、様々な方法を組み合わせてニューラルネットワークを構築する必要がある
畳み込みニューラルネットワーク(CNN)
- 畳み込みニューラルネットワークとは畳み込み層とプーリング層という2種類の層を含む順伝播型ネットワーク。主に画像認識で使われる。
- これまでの順伝播型ネットワークは隣接している層同士の結合は全結合であったが、畳み込みニューラルネットでは特定のユニット同士が結合をもっている
- 全結合で画像を学習した場合、縦・横・チャンネルの3次元データが1次元のデータとして処理されてしまう
畳み込み層
- 畳み込み層とは通常の順伝播型ネットワークでいうと各入力値と各重みの積にバイアスをかけて値を次の層に出力する層のことを言う
- 畳み込みニューラルネットワークは主に画像認識で使われるので入力データは画像となる。畳み込み層では重みのことをフィルタと呼ぶ。
- 入力されたデータの画素をi,jで表し(i,j)番目の画素の値をxとし、フィルタの画素をp,qで表し(p,q)の値をhで表すとすると畳み込み層の計算は以下の式で表される(フィルタは入力された画像よりサイズが小さいものとする)
- イメージとしては入力された画像にフィルタを重ねて各要素の積の和を求める、そしてフィルタを少しづつずらして同様に計算を行う。以上を繰り返して値を出力する
パディング
- 普通に畳み込みの計算を行うと、入力された画像よりフィルタのほうが小さいことから、出力される画像のサイズはどんどん小さくなってしまう。出力される画像のサイズを大きくしたい場合は、入力画像の外側に0などの値を加えて入力画像のサイズを大きくする方法がある。これをパディングと呼ぶ
ストライド
- ストライドとは畳み込みの計算を行うときにフィルタをずらす間隔のことを言う
- ストライドを大きくすると画像の特徴を取りこぼす可能性が増える。ただし、入力された画像が大きすぎるときに出力される画像のサイズを小さくしたいときはストライドを2以上にして計算を行う。
-例)サイズ6×6の入力画像を、サイズ2×2のフィルタで畳み込んだ時(ストライドとパディングは1)の出力画象のサイズは6×6となる
チャンネル
- チャンネルとは入力画像の奥行きのことを示す。
- チャンネルの数とフィルターの数は一致する
実装演習
考察
- im2colはimage to columnの略で画像を2次元配列に変えるという意味
- 画像(多次元データ)を2次元配列に変換することで、2次元配列を扱う既存のライブラリを利用することができる
- フィルターのサイズを大きくすることで出力される2次元配列のサイズが小さくなる。ストライドを大きくすることで出力される2次元配列のサイズが小さくなる。パディングを増やすことで出力される2次元配列のサイズが大きくなる
- col2imは2次元配列を多次元データに変換する処理
- im2colとcol2imは全く違う処理を行うので、im2colの出力をそのままcol2imの入力に使っても元の多次元データに復元することはできない。通常はim2colで出力された2次元配列を加工してからcol2imを行う
プーリング層
- プーリング層では以下の計算が行われる。入力された画像を一定のサイズの正方形に分割する。そして、それぞれの正方形の中で平均値や最大値などの値を計算し最終的な出力値とする。
- プーリング層を使うことで、学習データの間で特徴の位置にずれがある場合でも、出力値を安定させることができる
- 畳み込み層と同様にパディングやストライドを使う場合がある
実装演習
考察
- ネットワークの構成は畳み込み層、ReLU関数を使った中間層、プーリング層などからなり、出力層はソフトマックス関数を使っている。
- プーリング層ではマックスプーリングを行っている
- 学習率の最適化にはAdamを使っている。結果として高い精度を実現できている
最新のCNN
AlexNet
- AlexNetとは2012年に開かれた画像認識コンペで、2位に大差をつけて優勝したモデルである。AlexNetの登場がディープラーニングブームのきっかけとなったと言われている。
- これ以前にもディープラーニングや畳み込みニューラルネットワークは存在していたが、実際に成果を出したのはAlexNetが初めてだとされている
- AlexNetは3層の畳み込み層、2層のプーリング層の後に3層の全結合層、合計8層で構成されたモデルである。
- プーリング層では最大値が出力されている
- 全結合層の活性化関数にはReLU関数が使われている
- 過学習を防ぐため、全結合層にドロップアウトを使用している