1. 序章

ディープニューラルネットワークのトレーニングは、取り組むべきいくつかの問題を伴う難しいタスクです。 それらの巨大な可能性にもかかわらず、それらは遅く、過剰適合しがちです。 したがって、これらの問題を解決する方法に関する研究は、ディープラーニングの研究では常に行われています。

バッチ正規化(一般にバッチノルムと略される)は、これらの方法の1つです。 現在、ディープラーニングの分野で広く使用されている手法です。 ニューラルネットワークの学習速度を向上させ、過剰適合を回避する正則化を提供します。

しかし、なぜそれがそれほど重要なのですか? それはどのように機能しますか? さらに、畳み込みニューラルネットワークなどの非正規ネットワークにどのように適用できますか?

2. 正規化

バッチノルムがどのように機能し、なぜそれが重要であるかを完全に理解するために、正規化について話すことから始めましょう。

正規化は、データを標準化するために使用される前処理手法です。 つまり、同じ範囲内に異なるデータソースがあるということです。 トレーニングの前にデータを正規化しないと、ネットワークに問題が発生し、トレーニングが大幅に困難になり、学習速度が低下する可能性があります。

たとえば、レンタカーサービスがあるとします。 まず、競合他社のデータに基づいて、各車の適正価格を予測します。 車ごとに2つの機能があります。年数と走行距離の合計です。 これらは、0年から30年の範囲で非常に異なる範囲を持つことができますが、距離は0から数十万キロメートルに及ぶ可能性があります。 範囲が高いほどモデルにバイアスがかかり、重要度が高くなる可能性があるため、機能に範囲の違いがないようにします。

データを正規化する主な方法は2つあります。 最も簡単な方法は、0から1の範囲にスケーリングすることです。

   

正規化するデータポイント、データセットの平均、最大値、および最小値。 この手法は、通常、データの入力に使用されます。 範囲が広い正規化されていないデータポイントは、ニューラルネットワークを不安定にする可能性があります。 比較的大きな入力はレイヤーにカスケードされ、グラデーションの爆発などの問題を引き起こす可能性があります。

データを正規化するために使用される他の手法は、次の式を使用して、データポイントの平均を0、標準偏差を1にすることです。

   

正規化するデータポイント、データセットの平均、およびデータセットの標準偏差です。 現在、各データポイントは標準正規分布を模倣しています。 この規模のすべての機能を備えているため、どの機能にもバイアスがないため、モデルの学習が向上します。

バッチノルムでは、この最後の手法を使用して、ネットワーク自体の内部のデータのバッチを正規化します。

3. バッチ正規化

バッチノルムは、生データではなく、ニューラルネットワークのレイヤー間で行われる正規化手法です。 これは、完全なデータセットではなく、ミニバッチに沿って行われます。 トレーニングをスピードアップし、より高い学習率を使用して、学習を容易にします。

前のセクションで説明した手法に従って、バッチノルムの正規化式を次のように定義できます。

   

ニューロンの出力の平均とニューロンの出力の標準偏差です。

3.1. それはどのように適用されますか?

次の画像では、通常のフィードフォワードニューラルネットワークを見ることができます。入力、ニューロンの出力、活性化関数の出力、およびネットワークの出力です。

バッチノルム(赤い線で表された画像)は、活性化関数を適用する直前にニューロンの出力に適用されます。 通常、バッチノルムのないニューロンは次のように計算されます。

   

ニューロンの線形変換、ニューロンの重み、ニューロンのバイアス、および活性化関数です。 モデルはパラメータとを学習します。 バッチノルムを追加すると、次のようになります。

   

バッチノルムの出力、ニューロンの出力の平均、ニューロンの出力の標準偏差、およびバッチノルムの学習パラメーターです。 ニューロンのバイアス()が削除されていることに注意してください。 これは、平均を減算するときに、–などの値を超える定数はそれ自体で減算されるため無視できるためです。

パラメータと、それぞれ平均と標準偏差をシフトします。 したがって、レイヤー上のバッチノルムの出力は、平均と標準偏差が。の分布になります。 これらの値は、モデルの損失を減らすことを目的として、エポックおよびニューロンの重みなどの他の学習パラメーターを介して学習されます。

3.2. Pythonでの実装

Keras、Tensorflow、Pytorchなどの最新の機械学習フレームワークを使用する場合、BatchNormの実装は非常に簡単です。 それらは最も一般的に使用される方法が付属しており、一般的に最新の状態になっています。

Kerasを使用すると、次のようにバッチノルムを使用して非常に単純なフィードフォワードニューラルネットワークを実装できます。

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, BatchNormalization

model = Sequential([
    Dense(16, input_shape=(1,5), activation='relu'),
    BatchNormalization(),
    Dense(32, activation='relu'),
    BatchNormalization(),
    Dense(2, activation='softmax')
])

3.3. なぜバッチ正規化が機能するのですか?

バッチノルムを適用および実装する方法がわかったので、なぜそれが機能するのですか? どうすればトレーニングをスピードアップし、学習を容易にすることができますか?

バッチノルムがそのすべてに影響を与えると考えられる理由はいくつかあります。 ここでは、最も重要な理由の直感を公開します。

まず、入力を正規化して同様の範囲の値を取得することで、学習をどのように高速化できるかを確認できます。 簡単な直感の1つは、Batch Normが、入力だけでなく、ネットワークのレイヤーの値でも同様のことを行っていることです。

第二に、彼らの元の論文 Sergey et al。は、BatchNormがネットワークの内部共変量シフトを減らすと主張しています。 共変量シフトは、データ分布の変化です。 たとえば、レンタカーサービスの例に戻って、他のバイクを含めたいと想像してみてください。 車のみを含む以前のデータセットのみを見ると、モデルはバイクの価格を予測できない可能性があります。 このデータの変化(現在はバイクを含む)は共変量シフトと呼ばれ、現実の問題で一般的な問題であるため、注目を集めています。

内部共変量シフトは、ニューラルネットワークの内部層の入力分布の変化です。 内部層のニューロンの場合、(前の層から)受信した入力は常に変化しています。 これは、その前に実行された複数の計算と、トレーニングプロセス全体の重みによるものです。

バッチノルムを適用すると、レイヤー入力の平均と標準偏差が常に同じになります。 と、それぞれ。 したがって、レイヤーの入力の分布の変化量が減少します。 より深い層は、入力値がどうなるかについてより強固な基盤を持ち、学習プロセス中に役立ちます。

最後に、BatchNormには正則化効果があるようです。  データセット全体ではなくミニバッチで計算されるため、モデルのデータ分布では、毎回ノイズが発生します。 これは正則化として機能し、過剰適合を克服し、よりよく学習するのに役立ちます。 ただし、追加されるノイズは非常に小さいです。 したがって、通常、それ自体で適切に正規化するだけでは不十分であり、通常はドロップアウトと一緒に使用されます。

4. 畳み込みニューラルネットワークにおけるバッチ正規化

バッチノルムは、畳み込みニューラルネットワークで非常によく似た方法で機能します。 以前と同じ方法でそれを行うことができますが、畳み込み特性に従う必要があります。

畳み込みでは、入力の特徴マップに沿ったフィルターを共有しました(画像では、特徴マップは通常、高さと幅です)。 これらのフィルタは、すべてのフィーチャマップで同じです。 その場合、同じ方法で出力を正規化し、機能マップ上で共有するのが合理的です。

つまり、これは、正規化に使用されるパラメータが各フィーチャマップ全体とともに計算されることを意味します。 通常のバッチノルムでは、各機能の平均と標準偏差が異なります。 ここで、各機能マップには、含まれるすべての機能で使用される単一の平均と標準偏差があります。

4.1. Pythonでの実装

繰り返しになりますが、畳み込みニューラルネットワークでのバッチノルムの実装は、最新のフレームワークを使用すると非常に簡単です。 以前に使用したのと同じ関数を使用して、バックグラウンドで操作を実行します。

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, BatchNormalization, Conv2D, MaxPooling2D

model = Sequential([
  Conv2D(32, (3,3), input_shape=(28, 28, 3) activation='relu'), 
  BatchNormalization(),
  Conv2D(32, (3,3), activation='relu'), 
  BatchNormalization(),
  MaxPooling2D(),
  Dense(2, activation='softmax')
])

5. 結論

ここでは、バッチ正規化をフィードフォワードニューラルネットワークと畳み込みニューラルネットワークに適用する方法を見てきました。 また、モデルと学習速度がどのように、そしてなぜ改善されるのかについても調査しました。

最後に、Kerasなどの最新の機械学習フレームワークを使用したこのメソッドの簡単な実装をいくつか見てきました。