当前位置:   article > 正文

pytorch对矩阵(奇异和非奇异)求逆_linalg.inv: the diagonal element 2 is zero, the in

linalg.inv: the diagonal element 2 is zero, the inversion could not be compl

非奇异矩阵求逆

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

输出结果为

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

        [[ 3.0000, -2.0000],
         [-1.0000,  1.0000]]])
  • 1
  • 2
  • 3
  • 4
  • 5

或者用

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

报错:

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

法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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

输出结果为

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

法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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

输出结果为

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

        [[ 3.0000, -2.0000],
         [-1.0000,  1.0000]]])
  • 1
  • 2
  • 3
  • 4
  • 5

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

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))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

输出结果:

tensor([[ 2.0000, -1.0000],
        [-0.5000,  0.5000]])
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/96607
推荐阅读
相关标签
  

闽ICP备14008679号