如何仅为Tensorflow子图定义渐变?

时间:2016-04-06 16:03:48

标签: tensorflow

首先:我和Tensorflow只有几天了,所以请耐心等待。

我从cifar10教程代码开始,我现在使用卷积和特征值分解的组合来打破符号差异。即图形构建,然后在调用train()时,脚本停止,并且#34;没有为操作定义梯度[...](操作类型:SelfAdjointEig)"。这并不奇怪。

所讨论的子图的输入仍然只是输入要素图和正在使用的过滤器,我有手头的渐变公式,并且它们应该直接实现给定子图的输入和关于其输出的梯度。

根据我在文档中看到的内容,我可以使用RegisterGradient为自定义操作注册渐变方法,或使用实验gradient_override_map覆盖它们。 这两个应该让我访问我需要的东西。例如,searching on Github我找到了很多以op.input[0]等形式访问操作输入的示例。

我遇到的问题是我本质上想要"快捷方式"一个完整的子图,而不是一个单独的op,所以我没有单一的op来装饰。 由于这发生在cifar示例的一个卷积层中,我尝试使用该层的范围对象。 从概念上讲,进入和退出该范围的图形正是我想要的,所以如果我能够以某种方式覆盖整个范围的渐变,那么已经"已经"做到这一点。

我看到tf.Graph.create_op(我认为)我可以用来注册一种新类型的操作,然后我可以用上述方法覆盖该操作类型的梯度计算。但我没有看到一种定义该操作前进的方法,而无需在C ++中编写它...

也许我完全以错误的方式接近这个? 由于我的所有前向或后向操作都可以使用python接口实现,因此我显然希望避免在C ++中实现任何内容。

4 个答案:

答案 0 :(得分:29)

这是Sergey Ioffe的一招:

假设您想要一组ops在前进模式下表现为f(x),但在后向模式下表示为g(x)。您将其实现为

t = g(x)
y = t + tf.stop_gradient(f(x) - t)

因此,在您的情况下,您的g(x)可以是身份操作,使用gradient_override_map

自定义渐变

答案 1 :(得分:1)

从TensorFlow 1.7开始,tf.custom_gradientthe way to go

答案 2 :(得分:0)

如何乘法和除法,而不是加减t?

t = g(x)
y = tf.stop_gradient(f(x) / t) * t

答案 3 :(得分:0)

这是适用于TensorFlow 2.0的方法。请注意,在2.0中,我们很高兴拥有2种不同的autodiff算法:Configuration.GetConnectionString("COMPANY"); 用于急切模式,GradientTape用于非急切模式(在这里称为“惰性”)。我们证明tf.gradient可以同时使用。

tf.custom_gradient