pytorch对矩阵(奇异和非奇异)求逆

  • Post author:
  • Post category:其他

非奇异矩阵求逆

import torch
x = torch.FloatTensor([[[1.0, 2.0],
                        [1.0, 4.0]],
                       [[1.0, 2.0],
                       [1.0, 3.0]]])
y=torch.inverse(x)
print(y)

输出结果为

tensor([[[ 2.0000, -1.0000],
         [-0.5000,  0.5000]],

        [[ 3.0000, -2.0000],
         [-1.0000,  1.0000]]])

或者用

y=torch.linalg.inv(x)

也可以得到相同的结果

奇异矩阵求逆

import torch
x = torch.FloatTensor([[[1.0, 2.0],
                        [1.0, 2.0]],
                       [[1.0, 2.0],
                       [1.0, 3.0]]])
y=torch.inverse(x)
print(y)

报错:

RuntimeError: inverse_cpu: The diagonal element 2 is zero, the inversion could not be completed because the input matrix is singular.

法1:计算矩阵行列式,计算abs(det)>0的矩阵的逆,删除奇异矩阵。缺点是改变了张量维度。

import torch
from torch.linalg import det
x = torch.FloatTensor([[[1.0, 2.0],
                        [1.0, 2.0]],
                       [[1.0, 2.0],
                       [1.0, 3.0]]])
determinants = torch.det(x)
y =torch.inverse(x[determinants.abs()>0.])
print(y)

输出结果为

tensor([[[ 3., -2.],
         [-1.,  1.]]])

法2:用torch.linalg.pinv()得到奇异矩阵的伪逆矩阵

import torch
x = torch.FloatTensor([[[1.0, 2.0],
                        [1.0, 2.0]],
                       [[1.0, 2.0],
                       [1.0, 3.0]]])
y=torch.linalg.pinv(x)
print(y)

输出结果为

tensor([[[ 0.1000,  0.1000],
         [ 0.2000,  0.2000]],

        [[ 3.0000, -2.0000],
         [-1.0000,  1.0000]]])

自定义求逆函数,仅针对非奇异矩阵

import torch
import numpy as np
from torch.linalg import det
 
def cof1(M,index):
    zs = M[:index[0]-1,:index[1]-1]
    ys = M[:index[0]-1,index[1]:]
    zx = M[index[0]:,:index[1]-1]
    yx = M[index[0]:,index[1]:]
    s = torch.cat((zs,ys),axis=1)
    x = torch.cat((zx,yx),axis=1)
    return det(torch.cat((s,x),axis=0))
 
def alcof(M,index):
    return pow(-1,index[0]+index[1])*cof1(M,index)
 
def adj(M):
    result = torch.zeros((M.shape[0],M.shape[1]))
    for i in range(1,M.shape[0]+1):
        for j in range(1,M.shape[1]+1):
            result[j-1][i-1] = alcof(M,[i,j])
    return result
 
def invmat(M):
    return 1.0/det(M)*adj(M)
    
x = torch.FloatTensor([[1.0, 2.0],
                        [1.0, 4.0]])
print(invmat(x))

输出结果:

tensor([[ 2.0000, -1.0000],
        [-0.5000,  0.5000]])

版权声明:本文为unbekannten原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。