プールレイヤーはドロップアウトレイヤーの前または後に追加されますか?


35

畳み込みニューラルネットワーク(CNN)を作成しています。畳み込みレイヤーの後にプールレイヤーがあり、ドロップアウトを適用してオーバーフィットを減らします。プールレイヤーの後にドロップアウトレイヤーを適用する必要があると感じていますが、実際にそれをバックアップするものはありません。ドロップアウトレイヤーを追加する適切な場所はどこですか?プール層の前または後?

回答:


18

編集: @Toke Faurbyが正しく指摘したように、tensorflowのデフォルトの実装は実際には要素ごとのドロップアウトを使用します。前に説明したことは、空間ドロップアウトと呼ばれるCNNのドロップアウトの特定のバリアントに適用されます。

CNNでは、各ニューロンが1つの特徴マップを生成します。以来、ドロップアウト 空間ドロップアウト対応する特徴マップがドロップされることニューロン手段を落とすごとニューロン作品、 -例えば、各位置が同じ値(通常0)を有します。したがって、各機能マップは完全にドロップされるか、まったくドロップされません。

通常、プーリングは各機能マップで個別に動作するため、プーリングの前後にドロップアウトを適用しても違いはありません。少なくともこれは、maxpoolingや平均化などのプーリング操作の場合です。

編集:ただし、実際に要素単位のドロップアウト(テンソルフローのデフォルトとして設定されているようです)を使用する場合、プールの前または後にドロップアウトを適用すると実際に違いが生じます。ただし、必ずしも間違った方法ではありません。平均的なプーリング操作を検討してください。プーリングの前にドロップアウトを適用すると、結果として生じるニューロンの活性化をで効果的にスケーリングできます1.0 - dropout_probabilityが、ほとんどのニューロンはゼロではありません(一般的に)。平均プーリング後にドロップアウトを適用すると、通常、(1.0 - dropout_probability)非ゼロの「スケーリングされていない」ニューロンの活性化の一部とdropout_probabilityゼロのニューロンの一部が発生します。どちらも私には実行可能に思えますが、どちらもまったく間違っています。


1
これがドロップアウトを実行する標準的な方法かどうかわかりません。たとえば、tf.nn.dropoutでは、「デフォルトでは、各要素は個別に保持またはドロップされます」と表示されます。これをバックアップするソースはありますか?
トケフォービー

1
ああ!私が説明したものは現在、空間ドロップアウトと呼ばれています:arxiv.org/pdf/1411.4280.pdf。だから、@ TokeFaurbyは私の主張を疑うのが正しい。ただし、リンクされたペーパーでも読むことができるため、空間ドロップアウト方式で機能マップ全体をドロップするとパフォーマンスが向上します。これは驚くことではありません。隣接するアクティベーションは高度に相関しており、特定の要素を1つドロップしても、その要素によって運ばれる情報はまったくドロップされません(実行中に機能マップに連続した「穴」要素ごと)。この違いを反映するように回答を編集します。
シュレオン

10

このチュートリアルでは、ドロップアウトする前にプーリングを使用し、良い結果を得ています。

それは、必ずしも他の順序がもちろん機能しないことを必ずしも意味しません。私の経験は限られており、プールせずに密なレイヤーでしか使用していません。


5

KerasのVGGのようなconvnetの例(プーリング後に使用されるドロップアウト):

import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD

# Generate dummy data
x_train = np.random.random((100, 100, 100, 3))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
x_test = np.random.random((20, 100, 100, 3))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(20, 1)), num_classes=10)

model = Sequential()
# input: 100x100 images with 3 channels -> (100, 100, 3) tensors.
# this applies 32 convolution filters of size 3x3 each.
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)

model.fit(x_train, y_train, batch_size=32, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=32)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.