回答:
編集: @Toke Faurbyが正しく指摘したように、tensorflowのデフォルトの実装は実際には要素ごとのドロップアウトを使用します。前に説明したことは、空間ドロップアウトと呼ばれるCNNのドロップアウトの特定のバリアントに適用されます。
CNNでは、各ニューロンが1つの特徴マップを生成します。以来、ドロップアウト 空間ドロップアウト対応する特徴マップがドロップされることニューロン手段を落とすごとニューロン作品、 -例えば、各位置が同じ値(通常0)を有します。したがって、各機能マップは完全にドロップされるか、まったくドロップされません。
通常、プーリングは各機能マップで個別に動作するため、プーリングの前後にドロップアウトを適用しても違いはありません。少なくともこれは、maxpoolingや平均化などのプーリング操作の場合です。
編集:ただし、実際に要素単位のドロップアウト(テンソルフローのデフォルトとして設定されているようです)を使用する場合、プールの前または後にドロップアウトを適用すると実際に違いが生じます。ただし、必ずしも間違った方法ではありません。平均的なプーリング操作を検討してください。プーリングの前にドロップアウトを適用すると、結果として生じるニューロンの活性化をで効果的にスケーリングできます1.0 - dropout_probability
が、ほとんどのニューロンはゼロではありません(一般的に)。平均プーリング後にドロップアウトを適用すると、通常、(1.0 - dropout_probability)
非ゼロの「スケーリングされていない」ニューロンの活性化の一部とdropout_probability
ゼロのニューロンの一部が発生します。どちらも私には実行可能に思えますが、どちらもまったく間違っています。
このチュートリアルでは、ドロップアウトする前にプーリングを使用し、良い結果を得ています。
それは、必ずしも他の順序がもちろん機能しないことを必ずしも意味しません。私の経験は限られており、プールせずに密なレイヤーでしか使用していません。
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)