機械学習: コンピューター ビジョンにおける深層学習: 畳み込みニューラル ネットワークの概要

記事コードの出典: "deep learning on keras" は非常に良い本です。英語が得意な方は直接この本を読むことをお勧めします。時間がない場合は、このシリーズの記事を読んでください。

この章では、コンピューター ビジョンで一般的に使用される深層学習モデルの一種である畳み込みニューラル ネットワークについて学習し、それを分類問題に適用する方法を学びます。
まず、畳み込みニューラル ネットワークの背後にある理論をいくつか紹介します。具体的には次のとおりです。

  • 畳み込みと最大プーリングとは何ですか?
  • 畳み込みネットワークとは何ですか?
  • 畳み込みネットワークは何を学んだのでしょうか?

次に、小さなデータセットを使用して画像分類問題を一般化します。

  • 小規模な畳み込みネットワークを最初からトレーニングする
  • データ拡張を使用して過剰適合を回避する
  • 事前トレーニングされた畳み込みネットワークを特徴抽出に使用する
  • 事前学習済み畳み込みネットワークのパラメータを調整する

最後に、分類方法を学ぶためのいくつかの視覚化テクニックの概要を説明します。

次は最初のセクション、畳み込みニューラル ネットワークの紹介です。

畳み込みニューラル ネットワークの理論を詳しく掘り下げ、なぜ畳み込みニューラル ネットワークがコンピューター ビジョン タスクでこれほど成功するのかを探ります。まず、実際の単純な畳み込みネットワークの例を見てみましょう。畳み込みネットワークを使用して MNIST 数字を分類します。以前は、完全に接続されたネットワークを使用して 97.8% の認識率を達成しました。私たちの畳み込みネットワークは非常に基本的ですが、その精度率は元の完全に接続されたネットワークよりも優れています。
次の 6 行のコードは、最も基本的な畳み込みネットワークがどのようなものであるかを示します。これは実際には、いくつかの 2 次元畳み込み層と 2 次元最大プーリング層のスタックです。畳み込みによって取得されるテンソルの形状 (長さ、幅、チャネル数) には、バッチの次元は含まれません。この例では、MNIST のデータ形式である形状 (28,28,1) の入力データを処理します。

from keras import layers
from keras import models
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

次に、畳み込みネットワークの構造を見てみましょう。

>>> model.summary()
________________________________________________________________
Layer (type) Output Shape Param #
================================================================
conv2d_1 (Conv2D) (None, 26, 26, 32) 320
________________________________________________________________
maxpooling2d_1 (MaxPooling2D) (None, 13, 13, 32) 0
________________________________________________________________
conv2d_2 (Conv2D) (None, 11, 11, 64) 18496
________________________________________________________________
maxpooling2d_2 (MaxPooling2D) (None, 5, 5, 64) 0
________________________________________________________________
conv2d_3 (Conv2D) (None, 3, 3, 64) 36928
================================================================
Total params: 55,744
Trainable params: 55,744
Non-trainable params: 0

各畳み込み層とプーリング層の出力が 3 次元テンソルであることがわかります。ネットワークが深くなるにつれて、幅と高さが縮小し始めます。チャネルの数は、畳み込み層に渡される最初のパラメータによって制御されます。
次のステップは、出力テンソルを完全に接続された分類ネットワークにフィードすることです。分類器は 1 次元ベクトルを処理し、出力は 3 次元テンソルであるため、3 次元出力を 1 次元出力に圧縮する必要があります。次に、密度レイヤーを追加します。

model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

次に 10 クラス分類を実行します。活性化関数としてソフトマックスを選択し、出力次元は 10 です。ネットワークは次のようになります。

>>> model.summary()
Layer (type) Output Shape Param #
================================================================
conv2d_1 (Conv2D) (None, 26, 26, 32) 320
________________________________________________________________
maxpooling2d_1 (MaxPooling2D) (None, 13, 13, 32) 0
________________________________________________________________
conv2d_2 (Conv2D) (None, 11, 11, 64) 18496
________________________________________________________________
maxpooling2d_2 (MaxPooling2D) (None, 5, 5, 64) 0
________________________________________________________________
conv2d_3 (Conv2D) (None, 3, 3, 64) 36928
________________________________________________________________
flatten_1 (Flatten) (None, 576) 0
________________________________________________________________
dense_1 (Dense) (None, 64) 36928
________________________________________________________________
dense_2 (Dense) (None, 10) 650
================================================================
Total params: 93,322
Trainable params: 93,322
Non-trainable params: 0

最後に、前にトレーニングに使用したコードを使用します。

from keras.datasets import mnist
from keras.utils import to_categorical
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape((60000, 28, 28, 1))
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape((10000, 28, 28, 1))
test_images = test_images.astype('float32') / 255
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
model.compile(optimizer='rmsprop',
 loss='categorical_crossentropy',
 metrics=['accuracy'])
model.fit(train_images, train_labels, epochs=5, batch_size=64)

その後、最終結果を評価します

>>> test_loss, test_acc = model.evaluate(test_images, test_labels)
>>> test_acc
0.99080000000000001

単純な畳み込みニューラル ネットワークが完全接続モデルよりもはるかに優れたパフォーマンスを発揮できるのはなぜでしょうか? この問題を理解するには、畳み込み層と最大プーリング層を引き続き深く掘り下げる必要があります。

畳み込み演算子

全結合層はグローバル パターンを学習し、畳み込み層はローカル パターンを学習します。

ここに画像の説明を挿入します

画像は、エッジ、テクスチャなどの局所的なパターンに分類できます。

この重要な機能により、畳み込みネットワークに 2 つの興味深い特性が与えられます。

  • 学習されたパターンは変換不変であり、完全に接続されたネットワークで学習されたパターンは位置に依存しますが、畳み込みネットワークはデータ効率が高くなります。

  • 以下に示すように、パターンの空間階層を学習できます。最初の層はエッジなどの小さな局所的なパターンを学習しますが、2 番目の畳み込み層は最初の層に基づいてより大きな特徴を学習します。これにより、畳み込みネットワークは、より効果的に複雑な機能をさらに抽象化する方法を学習できるようになります。

    ここに画像の説明を挿入します

    視覚世界は、視覚モジュールの空間階層を形成します。超局所的なエッジが目や耳などの局所的なオブジェクトに結合され、それが「猫」などの高レベルの概念に結合されます。

    3 次元テンソルの畳み込み演算は「特徴マップ」と呼ばれ、これには 2 つの空間座標 (幅と高さ) と深さ座標 (チャネル数とも呼ばれます) が含まれます。RGB 画像の場合、深さの次元は座標は3です。MNIST の場合、白黒画像の深度は 1 です。畳み込み演算子は、入力特徴マップからパッチを抽出し、すべてのパッチに対していくつかの変換を実行して、出力特徴マップを生成します。出力特徴マップは依然として 3 次元テンソルですが、ここでの深度は特定の色を表すのではなく、フィルターと呼ばれるものを表します。フィルターは入力データの特定の側面をエンコードします。大まかに言うと、単純なフィルターは入力内の顔の存在をエンコードできます。
    畳み込みは、次の 2 つの主要なパラメーターによって定義されます。

  • 入力から抽出されたパッチ チャンクのサイズ。私たちの場合、通常は
    ここに画像の説明を挿入します

の。

  • 出力特徴マップの深さ、つまりフィルターの数。この例では、深さ 32 で開始し、深さ 64 で終了します。

keras の畳み込み層では、渡される最初のパラメーターは Conv2D(output_ Depth, (window_height, window_width)) です。
コンボリューションは、スライドしてあらゆる可能な位置で停止し、周囲の特徴から 3D パッチを抽出することによって機能します。
概略図は次のとおりです。

ここに画像の説明を挿入します

畳み込みの仕組み

取得する出力の幅と高さが入力の幅と高さと異なる場合があることに注意してください。これには 2 つの理由があります。

  • 入力特徴マップのパディングによって生じる境界効果。
  • スライディングの使用については後で定義します。

これらの注意点を見てみましょう。

境界線の効果とパディングを理解する

を検討してください

ここに画像の説明を挿入します

フィーチャー マップ、合計 25 個の小さなブロック。ただし、9 種類の小さなピースしかないため、集中して取り組むことができます。

ここに画像の説明を挿入します

小さな窓に。したがって、出力特徴マップは次のようになります

ここに画像の説明を挿入します

: これにより、各次元で 2 つの小さなブロックずつ大幅に縮小され、前の例の「境界効果」がわかります。
ここに画像の説明を挿入します

5x5 入力特徴マップ内の 3x3 パッチの有効な位置

元の入力と同一の出力特徴マップを取得したい場合は、パディングの使用を選択できます。適切な数の行ベクトルと列ベクトルを追加して埋めます。

ここに画像の説明を挿入します

ウィンドウでは、左側と右側に列を追加するか、上部と下部に行を追加するかを選択できます。のために

ここに画像の説明を挿入します

ウィンドウには 2 行しかありません。

ここに画像の説明を挿入します

25 個の 3x3 パッチを抽出できるようにするための 5x5 入力のパディング

畳み込み層では、パディングは「padding」パラメータを通じて設定できます。「padding」パラメータには、「valid」と「same」の 2 つの値が含まれます。前者はパディングなしを意味し、後者は入力と出力にパディングを持たせることを意味します。幅と高さが同じで、パディングパラメータのデフォルト値は「有効」です。

畳み込みスライディングを理解する

出力サイズに影響を与えるもう 1 つの要素は「ストライド」です。これまでの畳み込みの説明では、畳み込みウィンドウの中央のブロックが構成されていると仮定してきました。ただし、実際には、2 つの連続するウィンドウ間には「ストライド」と呼ばれる畳み込みパラメータがあり、デフォルト値は 1 です。次の図では、ストライドが 2 に設定されていることがわかります。

ここに画像の説明を挿入します

2x2 ストライドの 3x3 コンボリューション パッチ

ストライド 2 を使用すると、幅と高さの両方が 2 の係数でダウンサンプリングされることを意味します。スライディング畳み込みは、さまざまなモデルで便利ですが、実際にはほとんど使用されません。よく理解しておくことは常に良いことです。
特徴をダウンサンプリングするには、スライドに加えて、最大プーリング演算子を使用して行うこともできます。

最大プーリング演算子

畳み込みの例では、最大プーリング後に特徴マップの数が半分になることがわかりました。これは、スライディング畳み込みと同様に、ダウンサンプリングにおいて非常に積極的です。
最大プーリングは、入力特徴からウィンドウを抽出し、各チャネルの最大値を出力することで構成されます。これは畳み込みに非常に似ています。
なぜプールを行うのでしょうか? プーリングステップが削除されたらどうなるでしょうか?

model_no_max_pool = models.Sequential()
model_no_max_pool.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model_no_max_pool.add(layers.Conv2D(64, (3, 3), activation='relu'))
model_no_max_pool.add(layers.Conv2D(64, (3, 3), activation='relu'))

出力構造:

>>> model_no_max_pool.summary()
Layer (type) Output Shape Param #
================================================================
conv2d_4 (Conv2D) (None, 26, 26, 32) 320
________________________________________________________________
conv2d_5 (Conv2D) (None, 24, 24, 64) 18496
________________________________________________________________
conv2d_6 (Conv2D) (None, 22, 22, 64) 36928
================================================================
Total params: 55,744
Trainable params: 55,744
Non-trainable params: 0

この設定は何か間違っているのでしょうか?ポイントは次の 2 つです。

  • これは、空間レベルの特徴を学習するのには役立ちません。
    ここに画像の説明を挿入します

レイヤー 3 のウィンドウには入力のみが含まれます。

ここに画像の説明を挿入します

情報。畳み込みネットワークが学習できる高レベルの機能はまだ小さすぎます。すべての入力情報を含めるために、最後の畳み込み層が必要です。

  • 最後の特徴量の係数が多すぎます。

簡単に言うと、ダウンサンプリングを使用して特徴係数の数を減らすと同時に、連続する畳み込み層でより大きなウィンドウを処理して空間フィルターの数を減らすことができます。
最大プーリングがダウンサンプリングを実現する唯一の方法ではないことに注意してください。また、ストライドも使用でき、平均プーリングも使用できることがわかります。ただし、多くの場合、最大プーリングはこれらの代替手段よりもパフォーマンスが優れています。

おすすめ

転載: blog.csdn.net/lijunhcn/article/details/135073031