问题描述
让我们假设我的函数是 (z : C -> C)
z = x - i*y
现在真正的部分是,
u(x,y) = x
虚部是,
v(x,y) = -y
所以,当我们得到导数时,我们发现
d_u_x(x,y) = 1 # derivative of u wrt x
d_u_y(x,y) = 0
d_v_x(x,y) = 0
d_v_y(x,y) = -1
所以,在这里,
d_u_x != d_v_y
因此,它不遵循柯西赖曼方程。
但是,然后是 Wirtinger 演算,也就是说,我可以将我的函数写为,
u(x,y) = ((x + iy) + (x - iy))/2
= (z + z.conj())/2
v(x,y) = (((x + iy) - (x - iy))/2i
= (z - z.conj())/2i
但是在此之后,我如何找到渐变。 另外,在 PyTorch 中,指定这样一个函数的正确方法是什么, 如果我这样做,
import torch
a = torch.randn(1,dtype=torch.cfloat,requires_grad=True)
f = a.conj()
f.backward()
print(a.grad)
这是正确的方法吗?
解决方法
您可能会发现以下感兴趣的页面:
-
当您使用 PyTorch 来区分具有复杂域和/或共域的任何函数
f(z)
时,梯度是在假设该函数是更大实值损失函数 {{ 1}}。计算的梯度为g(input)=L
(注意∂L/∂z*
的共轭),其负值正是梯度下降算法中使用的最速下降方向。因此,所有现有的优化器都可以使用复杂的参数开箱即用。 -
此约定与 TensorFlow 的复杂微分约定相匹配,但与 JAX(计算
z
)不同。 -
如果您有一个内部使用复杂运算的实对实函数,则此处的约定无关紧要:您将始终获得与仅使用实数实现相同的结果操作。
...
对于优化问题,研究界仅使用实值目标函数,因为复数不是任何有序域的一部分,因此具有复值损失没有多大意义。
事实证明,没有有趣的实值目标满足柯西-黎曼方程。所以同态函数理论不能用于优化,因此大多数人使用Wirtinger演算。