tf 如何进行svd_Tensorflow快餐教程(6) - 矩阵分解-阿里云开发者社区

矩阵分解

特征向量和特征值

我们在《线性代数》课学过方阵的特征向量和特征值。

定义:设$A{\in}F^{n{\times}n}$是n阶方阵。如果存在非零向量$X{\in}F^{n{\times}1}$使$AX={\lambda}X$对某个常数${\lambda\in}F$成立,则称$\lambda$是A的特征值(eigenvalue),X是属于特征值${\lambda}$的特征向量。

设$\sigma$是数域F上向量空间V上的线性变换,如果某个非零向量$u{\in}V$被$\sigma$映射到自己的常数倍$\sigma(u)={\lambda}u$,则称常数$\lambda\in{F}$是$\sigma$的特征值,向量u是属于特征值$\lambda$的特征向量。

又找$\lambda$又找A确实不是一件容易事。好在,我们可以把这事儿交给Tensorflow去解决。我们可以用tf.self_adjoint_eigvals来求特征值,相当于MATLAB的eig函数,只不过名字长了点。

例:

>>> A1 = tf.constant([[3,2,1],[0,-1,-2],[0,0,3]],dtype=tf.float64)

>>> sess.run(A1)

array([[ 3., 2., 1.],

[ 0., -1., -2.],

[ 0., 0., 3.]])

>>> sess.run(tf.self_adjoint_eigvals(A1))

array([-1., 3., 3.])

附:MATLAB例:

> A1 = [3,2,1;0,-1,-2;0,0,3]

A1 =

3 2 1

0 -1 -2

0 0 3

> eig(A1)

ans =

3

-1

3

也就是说,A1矩阵有3个特征值-1,3,3。

特征分解

我们把用self_adjoint_eigvals求出来的向量转换成对角矩阵:

>>> sess.run(tf.diag(tf.self_adjoint_eigvals(A1)))

array([[-1., 0., 0.],

[ 0., 3., 0.],

[ 0., 0., 3.]])

同样,我们把每个特征向量组成一个矩阵,假设为V.

这样,我们可以得到一个公式:$A = Vdiag(\lambda)V^{-1}$

按照上面公式方法对矩阵A所做的操作叫做A的特征分解(eigen decomposition)

不是每一个矩阵都可以分解成特征值和特征向量。在某些情况下,特征分解存在,但是值是复数而不是实数。幸运的是,机器学习中遇到的方阵基本都可以分解成$A=Q{\Lambda{Q^T}}$,其中Q是特征向量构成的正交矩阵,$\Lambda$是对角矩阵。

奇异值分解

对于多数方阵,我们可以进行特征值分解。如果对于非方阵该怎么办呢?答案是我们有类似的奇异向量(Singular vector)和奇异值(singular value). 通过奇异向量和奇异值,我们可以把非方阵进行奇异值分解(singular value decomposition),简称svd.

SVD将矩阵分解为三个矩阵的乘积:$A=UDV^T$。其中,U和V都定义为正交矩阵。D是对角矩阵,虽然不一定是方阵。

如果A是一个mn的矩阵,那么U是一个mm的矩阵,V是一个nn的矩阵,D与A一样是mn的矩阵。

我们可以通过tf.svd函数来做奇异值分解,例:

>>> As =tf.constant( [[1,2,3],[4,5,6]], dtype=tf.float64)

>>> sess.run(As)

array([[1., 2., 3.],

[4., 5., 6.]])

>>> sess.run(tf.svd(As, full_matrices=True))

(array([9.508032 , 0.77286964]), array([[-0.3863177 , -0.92236578],

[-0.92236578, 0.3863177 ]]), array([[-0.42866713, 0.80596391, 0.40824829],

[-0.56630692, 0.11238241, -0.81649658],

[-0.7039467 , -0.58119908, 0.40824829]]))

As矩阵是23的矩阵。所以U是22的,而V是3*3的。第1个值是奇异值,[9.508032 , 0.77286964],它是D的对角线上值,其它位置为0.

D的完整值为:

array([[9.508032 , 0. , 0. ],

[0. , 0.77286964, 0. ]])

三个矩阵的完整值为:

#U

array([[-0.3863177 , -0.92236578],

[-0.92236578, 0.3863177 ]])

#D

array([[9.508032 , 0. , 0. ],

[0. , 0.77286964, 0. ]])

#V

array([[-0.42866713, 0.80596391, 0.40824829],

[-0.56630692, 0.11238241, -0.81649658],

[-0.7039467 , -0.58119908, 0.40824829]])

我们来验算一下这个奇异值分解是不是正确的,别忘了V是要转置的:

>>> sess.run(U @ D @ tf.transpose(V))

array([[0.99999997, 1.99999999, 2.99999997],

[3.99999997, 5.00000001, 5.99999996]])

虽然是有点浮点计算误差,但是结果还确实是我们分解前的那个。关于计算误差的问题,在机器学习中也自然是重要问题,后面会讨论。

Moore-Penrose广义逆

铺垫了这么多,其实我们是在为解线性方程组奋斗。我们在第一节Tensorflow的线性回归例子,还有神经网络的例子都看到,求解线性方程组是重要的运算。

形如Ax=b的线性方程组,如果A有逆矩阵就好办了,两边分别右乘A逆就可以解出方程组。

但是问题是,机器学习中有很多方程是欠定的(underdetermined)。

这时候我们就需要一种类似于逆矩阵的工具 - Moore-Penrose广义逆(pseudoinverse)。

Moore-Penrose广义逆定义如下:

$A^+=lim_{\alpha\rightarrow{0}}(A^TA+\alpha{I})^{-1}A^T$

这个定义在计算时是没法使用的,我们使用另一个公式来算

$A^+=VD^+U^T$

这个公式一看太熟悉了,就是刚才我们学习的奇异值分解嘛。

其中$D^+$,D的广义逆的计算方法是所有非0值取倒数,然后矩阵转置。

对于一个AX=B方程组的最小二乘法解,一般来讲不是唯一的。通常把它们中2-范数最小的一个称为极小最小二乘解,也叫最佳逼近解。

可以证明,AX=B必有唯一的极小最小二乘解,这个解就是$X=A^+B$

广义逆简史

首先复习一下逆阵的概念,如果一个矩阵有逆阵,条件为:

必须是方阵

行列式不能为0

美国数学家Moore于1920年逆矩阵的概念推广到任意矩阵上,使用的方法是正交投影算子来定义的。

1955年,英国数学家Penrose用下面的方程组来定义广义逆:

$AGA=A, GAG=G, (AG)^H=AG (GA)^H=GA$

其中,H这个符号代表矩阵共轭的转置,对于实数就相当于T。

不久之后,瑞典大地测量学家Arne Bjerhammer证明了Moore广义逆与Penrose广义逆的等价性。所以把它定义为Moore-Penrose广义逆。除了$A+$之外,还有$A^-$广义逆等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值