Ars*_*tic 90 python machine-learning deep-learning lstm tensorflow
考虑示例代码.
我想知道如何在可能爆炸梯度的RNN上对此网络应用渐变剪辑.
tf.clip_by_value(t, clip_value_min, clip_value_max, name=None)
Run Code Online (Sandbox Code Playgroud)
这是一个可以使用的示例,但我在哪里介绍这个?在defN的RNN
lstm_cell = rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0)
# Split data because rnn cell needs a list of inputs for the RNN inner loop
_X = tf.split(0, n_steps, _X) # n_steps
tf.clip_by_value(_X, -1, 1, name=None)
Run Code Online (Sandbox Code Playgroud)
但是这没有意义,因为张量_X是输入而不是渐变的被剪裁的东西?
我是否必须为此定义自己的优化器,还是有更简单的选项?
Sty*_*rke 133
在计算渐变之后,但在应用它们来更新模型的参数之前,需要进行梯度裁剪.在您的示例中,这两个方面都由AdamOptimizer.minimize()
方法处理.
为了剪切渐变,您需要显式计算,剪辑和应用它们,如本节TensorFlow的API文档中所述.具体来说,您需要使用以下内容替换调用minimize()
方法:
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
gvs = optimizer.compute_gradients(cost)
capped_gvs = [(tf.clip_by_value(grad, -1., 1.), var) for grad, var in gvs]
train_op = optimizer.apply_gradients(capped_gvs)
Run Code Online (Sandbox Code Playgroud)
dan*_*jar 108
尽管看起来很受欢迎,但您可能希望通过其全局规范来剪切整个渐变:
optimizer = tf.train.AdamOptimizer(1e-3)
gradients, variables = zip(*optimizer.compute_gradients(loss))
gradients, _ = tf.clip_by_global_norm(gradients, 5.0)
optimize = optimizer.apply_gradients(zip(gradients, variables))
Run Code Online (Sandbox Code Playgroud)
单独剪切每个渐变矩阵会改变它们的相对比例,但也可能:
optimizer = tf.train.AdamOptimizer(1e-3)
gradients, variables = zip(*optimizer.compute_gradients(loss))
gradients = [
None if gradient is None else tf.clip_by_norm(gradient, 5.0)
for gradient in gradients]
optimize = optimizer.apply_gradients(zip(gradients, variables))
Run Code Online (Sandbox Code Playgroud)
调用minimize()会同时计算渐变并将它们应用于变量.如果要在应用渐变之前处理渐变,可以分三步使用优化器:
- 使用compute_gradients()计算渐变.
- 根据需要处理渐变.
- 使用apply_gradients()应用已处理的渐变.
在他们提供的示例中,他们使用以下3个步骤:
# Create an optimizer.
opt = GradientDescentOptimizer(learning_rate=0.1)
# Compute the gradients for a list of variables.
grads_and_vars = opt.compute_gradients(loss, <list of variables>)
# grads_and_vars is a list of tuples (gradient, variable). Do whatever you
# need to the 'gradient' part, for example cap them, etc.
capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars]
# Ask the optimizer to apply the capped gradients.
opt.apply_gradients(capped_grads_and_vars)
Run Code Online (Sandbox Code Playgroud)
这MyCapper
是限制渐变的任何函数.有用的功能列表(除了tf.clip_by_value()
)在这里.
tf.keras 很容易!
optimizer = tf.keras.optimizers.Adam(clipvalue=1.0)
Run Code Online (Sandbox Code Playgroud)
此优化器会将所有梯度剪辑到 之间的值[-1.0, 1.0]
。
请参阅文档。
对于那些想要理解渐变剪辑(通过规范)的人:
只要梯度范数大于特定阈值,我们就会剪切梯度范数,使其保持在阈值范围内.此阈值有时设置为5
.
设梯度为g,max_norm_threshold为j.
现在,如果|| g || > j,我们这样做:
g =( j*g)/ || g ||
这是在中完成的实现 tf.clip_by_norm
IMO 最好的解决方案是用 TF 的 estimator 装饰器包装您的优化器tf.contrib.estimator.clip_gradients_by_norm
:
original_optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
optimizer = tf.contrib.estimator.clip_gradients_by_norm(original_optimizer, clip_norm=5.0)
train_op = optimizer.minimize(loss)
Run Code Online (Sandbox Code Playgroud)
这样你只需要定义一次,而不是在每次梯度计算后运行它。
文档:https : //www.tensorflow.org/api_docs/python/tf/contrib/estimator/clip_gradients_by_norm
归档时间: |
|
查看次数: |
62660 次 |
最近记录: |