在tensorflow中为LSTM进行正则化

14

TensorFlow 提供了一个不错的 LSTM 封装。

rnn_cell.BasicLSTM(num_units, forget_bias=1.0, input_size=None,
           state_is_tuple=False, activation=tanh)

我想使用正则化,比如L2正则化。然而,我没有直接访问LSTM单元中使用的不同权重矩阵的权限,因此我无法显式地执行类似以下的操作:

loss = something + beta * tf.reduce_sum(tf.nn.l2_loss(weights))

有办法在LSTM中访问矩阵或以某种方式使用正则化吗?


我将整个过程作为回答放在了你的问题中。请查看 https://stackoverflow.com/questions/37869744/tensorflow-lstm-regularization/46761296#46761296 - sdr2002
3个回答

13

tf.trainable_variables会给你一个Variable对象的列表,你可以用它来添加L2正则化项。注意,这将为模型中的所有变量添加正则化。如果您只想将L2正则化项限制为权重的子集,则可以使用name_scope为您的变量命名特定前缀,并稍后使用该前缀来过滤从tf.trainable_variables返回的变量列表。


13

我喜欢做以下事情,但唯一知道的是,有些参数不喜欢用L2进行正则化,比如批规范化参数和偏置项。LSTMs包含一个Bias张量(虽然概念上它有许多偏差,但它们似乎被连结在一起以提高性能),对于批规范化,我在变量名中添加“noreg”以忽略它。

loss = your regular output loss
l2 = lambda_l2_reg * sum(
    tf.nn.l2_loss(tf_var)
        for tf_var in tf.trainable_variables()
        if not ("noreg" in tf_var.name or "Bias" in tf_var.name)
)
loss += l2

其中lambda_l2_reg是小的乘数,例如:float(0.005)

在循环中进行此选择(即完整的if),丢弃一些正则化变量,使我从未重新调整配置值的代码测试中一步跳跃从0.879 F1得分到了0.890。好吧,这包括批处理归一化和偏置的更改,我神经网络中还有其他的偏置。

根据这篇论文,对循环权重进行规范化可能有助于解决梯度爆炸问题。

此外,根据另一篇论文,如果使用dropout,最好将其用于堆叠单元之间而不是单元内部。

关于梯度爆炸问题,如果使用带有已添加L2正则化的损失函数进行梯度裁剪,则该正则化也会在裁剪过程中被考虑在内。


P.S. 这是我正在工作的神经网络:https://github.com/guillaume-chevalier/HAR-stacked-residual-bidir-LSTMs


0

Tensorflow有一些内置和辅助函数,可以让您将L2范数应用于您的模型,例如tf.clip_by_global_norm

    # ^^^ define your LSTM above here ^^^

    params = tf.trainable_variables()

    gradients = tf.gradients(self.losses, params)

    clipped_gradients, norm = tf.clip_by_global_norm(gradients,max_gradient_norm)
    self.gradient_norms = norm

    opt = tf.train.GradientDescentOptimizer(self.learning_rate)
    self.updates = opt.apply_gradients(
                    zip(clipped_gradients, params), global_step=self.global_step)

在你的训练步骤中运行:
    outputs = session.run([self.updates, self.gradient_norms, self.losses], input_feed)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接