我在评估基础矩阵的特征值/特征向量的梯度方面存在问题。 Tensorflow评估梯度,但这些与分析推导不一致。
我们使用tf.self_adjoint_eig来评估张量流变量输入的频谱分解。我们用对称矩阵初始化它以满足自伴运算符属性。我们希望得到单个特征值或特征向量相对于原始矩阵的导数(对于特征向量的注释,我们从一个特征向量中取一个元素,例如特征向量1中的元素2,以避免现在的梯度聚合问题。)
评估特征值的分析梯度和对称实矩阵的向量的方法可以在论文"关于区分特征值和特征向量"作者:Magnus(1985),Theorem 1 eqn(6)+(7)。我们使用输入矩阵评估了本文下的梯度,并将其与张量流评估的梯度和有限差分近似的梯度进行了比较。对于特征值,梯度是相似的(在对角线条目上相同,在非对角线元素上偏离2倍),然而特征向量在对角线条目之外相当远。首先,定义矩阵A(任何关于在帖子中呈现矩阵的建议都会有所帮助!)
A =
在A上使用np.linalg.eig和tf.self_adjoint_eig(我只是用A初始化变量并计算tf实现的渐变)
张量流特征值:[ - 5.43071561 1.76904987 6.66166575] Python特征值:[ - 5.43071561 6.66166575 1.76904987]
我现在想要评估特征值1(-5.43071561)w.r.t的梯度。甲
分析梯度(Magnus 1985):
Tensorflow梯度:
对角线条目是相同的,但非对角条目明显偏离了2倍。现在我们尝试评估特征向量的渐变。
张量流特征向量:
Python特征向量:
我们尝试找到特征向量1元素2的梯度(+/- 0.32778267)。我们期望张量流梯度等于分析梯度(在考虑符号差异之后)。
分析梯度:
Tensorflow梯度:
除了非对角线上的条目不同之外,一个问题是张量流仅返回梯度的下三角形。尽管A是对称的,但对梯度的贡献不是对称的,如上面的分析评估所示。谢谢你的阅读!
TL:DR,我认为梯度计算不正确。有任何想法或类似经历吗?
下面重现的代码:
import tensorflow as tf
import numpy as np
from numpy.linalg import eig
from numpy.linalg import pinv
#create upper triangular matrix
A_vec = np.array([-3,-2,4,-2,1,1,4,1,5])
A = np.reshape(A_vec,[3,3])
e = eig(A)
#extract eigenvalues and eigenvectors
e_val = e[0]
e_vec = e[1]
#tensorflow variables
A_tf = tf.Variable(tf.constant(A,dtype=tf.float64))
e_tf = tf.self_adjoint_eig(A_tf)
#extract eigenvalues and eigenvectors
e_val_tf = e_tf[0]
e_vec_tf = e_tf[1]
#initialise variables and run session
sess = tf.Session()
sess.run(tf.global_variables_initializer())
#print A
print("A:")
print(A)
#show eigenvalues for Tensorflow and R
print("Tensorflow eigenvalues:",sess.run(e_val_tf))
print("Python eigenvalues:",e_val)
############# Eigenvector element gradient #############
eval_grad_tf = tf.gradients(e_val_tf[0], A_tf) #Tensorflow gradient of first eigenvalue w.r.t. A
#analytical gradient
eigenvec = e_vec[:,0]
#analytical deriv from analytical gradient of eigenvalue from Magnus (1985), "On differentiating
#Eigenvalues and Eigenvectors", Theorem 1 eqn (6)
eval_grad_analytical = np.outer(eigenvec,eigenvec)
print("Analytical gradient:")
print(eval_grad_analytical)
print("Tensorflow gradient:")
print(sess.run(eval_grad_tf))
############# Eigenvector element gradient #############
print("Tensorflow eigenvectors:")
print(sess.run(e_vec_tf))
print("Python eigenvectors:")
print(e_vec)
#tensorflow gradient
evec_grad_tf = tf.gradients(e_vec_tf[1,0], A_tf)
#analytical gradient
#analytical deriv from analytical gradient of eigenvalue from Magnus (1985), "On differentiating
#Eigenvalues and Eigenvectors", Theorem 1 eqn (7)
evec_grad_analytical = np.kron(eigenvec, pinv(e_val[0]*np.eye(3)-A)) #calculates derivatives for each component of eigenvector 3
evec_grad_analytical1 = np.reshape(evec_grad_analytical[1,:],[3,3]) #retrieves column 2 which should correspond to the gradient of eigenvector 3 element 2 w.r.t. A
print("Analytical gradient:")
print(evec_grad_analytical1)
print("Tensorflow gradient:")
print(sess.run(evec_grad_tf))