Answers:
编辑:正如@Toke Faurby正确指出的那样,tensorflow中的默认实现实际上使用了逐个元素丢弃。我之前描述的内容适用于CNN中辍学的特定变体,称为空间辍学:
在CNN中,每个神经元都会产生一个特征图。由于漏失 空间漏失每神经元作品,滴中的神经元单元,其对应的特征地图被丢弃-例如,每个位置具有相同的值(通常为0)。因此,每个功能图要么完全删除,要么完全不删除。
池化通常在每个要素图上单独运行,因此,如果在池化之前或之后应用辍学,则池化不会有任何区别。至少对于像maxpooling或averaging这样的池化操作来说就是这种情况。
编辑:但是,如果您实际上使用逐元素的辍学(似乎已将其设置为张量流的默认值),则在池化之前或之后应用辍学实际上会有所不同。但是,不一定有错误的方法。考虑平均池化操作:如果在池化之前应用dropout,则可以有效地缩放产生的神经元激活1.0 - dropout_probability
,但是大多数神经元将非零(通常)。如果在平均池化之后应用dropout,通常最终会得到一小部分(1.0 - dropout_probability)
非零“未缩放”神经元激活和一小部分dropout_probability
零神经元。两者在我看来都是可行的,都不是完全错误的。
来自Keras的类似于VGG的卷积网络示例(合并后使用辍学):
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)