池层是在辍学层之前还是之后添加的?


35

我正在创建一个卷积神经网络(CNN),其中有一个卷积层,后跟一个池化层,我想应用dropout来减少过度拟合。我有种感觉,应该在池化层之后应用辍学层,但是我真的没有什么可以支持的。在何处添加辍学图层?在池化层之前还是之后?

Answers:


18

编辑:正如@Toke Faurby正确指出的那样,tensorflow中的默认实现实际上使用了逐个元素丢弃。我之前描述的内容适用于CNN中辍学的特定变体,称为空间辍学

在CNN中,每个神经元都会产生一个特征图。由于漏失 空间漏失每神经元作品,滴中的神经元单元,其对应的特征地图被丢弃-例如,每个位置具有相同的值(通常为0)。因此,每个功能图要么完全删除,要么完全不删除。

池化通常在每个要素图上单独运行,因此,如果在池化之前或之后应用辍学,则池化不会有任何区别。至少对于像maxpooling或averaging这样的池化操作来说就是这种情况。

编辑:但是,如果您实际上使用逐元素的辍学(似乎已将其设置为张量流的默认值),则在池化之前或之后应用辍学实际上会有所不同。但是,不一定有错误的方法。考虑平均池化操作:如果在池化之前应用dropout,则可以有效地缩放产生的神经元激活1.0 - dropout_probability,但是大多数神经元将非零(通常)。如果在平均池化之后应用dropout,通常最终会得到一小部分(1.0 - dropout_probability)非零“未缩放”神经元激活和一小部分dropout_probability零神经元。两者在我看来都是可行的,都不是完全错误的。


1
我不确定这是执行辍学的标准方法。例如,在tf.nn.dropout中,它指出“默认情况下,每个元素都是独立保留或删除的”。您是否有支持此的来源?
Toke Faurby

1
哦! 我所描述的现在称为空间缺失arxiv.org/pdf/1411.4280.pdf。因此,@ TokeFaurby怀疑我的主张是正确的。但是,您也可以在链接的文章中阅读,以空间缺失的方式放置整个要素地图可以提高性能。这一点不足为奇,因为相邻的激活高度相关,并且丢弃一个特定元素实际上根本不会丢弃该元素所携带的信息(因为这样做时不太可能在特征图中丢弃连续的“空洞”元素)。我将编辑答案以反映这种差异。
schreon

10

本教程使用辍学前的池化,并获得良好的结果。

那不一定意味着其他顺序当然行不通。我的经验是有限的,我只在密集的层上使用它们而不进行池化。


5

来自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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.