Tensorflow快餐教程(6) - 矩陣分解

摘要: 特徵分解,奇異值分解,Moore-Penrose廣義逆網絡

矩陣分解

特徵向量和特徵值
咱們在《線性代數》課學過方陣的特徵向量和特徵值。機器學習

定義:設A∈Fn×n是n階方陣。若是存在非零向量X∈Fn×1使AX=λX對某個常數λ∈F成立,則稱λ是A的特徵值(eigenvalue),X是屬於特徵值λ的特徵向量。
設σ是數域F上向量空間V上的線性變換,若是某個非零向量u∈V被σ映射到本身的常數倍σ(u)=λu,則稱常數λ∈F是σ的特徵值,向量u是屬於特徵值λ的特徵向量。函數

又找λ又找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例:code

> 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。get

特徵分解
咱們把用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(λ)V−1
按照上面公式方法對矩陣A所作的操做叫作A的特徵分解(eigen decomposition)it

不是每個矩陣均可以分解成特徵值和特徵向量。在某些狀況下,特徵分解存在,可是值是複數而不是實數。幸運的是,機器學習中遇到的方陣基本均可以分解成A=QΛQT,其中Q是特徵向量構成的正交矩陣,Λ是對角矩陣。io

奇異值分解

對於多數方陣,咱們能夠進行特徵值分解。若是對於非方陣該怎麼辦呢?答案是咱們有相似的奇異向量(Singular vector)和奇異值(singular value). 經過奇異向量和奇異值,咱們能夠把非方陣進行奇異值分解(singular value decomposition),簡稱svd.
SVD將矩陣分解爲三個矩陣的乘積:A=UDVT。其中,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α→0(ATA+αI)−1AT
這個定義在計算時是無法使用的,咱們使用另外一個公式來算
A+=VD+UT
這個公式一看太熟悉了,就是剛纔咱們學習的奇異值分解嘛。
其中D+,D的廣義逆的計算方法是全部非0值取倒數,而後矩陣轉置。

對於一個AX=B方程組的最小二乘法解,通常來說不是惟一的。一般把它們中2-範數最小的一個稱爲極小最小二乘解,也叫最佳逼近解。
能夠證實,AX=B必有惟一的極小最小二乘解,這個解就是X=A+B
廣義逆簡史
首先複習一下逆陣的概念,若是一個矩陣有逆陣,條件爲:

  1. 必須是方陣
  2. 行列式不能爲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−廣義逆等。

做者:lusing

原文連接

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索