SpatialDropout2D、BatchNormalization 和激活函数的正确顺序?

Cod*_*Now 6 keras activation-function batch-normalization dropout

对于 CNN 架构,我想使用 SpatialDropout2D 层而不是 Dropout 层。另外我想使用 BatchNormalization。到目前为止,我总是直接在卷积层之后但在激活函数之前设置 BatchNormalization,就像 Ioffe 和 Szegedy 的论文中提到的那样。我总是在 MaxPooling2D 层之后设置 dropout 层。

https://machinelearningmastery.com/how-to-reduce-overfit-with-dropout-regularization-in-keras/ 中, SpatialDropout2D 直接设置在卷积层之后。

我发现我现在应该以何种顺序应用这些层相当令人困惑。我还在 Keras 页面上读到 SpatialDropout 应该直接放在 ConvLayer 后面(但我再也找不到这个页面了)。

以下顺序是否正确?

ConvLayer - SpatialDropout - BatchNormalization - 激活函数 - MaxPooling

我真的希望得到提示并提前谢谢你

更新 我的目标实际上是在以下 CNN 架构 dropout 中交换空间 dropout:

model = Sequential()
model.add(Conv2D(32,(3,3))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Conv2D(32,(3,3))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2))
model.add(Dropout(0.2))

model.add(Conv2D(64, (3,3))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Conv2D(64,(3,3))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2))
model.add(Dropout(0.2))

model.add(Flatten())
model.add(Dense(512))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.4))
model.add(Dense(10))
model.add(Activation('softmax'))
Run Code Online (Sandbox Code Playgroud)

Dan*_*ler 11

Dropout vs BatchNormalization - 标准偏差问题

混合这些图层时会出现一个大问题,尤其BatchNormalization是在Dropout.

Dropouts 尝试在没有 dropouts 的情况下保持相同的输出均值,但它确实改变了标准偏差,这将导致训练和验证之间的 BatchNormalization 存在巨大差异。(在训练期间,BatchNormalization接收更改的标准偏差,累积并存储它们。在验证期间,辍学被关闭,标准偏差不再是更改的,而是原始的。但是BatchNormalization,因为它在验证中,不会使用批次统计,但存储的统计,这将与批量统计有很大不同)

因此,第一个也是最重要的规则是:不要BatchNormalization在 a Dropout(或 a SpatialDropout)之后放置 a 。

通常,在应用批量归一化之前,我会尝试至少保留两个卷积/密集层而不会出现任何丢失,以避免这种情况。

Dropout 与 BatchNormalization - 将零更改为另一个值

同样重要的是: 的作用Dropout是将下一层的某些权重的影响“归零”。如果你在 dropout 之后应用归一化,你将不再有“零”,而是一个特定的值,该值将重复许多单位。这个值会因批次而异。因此,尽管添加了噪音,但您并没有像纯粹的 dropout 那样杀死单位。

Dropout 与 MaxPooling

在 aDropout之前使用正则的问题MaxPooling是你会将一些像素归零,然后MaxPooling将取最大值,有点忽略掉你的一部分。如果您的 dropout 碰巧达到最大像素,则池化将导致第二个最大值,而不是零。

所以,DropoutbeforeMaxPooling降低了dropout的有效性。

SpatialDropout 与 MaxPooling

但是,aSpatialDropout永远不会击中“像素”,它只会击中通道。当它击中一个通道时,它将该通道的所有像素归零,因此,MaxPooling也将有效地导致归零。

因此,池化之前和之后的空间丢失没有区别。整个“通道”在两个订单中都为零。

批量标准化与激活

根据激活函数,在它之前使用批量归一化可能是一个很好的优势。

对于'relu'激活,归一化使模型能够防止“全零冻结 relu 层”的坏运气情况。它还倾向于保证一半的单位为零,另一半为线性。

对于 a'sigmoid'或 a 'tahn'BatchNormalization将保证值在健康范围内,避免饱和度和梯度消失(离零太远的值将触及这些函数的几乎平坦区域,导致梯度消失)。

有人说反之还有其他优点,我不是很清楚这些优点,我很喜欢我提到的那些。

辍学与激活

'relu',没有区别,可以证明结果是完全一样的

对于不居中的激活,例如'sigmoid'在激活之前放置dropout不会导致“零”,而是其他值。对于 sigmoid,dropout 的最终结果是 0.5。

'tanh'例如,如果您在 dropout 后添加 a ,您将获得零,但用于保持相同均值的 dropout 缩放将被 tanh 扭曲。(我不知道这是否是一个大问题,但可能是)

MaxPooling 与激活

我在这里看的不多。如果激活不是很奇怪,最后的结果应该是一样的。

结论?

有可能,但有些可能很麻烦。我发现以下顺序很好,并且经常使用它

我会做类似的事情

  • 第一组
    • 转化率
    • 批规范
    • 激活
    • 最大池化
    • Dropout 或 SpatialDropout
  • 组2
    • 转化率
    • -----(最后一组有dropout,这里没有BatchNorm)
    • 激活
    • 最大池化
    • Dropout 或 SpatialDropout(决定使用与否)
  • 两组无辍学后
    • 可以再次使用 BatchNorm