2017-02-28 541 views
4

我正在寻找一种在tensorflow中替代numpy.linalg.pinv。 到目前为止,我发现tensorflow只有tf.matrix_inverse(input, adjoint=None, name=None),如果矩阵不可逆,它将引发错误。tensorflow中的numpy.linalg.pinv的替代

+0

如果矩阵不可逆,您可以选择使用正则化。 –

+0

@NikolasRieble,请提供示例 – Rahul

+0

'pinv()'基于SVD,而Tensorflow具有SVD功能......我不打算提供示例:) – gboffi

回答

1

我不知道numpy.linalg.pinv在tensorflow中的替代品,但正则化是在矩阵不可逆时的替代方案。一个例子:

try: 
    result = tf.matrix_inverse(input, adjoint=None, name=None) 
except: 
    input += np.identity((input.shape))* c 
    result = tf.matrix_inverse(input, adjoint=None, name=None) 

其中c是常数,并且应该是很小的例如c = 0.000001

然而矩阵求逆是相当昂贵的计算,只应如果neccesary完成。欲了解更多信息,请参阅:do not invert that matrix

+1

如果OP有扩展最终评论他们可以按照'x←pinv(A)@ b'(OP暗示的路线)或(根据你的建议)找到'x',他们可以按如下方式进行:'b ^←AT @ b','A ^←AT @ A'并使用例如LU分解,线性系统_'A^x = b ^'_ – gboffi

2

TensorFlow提供了一个SVD运算,所以你可以很容易地计算从伪逆:

def pinv(A, b, reltol=1e-6): 
    # Compute the SVD of the input matrix A 
    s, u, v = tf.svd(A) 

    # Invert s, clear entries lower than reltol*s[0]. 
    atol = tf.reduce_max(s) * reltol 
    s = tf.boolean_mask(s, s > atol) 
    s_inv = tf.diag(tf.concat([1./s, tf.zeros([tf.size(b) - tf.size(s)])], 0)) 

    # Compute v * s_inv * u_t * b from the left to avoid forming large intermediate matrices. 
    return tf.matmul(v, tf.matmul(s_inv, tf.matmul(u, tf.reshape(b, [-1, 1]), transpose_a=True))) 
+0

+1,这应该是被接受的答案。但是,也许让'b'可选?除了计算A + * b之外,用户可能需要伪逆来达到其他目的。 – MiniQuark