SpatialDropout2D、BatchNormalization 和激活函数的正确顺序?
correct order for SpatialDropout2D, BatchNormalization and activation function?
对于 CNN 架构,我想使用 SpatialDropout2D 层而不是 Dropout 层。
另外我想使用 BatchNormalization。
到目前为止,我总是直接在卷积层之后但在激活函数之前设置 BatchNormalization,正如 Ioffe 和 Szegedy 在论文中提到的那样。
我一直在 MaxPooling2D 层之后设置的 dropout 层。
在https://machinelearningmastery.com/how-to-reduce-overfitting-with-dropout-regularization-in-keras/中直接在Convolutional层之后设置SpatialDropout2D。
我发现我现在应用这些层的顺序很混乱。我还在 Keras 页面上读到 SpatialDropout 应该直接放在 ConvLayer 后面(但我找不到这个页面了)。
以下顺序正确吗?
ConvLayer - SpatialDropout - BatchNormalization - 激活函数 - MaxPooling
非常希望得到提示并提前谢谢你
更新
我的目标其实是在下面的CNN架构dropout中换成spatial 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'))
Dropout 与 BatchNormalization - 标准偏差问题
混合这些层时会出现一个大问题,尤其是当 BatchNormalization
紧跟在 Dropout
之后时。
Dropouts 试图在没有 dropouts 的情况下保持相同的输出均值,但它确实改变了标准偏差,这将导致训练和验证之间的 BatchNormalization 存在巨大差异。 (在训练过程中,BatchNormalization
接收变化的标准差,累积并存储它们。在验证过程中,dropouts被关闭,标准差不再是变化的,而是原来的。但是BatchNormalization
,因为在validation中,不会使用batch statistics,而是stored statistics,与batch statistics有很大区别)
因此,第一个也是最重要的规则是:不要在 Dropout
(或 SpatialDropout
)之后放置 BatchNormalization
。
通常,在应用批量归一化之前,我会尝试保留至少两个 convolutional/dense 层没有任何丢失,以避免这种情况。
Dropout 与 BatchNormalization - 将零更改为另一个值
同样重要的是:Dropout
的作用是将下一层的一些权重的影响“归零”。如果你在 dropout 之后应用归一化,你将不再有“零”,而是一个将对许多单元重复的特定值。而且这个值会因批次而异。因此,尽管添加了噪声,但您并没有像纯 dropout 应该做的那样杀死单元。
Dropout 与 MaxPooling
在 MaxPooling
之前使用常规 Dropout
的问题是您会将一些像素归零,然后 MaxPooling
将取最大值,有点忽略部分你的辍学。如果你的 dropout 恰好达到最大像素,那么池化将导致第二个最大值,而不是零。
因此,Dropout
在 MaxPooling
之前降低了 dropout 的有效性。
SpatialDropout 与 MaxPooling
但是,SpatialDropout
永远不会命中“像素”,它只会命中频道。当它到达一个通道时,它将将该通道的所有像素归零,因此,MaxPooling
也将有效地导致零。
因此,spatial dropout 在池化之前和之后没有区别。整个“通道”在两个订单中都将为零。
BatchNormalization 与激活
根据激活函数,在它之前使用批量归一化可能是一个很好的优势。
对于 'relu'
激活,归一化使模型能够防止“全零冻结 relu 层”的不幸情况。它还将倾向于保证一半的单位为零,另一半为线性。
对于 'sigmoid'
或 'tahn'
,BatchNormalization
将保证值在健康范围内,避免饱和和梯度消失(值离零太远将击中这些函数的一个几乎平坦的区域,导致梯度消失。
有人说反之还有其他好处,这些好处我不是很清楚,我很喜欢我说的那些。
辍学与激活
和'relu'
没有区别,it can be proved that the results are exactly the same.
对于不居中的激活,例如 'sigmoid'
在激活之前放置一个 dropout 不会导致“零”,而是其他值。对于sigmoid,之前dropout的最终结果会是0.5.
例如,如果你在 dropout 之后添加一个 'tanh'
,你将得到零,但是 dropout 用于保持相同均值的缩放比例将被 tanh 扭曲。 (我不知道这是否是一个大问题,但可能是)
最大池化与激活
我在这里看的不多。如果激活不是很奇怪,最后的结果也是一样的。
结论?
有可能,但有的比较麻烦。我觉得下面的顺序不错,经常用
我会做类似的事情
- 第 1 组
- 转换
- BatchNorm
- 激活
- 最大池化
- Dropout 或 SpatialDropout
- 第 2 组
- 转换
- -----(最后一组有dropout,这里没有BatchNorm)
- 激活
- 最大池化
- Dropout or SpatialDropout(决定用不用)
- 两组后无dropout
- 可以再次使用 BatchNorm
对于 CNN 架构,我想使用 SpatialDropout2D 层而不是 Dropout 层。 另外我想使用 BatchNormalization。 到目前为止,我总是直接在卷积层之后但在激活函数之前设置 BatchNormalization,正如 Ioffe 和 Szegedy 在论文中提到的那样。 我一直在 MaxPooling2D 层之后设置的 dropout 层。
在https://machinelearningmastery.com/how-to-reduce-overfitting-with-dropout-regularization-in-keras/中直接在Convolutional层之后设置SpatialDropout2D。
我发现我现在应用这些层的顺序很混乱。我还在 Keras 页面上读到 SpatialDropout 应该直接放在 ConvLayer 后面(但我找不到这个页面了)。
以下顺序正确吗?
ConvLayer - SpatialDropout - BatchNormalization - 激活函数 - MaxPooling
非常希望得到提示并提前谢谢你
更新 我的目标其实是在下面的CNN架构dropout中换成spatial 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'))
Dropout 与 BatchNormalization - 标准偏差问题
混合这些层时会出现一个大问题,尤其是当 BatchNormalization
紧跟在 Dropout
之后时。
Dropouts 试图在没有 dropouts 的情况下保持相同的输出均值,但它确实改变了标准偏差,这将导致训练和验证之间的 BatchNormalization 存在巨大差异。 (在训练过程中,BatchNormalization
接收变化的标准差,累积并存储它们。在验证过程中,dropouts被关闭,标准差不再是变化的,而是原来的。但是BatchNormalization
,因为在validation中,不会使用batch statistics,而是stored statistics,与batch statistics有很大区别)
因此,第一个也是最重要的规则是:不要在 Dropout
(或 SpatialDropout
)之后放置 BatchNormalization
。
通常,在应用批量归一化之前,我会尝试保留至少两个 convolutional/dense 层没有任何丢失,以避免这种情况。
Dropout 与 BatchNormalization - 将零更改为另一个值
同样重要的是:Dropout
的作用是将下一层的一些权重的影响“归零”。如果你在 dropout 之后应用归一化,你将不再有“零”,而是一个将对许多单元重复的特定值。而且这个值会因批次而异。因此,尽管添加了噪声,但您并没有像纯 dropout 应该做的那样杀死单元。
Dropout 与 MaxPooling
在 MaxPooling
之前使用常规 Dropout
的问题是您会将一些像素归零,然后 MaxPooling
将取最大值,有点忽略部分你的辍学。如果你的 dropout 恰好达到最大像素,那么池化将导致第二个最大值,而不是零。
因此,Dropout
在 MaxPooling
之前降低了 dropout 的有效性。
SpatialDropout 与 MaxPooling
但是,SpatialDropout
永远不会命中“像素”,它只会命中频道。当它到达一个通道时,它将将该通道的所有像素归零,因此,MaxPooling
也将有效地导致零。
因此,spatial dropout 在池化之前和之后没有区别。整个“通道”在两个订单中都将为零。
BatchNormalization 与激活
根据激活函数,在它之前使用批量归一化可能是一个很好的优势。
对于 'relu'
激活,归一化使模型能够防止“全零冻结 relu 层”的不幸情况。它还将倾向于保证一半的单位为零,另一半为线性。
对于 'sigmoid'
或 'tahn'
,BatchNormalization
将保证值在健康范围内,避免饱和和梯度消失(值离零太远将击中这些函数的一个几乎平坦的区域,导致梯度消失。
有人说反之还有其他好处,这些好处我不是很清楚,我很喜欢我说的那些。
辍学与激活
和'relu'
没有区别,it can be proved that the results are exactly the same.
对于不居中的激活,例如 'sigmoid'
在激活之前放置一个 dropout 不会导致“零”,而是其他值。对于sigmoid,之前dropout的最终结果会是0.5.
例如,如果你在 dropout 之后添加一个 'tanh'
,你将得到零,但是 dropout 用于保持相同均值的缩放比例将被 tanh 扭曲。 (我不知道这是否是一个大问题,但可能是)
最大池化与激活
我在这里看的不多。如果激活不是很奇怪,最后的结果也是一样的。
结论?
有可能,但有的比较麻烦。我觉得下面的顺序不错,经常用
我会做类似的事情
- 第 1 组
- 转换
- BatchNorm
- 激活
- 最大池化
- Dropout 或 SpatialDropout
- 第 2 组
- 转换
- -----(最后一组有dropout,这里没有BatchNorm)
- 激活
- 最大池化
- Dropout or SpatialDropout(决定用不用)
- 两组后无dropout
- 可以再次使用 BatchNorm