Pytorch 的 Autograd 不支持复杂矩阵求逆,有人有解决方法吗?

问题描述

在我的损失函数的某个地方,我反转了一个大小为 64*64 的复杂矩阵。尽管 torch.tensor 支持复矩阵求逆,但由于出现此错误,因此无法在训练循环中计算梯度:

RuntimeError: inverse 不支持复杂类型输出自动微分。

有没有人有解决这个问题的方法一个自定义函数而不是 torch.inverse 也许?

解决方法

您可以使用复矩阵的实值分量自己进行逆运算。

先了解一些线性代数:

一个复矩阵 C 可以写成两个 real 矩阵 AB 的和(j 是 - 1):

C = A + jB  

找到C的逆基本上是找到两个实值矩阵xy,使得

(A + jB)(x + jy) = I + j0

这归结为求解实值方程组: enter image description here

既然我们知道如何将复数矩阵求逆简化为实值矩阵求逆,我们就可以使用 pytorch 的 solve 为我们进行求逆。

def complex_inverse(C):
  A = torch.real(C)
  B = torch.imag(C)
  # construct the left hand side of the system of equations
  # side note: from pytorch 1.7.1 you can use vstack and hstack instead of cat
  lhs = torch.cat([torch.cat([A,-B],dim=1),torch.cat([B,A],dim=1)],dim=0)
  # construct the rhs of the system of equations
  rhs = torch.cat([torch.eye(A.shape[0]).to(A),torch.zeros_like(A)],dim=0)

  # solve the system of equations
  raw,_ = torch.solve(rhs,lhs)
  # write the solution as a single complex matrix
  iC = raw[:C.shape[0],:] + 1j * raw[C.shape[0]:,:]
  return iC  

您可以使用 numpy 验证解决方案:

# C is a complex torch tensor
iC = complex_inverse(C)

with torch.no_grad():  
  print(np.isclose(iC.cpu().numpy() @ C.cpu().numpy(),np.eye(C.shape[0])).all())  

请注意,通过使用块矩阵的逆技巧,您可以降低 solve 操作的计算成本。

,

1.9 开始,PyTorch 现在支持复杂的 autograd。