在非线性之前或在Keras之后立即添加批量标准化?

时间:2017-02-21 06:06:40

标签: tensorflow deep-learning theano keras

def conv2d_bn(x, nb_filter, nb_row, nb_col,
              border_mode='same', subsample=(1, 1),
              name=None):
    '''Utility function to apply conv + BN.
    '''

    x = Convolution2D(nb_filter, nb_row, nb_col,
                      subsample=subsample,
                      activation='relu',
                      border_mode=border_mode,
                      name=conv_name)(x)
    x = BatchNormalization(axis=bn_axis, name=bn_name)(x)
    return x

当我在keras中使用官方inception_v3模型时,我发现他们在'relu'非线性之后使用BatchNormalization作为上面的代码脚本。

但在批量标准化论文中,作者说

  

我们在非线性之前立即添加BN变换   标准化x = Wu + b。

然后我在tensorflow中查看初始化的实现,它在非线性之前立即添加BN。有关inception ops.py

的详细信息

我很困惑。为什么人们在Keras中使用以上风格而不是以下?

def conv2d_bn(x, nb_filter, nb_row, nb_col,
              border_mode='same', subsample=(1, 1),
              name=None):
    '''Utility function to apply conv + BN.
    '''

    x = Convolution2D(nb_filter, nb_row, nb_col,
                      subsample=subsample,
                      border_mode=border_mode,
                      name=conv_name)(x)
    x = BatchNormalization(axis=bn_axis, name=bn_name)(x)
    x = Activation('relu')(x)
    return x

在密集的情况下:

x = Dense(1024, name='fc')(x)
x = BatchNormalization(axis=bn_axis, name=bn_name)(x)
x = Activation('relu')(x)

2 个答案:

答案 0 :(得分:0)

我也在激活之前使用它,这确实是它的设计方式,其他库也是如此,例如lasagne的batch_norm http://lasagne.readthedocs.io/en/latest/modules/layers/normalization.html#lasagne.layers.batch_norm

然而,实际上,在激活之后放置它会更好一些:

https://github.com/ducha-aiki/caffenet-benchmark/blob/master/batchnorm.md (这只是一个基准)

答案 1 :(得分:0)

除了原始论文在激活前使用批归一化之外,Bengio 的书 Deep Learning, section 8.7.1 给出了一些推理为什么在激活之后(或直接在输入到下一层之前)应用批归一化可能会导致一些问题:

<块引用>

很自然地想知道我们是否应该将批量归一化应用于 输入 X,或转换后的值 XW+b。 Ioffe 和 Szegedy (2015) 推荐后者。更具体地说,XW+b 应该替换为 a XW 的标准化版本。应该省略偏置项,因为它 随着批处理应用的 β 参数变得多余 归一化重新参数化。层的输入通常是 非线性激活函数的输出,例如整流线性 上一层的功能。因此,输入的统计信息是 更非高斯,更不适合线性标准化 操作。

换句话说,如果我们使用 relu 激活,所有负值都映射为零。这可能会导致平均值已经非常接近于零,但剩余数据的分布将严重偏向右侧。尝试将该数据标准化为漂亮的钟形曲线可能不会给出最佳结果。对于 relu 系列之外的激活,这可能不是什么大问题。

请记住,有报告称模型在激活后使用批量标准化获得了更好的结果,因此使用这两种配置测试您的模型可能是值得的。