将 Lasagne BatchNormLayer 转换为 Keras BatchNormalization 层

Convert Lasagne BatchNormLayer to Keras BatchNormalization layer

我想将预训练的 Lasagne (Theano) 模型转换为 Keras (Tensorflow) 模型,因此所有层都需要具有完全相同的配置。从这两个文档中,我不清楚参数是如何对应的。假设千层面 BatchNormLayer 具有默认设置:

class lasagne.layers.BatchNormLayer(incoming, axes='auto', epsilon=1e-4, alpha=0.1, beta=lasagne.init.Constant(0), gamma=lasagne.init.Constant(1), mean=lasagne.init.Constant(0), inv_std=lasagne.init.Constant(1), **kwargs)

这是 Keras BatchNormalization 层 API:

keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True, beta_initializer='zeros', gamma_initializer='ones', moving_mean_initializer='zeros', moving_variance_initializer='ones', beta_regularizer=None, gamma_regularizer=None, beta_constraint=None, gamma_constraint=None)

大部分都清楚了,所以我在这里提供相应的参数供以后参考:

(Lasagne -> Keras)
incoming -> (not needed, automatic)
axes -> axis
epsilon -> epsilon
alpha -> ?
beta -> beta_initializer
gamma -> gamma_initializer
mean -> moving_mean_initializer
inv_std -> moving_variance_initializer
? -> momentum
? -> center
? -> scale
? -> beta_regularizer
? -> gamma_regularizer
? -> beta_constraint
? -> gamma_constraint

我假设 Lasagne 根本不支持 beta_regularizer、gamma_regularizer、beta_constraint 和 gamma_constraint,因此 Keras 中的默认值 None 是正确的。我还假设千层面中心和比例始终打开且无法关闭。

这就留下了 Lasagne alpha 和 Keras 的势头。来自 Lasagne documentation 的 alpha:

Coefficient for the exponential moving average of batch-wise means and standard deviations computed during training; the closer to one, the more it will depend on the last batches seen

来自Keras documentation的动力:

Momentum for the moving mean and the moving variance.

它们似乎是对应的——但是是哪个公式?

the Lasagne code我们看到alpha的用法是这样的:

running_mean.default_update = ((1 - self.alpha) * running_mean +
                               self.alpha * input_mean)
running_inv_std.default_update = ((1 - self.alpha) *
                                  running_inv_std +
                                  self.alpha * input_inv_std)

从这个issue discussing Keras batch norm 'momentum'我们可以看出:

def assign_moving_average(variable, value, decay, zero_debias=True, name=None):
    """Compute the moving average of a variable.
    The moving average of 'variable' updated with 'value' is:
      variable * decay + value * (1 - decay)

    ...

其中,如问题所述,TensorFlow 项 'decay' 是从 Keras 中获取 'momentum' 值的内容。

由此看来Lasagne所说的'alpha'等于1-'momentum',因为在Keras中,'momentum'是现有变量的乘数(现有移动平均值),而在烤宽面条中,此乘数为 1 - alpha.

诚然,这令人困惑,因为

  • Keras 底层的 TensorFlow 操作使用术语 'decay',但这是 Keras 直接命名的 'momentum'。
  • TensorFlow 代码仅将事物命名为 'variable' 和 'value',这使得很难知道哪些是存储的移动平均值,哪些是要合并的额外新数据。