【问题标题】:Is my code right to use batch normalization layers in tensorflow?我的代码在 tensorflow 中使用批量标准化层是否正确?
【发布时间】:2018-04-20 15:22:58
【问题描述】:

我有两个输入:qi_pos & qi_neg 具有相同的形状。它们应该由两个 mlp 层处理,最后得到两个结果作为分数。这是我的代码:

  self.mlp1_pos  =    nn_layers.full_connect_(qi_pos,        256, activation='relu', use_bn = None, keep_prob=self.keep_prob,  name = 'deep_mlp_1')
  self.mlp2_pos  =    nn_layers.full_connect_(self.mlp1_pos, 128,  activation='relu', use_bn = True, keep_prob=self.keep_prob,  name = 'deep_mlp_2')
  self.pos_pair_sim = nn_layers.full_connect_(self.mlp2_pos,  1,  activation=None, use_bn = True, keep_prob=self.keep_prob,  name = 'deep_mlp_3')
  tf.get_variable_scope().reuse_variables()
  self.mlp1_neg  =    nn_layers.full_connect_(qi_neg,        256, activation='relu', use_bn = None, keep_prob=self.keep_prob,  name = 'deep_mlp_1')
  self.mlp2_neg  =    nn_layers.full_connect_(self.mlp1_neg, 128,  activation='relu', use_bn = True, keep_prob=self.keep_prob,  name = 'deep_mlp_2')
  self.neg_pair_sim = nn_layers.full_connect_(self.mlp2_neg,  1,  activation=None, use_bn = True, keep_prob=self.keep_prob,  name = 'deep_mlp_3')

我使用 BN 层对隐藏层中的节点进行归一化:

def full_connect_(inputs, num_units, activation=None, use_bn = None, keep_prob = 1.0, name='full_connect_'):
  with tf.variable_scope(name):
    shape = [inputs.get_shape()[-1], num_units]
    weight = weight_variable(shape)
    bias = bias_variable(shape[-1])
    outputs_ = tf.matmul(inputs, weight) + bias
    if use_bn:
        outputs_ = tf.contrib.layers.batch_norm(outputs_, center=True, scale=True, is_training=True,decay=0.9,epsilon=1e-5, scope='bn')
    if activation=="relu":
      outputs = tf.nn.relu(outputs_)
    elif activation == "tanh":
      outputs = tf.tanh(outputs_)
    elif activation == "sigmoid":
      outputs = tf.nn.sigmoid(outputs_)
    else:
      outputs = outputs_
    return  outputs

   with tf.name_scope('predictions'):
      self.sim_diff = self.pos_pair_sim - self.neg_pair_sim # shape = (batch_size, 1)
      self.preds = tf.sigmoid(self.sim_diff) # shape = (batch_size, 1)
      self.infers = self.pos_pair_sim

下面是损失定义。看起来没问题。

with tf.name_scope('predictions'):
  sim_diff = pos_pair_sim - neg_pair_sim
  predictions = tf.sigmoid(sim_diff)
  self.infers = pos_pair_sim
## loss and optim
with tf.name_scope('loss'):
  self.loss = nn_layers.cross_entropy_loss_with_reg(self.labels, self.preds)
  tf.summary.scalar('loss', self.loss)

我不确定我是否以正确的方式使用了 BN 层。我的意思是 BN 参数来自两个独立部分的隐藏单元,它们基于 qi_posqi_neg 张量作为输入。无论如何,有人可以帮忙检查一下吗?

【问题讨论】:

    标签: machine-learning tensorflow deep-learning batch-normalization


    【解决方案1】:

    您的代码对我来说似乎很好,在网络的不同分支中应用 BN 没有问题。但我想在这里提几点注意事项:

    • BN 超参数非常标准,所以我通常不会手动设置decayepsilonrenorm_decay。这并不意味着您不能更改它们,在大多数情况下根本没有必要。

    • 您在激活函数之前应用了BN,但是,有证据表明如果在激活函数之后应用它会更好。例如,参见this discussion。再说一次,这并不意味着它是一个错误,只是需要考虑一个架构。

    【讨论】:

    • 谢谢。顺便问一下,有必要在我的网络中使用 BN 吗?实际上我的网络只有三层,输入是嵌入短句。听说BN在电脑版网络中比较常用,因为网络的参数很大很密集。
    • 这是一个深奥的问题,没有通用的答案。在收敛速度(通常是 RNN 和 RL 任务)方面,BN 可以变得更糟。数据也有可能被很好地标准化,以至于 BN 并没有产生太大的影响,但在计算方面并不是免费的。如果只有 3 层并且数据经过良好的预处理,我通常会考虑一个或没有 BN,然后继续检查我的模型。最终可能会有几个 BN,但不是我开始的设计。
    猜你喜欢
    • 1970-01-01
    • 2016-11-14
    • 2018-04-09
    • 2017-03-03
    • 1970-01-01
    • 2016-03-01
    • 2015-09-28
    • 2018-06-05
    • 2016-03-03
    相关资源
    最近更新 更多