Tensorflow 如何在TF2.0中实现梯度反转层?
这一层是静态的,它是一个伪函数。在正向传播中,它不做任何事情(标识函数)。然而,在反向传播中,它将梯度乘以-1。github上有很多实现,但它们不适用于TF2.0 这里有一个供参考Tensorflow 如何在TF2.0中实现梯度反转层?,tensorflow,keras,tensorflow2.0,Tensorflow,Keras,Tensorflow2.0,这一层是静态的,它是一个伪函数。在正向传播中,它不做任何事情(标识函数)。然而,在反向传播中,它将梯度乘以-1。github上有很多实现,但它们不适用于TF2.0 这里有一个供参考 import tensorflow as tf from tensorflow.python.framework import ops class FlipGradientBuilder(object): def __init__(self): self.num_calls = 0
import tensorflow as tf
from tensorflow.python.framework import ops
class FlipGradientBuilder(object):
def __init__(self):
self.num_calls = 0
def __call__(self, x, l=1.0):
grad_name = "FlipGradient%d" % self.num_calls
@ops.RegisterGradient(grad_name)
def _flip_gradients(op, grad):
return [tf.negative(grad) * l]
g = tf.get_default_graph()
with g.gradient_override_map({"Identity": grad_name}):
y = tf.identity(x)
self.num_calls += 1
return y
flip_gradient = FlipGradientBuilder()
反转渐变的虚拟操作
这可以使用decoratortf.custom_gradient
完成,如下所述:
@tf.custom\u梯度
def梯度反转(x):
y=tf.identity(x)
def自定义梯度(dy):
返回dy
返回y,自定义梯度
然后,您可以将其当作正常的TensorFlow op来使用,例如:
z=编码器(x)
r=梯度_反向(z)
y=解码器(r)
凯拉斯API?
TF2.0的一大便利是它对KerasAPI的本机支持。您可以定义自定义的GradReverse
op,享受Keras的便利:
class梯度反转(tf.keras.layers.Layer):
定义初始化(自):
super()。\uuuu init\uuuuu()
def呼叫(自我,x):
反向返回梯度(x)
然后,您可以将该层用作任何其他Keras层,例如:
model=Sequential()
conv=tf.keras.layers.Conv2D(…)(inp)
cust=CustomLayer()(conv)
flat=tf.keras.layers.flant()(cust)
fc=tf.keras.layers.Dense(数量级)(平坦)
model=tf.keras.models.model(输入=[inp],输出=[fc])
compile(损失=…,优化器=…)
模型拟合(…)
这里有文档:@PedroMarques感谢您的链接。但文件仍然不明显。例如,他们定义了一个函数clip\u gradient\u by\u norm,但没有解释在何处使用它。例如,如果您使用Keras构建图形,您将从Lambda层调用此函数。默认情况下,Tensorflow跟踪图形定义内的张量操作,并使用其自动微分规则计算梯度。自定义渐变告诉它使用用户定义的渐变函数,而不是自动微分计算的渐变(对于此函数的范围)。Stackoverflow社区需要更多像您这样的人。谢谢。还有一件事,我不是专家,但我认为您应该将函数包装为lambda层,而不是有状态层,因为它是静态的。我说的对吗?@FalconUA,使用kerasapi的解决方案很优雅,但我无法让它工作。我尝试了裸骨代码(参见),并获取了错误值error:尝试将不支持类型()的值()转换为张量。@Jatala看起来您是将上一层本身作为参数传递,而不是调用它并传递结果。我没有看过你的代码,但这通常是由于放错了位置。