张量流如何处理复杂的梯度?

时间:2017-02-27 06:19:07

标签: tensorflow autodiff

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如何处理复杂的渐变

2 个答案:

答案 0 :(得分:0)

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

关键是TensorFlow 定义复杂变量的复数值函数f(z)的“梯度”为“实图F的梯度:(x,y) -> Re(f(x + iy)),表示为复数”(该实图的梯度是R ^ 2中的向量,因此我们可以用明显的方式将其表示为复数)。

该定义的原因大概是,在TF中,通常与梯度有关,目的是对损失函数进行梯度下降,特别是确定该损失函数最大增加/减少的方向。使用上述梯度定义,意味着可以将复杂变量的复值函数用作标准梯度下降算法中的损失函数,其结果是该函数的实部被最小化(在我看来, “优化此复数值函数”的合理解释。)

现在,对于您的问题,写梯度定义的等效方法是

gradient(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

答案 1 :(得分:0)

如何?

Tensorflow用于渐变的公式为:

tf-grad-def

“ *”表示共轭。

当使用偏导数wrt z和z *的定义时,它使用Wirtinger微积分。 Wirtinger演算可以为非亚纯函数计算一个复杂变量的导数。 Wirtinger的定义是:

wirtinger

为什么使用此定义?

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

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