Tensorflow:如何替换或修改渐变? [英] Tensorflow: How to replace or modify gradient?

查看:126
本文介绍了Tensorflow:如何替换或修改渐变?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想替换或修改张量流中op或图形的一部分的梯度.如果可以在计算中使用现有的梯度,那将是理想的选择.

I would like to replace or modify the gradient of an op or portion of the graph in tensorflow. It would be ideal if I can use the existing gradient in the calculation.

从某些方面讲,这与tf.stop_gradient()的作用相反:我希望添加仅在计算梯度时使用的计算,而不是添加在计算梯度时会被忽略的计算.

In some ways this is the opposite to what tf.stop_gradient() does: instead of adding a calculation which is ignored when calculating gradients, I want a calculation which is only used when calculating gradients.

一个简单的例子就是简单地通过将梯度乘以常数来缩放比例(但不会将正向计算乘以常数).另一个例子是将梯度剪切到给定范围的东西.

A simple example would be something which simply scales gradients by multiplying them with a constant (but does not multiply the forward calculation by a constant). Another example would be something which clips the gradients to a given range.

推荐答案

对于TensorFlow 1.7和TensorFlow 2.0,请参见编辑打击.

For TensorFlow 1.7 and TensorFlow 2.0 look at edit blow.

首先定义您的自定义渐变:

First define your custom gradient:

@tf.RegisterGradient("CustomGrad")
def _const_mul_grad(unused_op, grad):
  return 5.0 * grad

由于您不希望前进过程中发生任何事情,因此请使用新的梯度来覆盖身份操作的梯度:

Since you want nothing to happen in the forward pass, override the gradient of an identity operation with your new gradient:

g = tf.get_default_graph()
with g.gradient_override_map({"Identity": "CustomGrad"}):
  output = tf.identity(input, name="Identity")

这是一个工作示例,其中的图层使用相同的方法在向后传递中剪切渐变,而在向前传递中不执行任何操作,

Here is a working example with a layer that clips gradients in the backwards pass and does nothing in the forwards pass, using the same method:

import tensorflow as tf

@tf.RegisterGradient("CustomClipGrad")
def _clip_grad(unused_op, grad):
  return tf.clip_by_value(grad, -0.1, 0.1)

input = tf.Variable([3.0], dtype=tf.float32)

g = tf.get_default_graph()
with g.gradient_override_map({"Identity": "CustomClipGrad"}):
  output_clip = tf.identity(input, name="Identity")
grad_clip = tf.gradients(output_clip, input)

# output without gradient clipping in the backwards pass for comparison:
output = tf.identity(input)
grad = tf.gradients(output, input)

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  print("with clipping:", sess.run(grad_clip)[0])
  print("without clipping:", sess.run(grad)[0])


为TensorFlow 1.7和TensorFlow 2.0编辑

从1.7开始,有一种新的方法可以使用较短的语法重新定义渐变,这也适用于Tensorflow 2.0.它还允许同时重新定义多个操作的梯度.以下是上面为TensorFlow 1.7和TensorFlow 2.0重写的示例:

Since 1.7 there is a new way to redefine the gradient with shorter syntax, which also works with Tensorflow 2.0. It also allows to redefine the gradient of multiple operations at the same time. Here are the examples from above, rewritten for TensorFlow 1.7 and TensorFlow 2.0:

在向后传递中缩放渐变的图层:

Layer that scales gradients in the backward pass:

@tf.custom_gradient
def scale_grad_layer(x):
  def grad(dy):
    return 5.0 * dy
  return tf.identity(x), grad

具有在向后传递中剪切渐变的图层的示例:

Example with a layer that clips gradients in the backward pass:

@tf.custom_gradient
def clip_grad_layer(x):
  def grad(dy):
    return tf.clip_by_value(dy, -0.1, 0.1)
  return tf.identity(x), grad

这篇关于Tensorflow:如何替换或修改渐变?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆