【问题标题】:how tensorflow handles complex gradient?tensorflow 如何处理复杂的梯度?
【发布时间】:2017-02-27 06:19:07
【问题描述】:

z是复变量,C(z)是它的共轭。 在复分析理论中,C(z) w.r.t z的导数是不存在的。但是在 tesnsorflow 中,我们可以计算 dC(z)/dz,结果只是 1。 这是一个例子:

x = tf.placeholder('complex64',(2,2))
y = tf.reduce_sum(tf.conj(x))
z = tf.gradients(y,x)
sess = tf.Session()
X = np.random.rand(2,2)+1.j*np.random.rand(2,2)
X = X.astype('complex64')
Z = sess.run(z,{x:X})[0]

输入X

[[0.17014372+0.71475762j  0.57455420+0.00144318j]
 [0.57871044+0.61303568j  0.48074263+0.7623235j ]]

结果Z

[[1.-0.j  1.-0.j]
 [1.-0.j  1.-0.j]]

我不明白为什么渐变设置为1? 而且我想知道tensorflow 是如何处理复杂梯度的

【问题讨论】:

  • 我猜这是不支持的。您的工作需要此功能吗?

标签: tensorflow autodiff


【解决方案1】:

怎么做?

Tensorflow 用于梯度的方程为:

“*”表示共轭。

当使用 z 和 z* 的偏导数的定义时,它使用维廷格微积分。 Wirtinger 演算能够计算非全纯函数的复变量的导数。 Wirtinger 的定义是:

为什么要这样定义?

当使用例如复值神经网络 (CVNN) 时,梯度将用于一个或多个复变量的非全纯实值标量函数,然后梯度的 tensorflow 定义可以写为:

此定义与 CVNN 的文献相对应,例如 this bookAmin et al. 的第 4 章第 4.3 节(在无数示例之间)。

【讨论】:

    【解决方案2】:

    有点晚了,不过我最近也遇到了这个问题。

    关键在于TensorFlow定义复变量的复值函数f(z)的“梯度”为“真实映射F的梯度:(x,y) -> Re(f(x+iy)),表示为复数”(那个实图的梯度是R^2中的一个向量,所以我们可以用很明显的方式将它表示为复数)。

    这个定义的原因大概是在 TF 中,人们通常关注梯度,以便在损失函数上运行梯度下降,特别是为了识别该损失函数的最大增加/减少的方向。使用上面的梯度定义意味着复变量的复值函数可以用作标准梯度下降算法中的损失函数,结果将是函数的实部被最小化(在我看来对“优化这个复值函数”的某种合理解释)。

    现在,对于您的问题,编写渐变定义的等效方法是

    梯度(f) := dF/dx + idF/dy = conj(df/dz + dconj(f)/dz)

    (你可以很容易地验证使用 d/dz 的定义)。这就是 TensorFlow 处理复杂梯度的方式。至于 f(z):=conj(z) 的情况,我们有 df/dz=0(正如你提到的)和 dconj(f)/dz=1,给出梯度(f)=1。

    我在这里写了一个更长的解释,如果你有兴趣:https://github.com/tensorflow/tensorflow/issues/3348#issuecomment-512101921

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多