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以某种方式使用正则化?
答案 0 :(得分:11)
我喜欢这样做,但我唯一知道的是一些参数不希望与L2正规化,例如批量标准参数和偏差。 LSTM包含一个偏置张量(尽管在概念上它有许多偏差,它们似乎是串联的或者某些东西,性能),并且对于批量标准化我添加" 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得分跳跃一次性测试代码没有重新调整配置的lambda
的值,这包括批量规范化和偏差的变化,我在神经网络中有其他偏差。
根据this paper,规则化重复的权重可能有助于爆发梯度。
另外,根据this other paper,如果你使用了一些,那么在堆叠的单元格之间使用dropout会更好,而不是在单元格内部。
关于爆炸梯度问题,如果使用已经添加了L2正则化的丢失的梯度限幅,那么在裁剪过程中也会考虑正则化。
P.S。这是我正在研究的神经网络:https://github.com/guillaume-chevalier/HAR-stacked-residual-bidir-LSTMs
答案 1 :(得分:10)
tf.trainable_variables
为您提供了Variable
个对象的列表,您可以使用这些对象添加L2正则化术语。请注意,这会为模型中的所有变量添加正则化。如果要将L2术语仅限制为权重的子集,可以使用name_scope
将变量命名为特定前缀,稍后使用它来过滤{{1}返回的列表中的变量}。
答案 2 :(得分: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)