1.1 線性代數

import tensorflow as tf
import numpy as np

標量,就是一個單獨的數

向量,一列數

矩陣,一個二維數組

張量,tensorflow 中,所有變量用張量tensor表示

轉置,行列互變

a = 10  #標量
b = tf.constant(a)   # 0階張量
print(a)
print(b)

A = [1, 2, 3] # 向量
B = tf.constant(A) # 1階張量
print(A)
print(B)

A_ = [[1,2,3], [4,5,6]]  # 矩陣
B_ = tf.constant(A_, dtype=tf.float32)   # 2階張量
print(A_)
print(B_)

B_T = tf.transpose(B_) # 轉置後的張量
print(B_T)

C_ = [[1,2,3], [4,5,6]]  # 矩陣
D_ = tf.constant(C_)   # 2階張量
F = C_ + D_
print(F)
10
Tensor("Const_45:0", shape=(), dtype=int32)
[1, 2, 3]
Tensor("Const_46:0", shape=(3,), dtype=int32)
[[1, 2, 3], [4, 5, 6]]
Tensor("Const_47:0", shape=(2, 3), dtype=float32)
Tensor("transpose_5:0", shape=(3, 2), dtype=float32)
Tensor("add_3:0", shape=(2, 3), dtype=int32)
張量

是tensorflow中的數據管理形式,在tensorflow中所有的數據都通過張量的形式來表示(從上面的例子可以看出來),張量並沒有正真的保存數字,它保存的是如何得到這些數字的計算過程,張量中主要保存三個屬性:名字,維度,類型。

如果想要得到計算結果,需要將張量放在session中運行。

with tf.Session() as sess:
    f = sess.run(F)
    print(f)
    sess.close()
[[ 2  4  6]
 [ 8 10 12]]

矩陣和向量的相乘

最重要的是A(m, n), B(n, k) --> C(m, k) 維度符合才能乘。

M = tf.matmul(B_, B_T)
print(M)
Tensor("MatMul_4:0", shape=(2, 2), dtype=float32)
單位矩陣和逆矩陣
I1 = tf.eye(3)
I2 = tf.eye(2, 3)
print(I1)
print(I2)
M_inv = tf.matrix_inverse(M)  # 逆矩陣,只接收float類型
print(M_inv)
Tensor("eye_10/MatrixDiag:0", shape=(3, 3), dtype=float32)
Tensor("eye_11/MatrixSetDiag:0", shape=(2, 3), dtype=float32)
Tensor("MatrixInverse_2:0", shape=(2, 2), dtype=float32)
線性相關和生成子空間

如果一組向量中的任意一個向量都不能表示成其它向量的線性組合,那麼這組向量稱爲線性無關。

如果某個向量是一組向量中某些向量的線性組合,那麼我們將這個向量加入到這組向量後不會增加這組向量的生成子空間。

範數(衡量一個向量的大小)

xp=(Σxip)1p||x||_p = (\Sigma|x_i|^p )^\frac {1} {p}

直觀上向量x的範數是衡量從原點到點x的距離。

當p = 2時,L2L^2範數被稱爲歐幾里得範數,表述從原點出發到向量x確定點的歐幾里得距離(其實就是所有的值的平方的和的平方根), L2L^2範數在機器學習中用的比較多,主要用在正則化等技術中,後面會有涉及,它可以簡單的通過點積xTxx^Tx計算

L2L^2類似,我們想衡量矩陣大小,在深度學習中常用Frobenius範數,有很多資料將L2L^2LFL^F認爲相同。

當p=1時,L1L^1範數,在機器學習應用中,區分恰好是0的元素和非零但值很小的元素,x1=(xi)||x||_1 = (\sum|x_i| )

當p=0時,L0L^0範數,用來統計向量中非零元素的個數,通過非零元素個數衡量向量大小。

p=p=\propto
時,LL^\propto範數,也稱爲最大範數。表示向量中最大幅值的原色的絕對值。

關於範數,有篇文章寫的比較好,引用一下 https://blog.csdn.net/yangpan011/article/details/79461846

# 我們可以用ord=’euclidean’的參數來調用tf.norm來求歐基裏得範數
a02 = tf.constant([1,2,3,4],dtype=tf.float32)  # 向量
a03 = tf.constant([[1,2],[3,4]],dtype=tf.float32)  # 矩陣
with tf.Session() as sess:   
    L2 = sess.run(tf.norm(a02, ord='euclidean')) # L2範數
    L_F = sess.run(tf.norm(a03, ord=2))  # 矩陣的範數稱爲Frobenius範數
    L1 = sess.run(tf.norm(a03,ord=1))   # L1範數
    L_MAX = sess.run(tf.norm(a03,ord=np.inf))  # L∝範數
    print(L2)
    print(L_F)
    print(L1)
    print(L_MAX)
    sess.close()
5.477226
5.477226
10.0
4.0
特殊類型的矩陣和向量

對角矩陣

對稱矩陣 A=ATA=A^T

單位向量 x=1.||x|| = 1.

正交 xTy=0x^Ty = 0

正交矩陣 ATA=AAT=IA^TA = AA^T = I

特徵分解:

將矩陣分解成一組特徵向量和特徵值

特徵分解的效果

矩陣A有兩個標準的正交的特徵向量,對應的特徵值爲 λ1\lambda_1v(1)v^{(1)}以及特徵值爲 λ2\lambda_2v(2)v^{(2)}, 從圖中可以看出,A將單位圓v(i)v^{(i)}拉伸了λi\lambda_i

所有特徵值都是正數的矩陣稱爲正定

所有特徵值都是非負數的矩陣稱爲半正定

所有特徵值都是負數的矩陣稱爲負定

所有特徵值都是非正數的矩陣稱爲半負定

A = tf.truncated_normal([3, 3])  # 截斷正太分佈,當mean=0, stddev=1時,生成的數在[-2,2](方差的兩倍內)
with tf.Session() as sess:
    print(sess.run(A))
    eigenvalues, eignvectors = sess.run(tf.self_adjoint_eig(A))
    print(eigenvalues)
    print(eignvectors)
    sess.close()
[[-1.2078785  -1.6885282   0.6439421 ]
 [ 0.671624    1.9556671   0.90718263]
 [-1.7275476   0.06104081  1.0154626 ]]
[-0.8078741  0.8497921  1.9737738]
[[-0.06946777 -0.98544115 -0.15517797]
 [-0.4434218   0.16984437 -0.88007396]
 [-0.8936171  -0.00767255  0.44876486]]
奇異值分解(SVD)

將矩陣分解爲奇異向量(singular value)和奇異值(singular vector)

與特徵分解類似,只不過奇異值分解需要將矩陣A分解成三個矩陣的乘積:
A=UDVTA = UDV^T

其中A(m,n), U(m,m), D(m,n), V(n, n)

對角矩陣D對角線上的元素稱爲矩陣A的奇異值,矩陣U的列向量被稱爲左奇異向量,矩陣U的列向量被稱爲右奇異向量。

As =tf.constant( [[1,2,3],[4,5,6]], dtype=tf.float64)
As_svd = tf.svd(As, full_matrices=True)
# full_matrices:如果爲 true,則計算全尺寸的 u 和 v
with tf.Session() as sess:
    print(sess.run(As))
    s,u,v = sess.run(As_svd)
    print(s)
    print(u)
    print(v)
    sess.close()
   
    # s:奇值
    # u:奇左向量
    # v :奇右向量
[[1. 2. 3.]
 [4. 5. 6.]]
[9.508032   0.77286964]
[[-0.3863177  -0.92236578]
 [-0.92236578  0.3863177 ]]
[[-0.42866713  0.80596391  0.40824829]
 [-0.56630692  0.11238241 -0.81649658]
 [-0.7039467  -0.58119908  0.40824829]]
Moore-Penrose僞逆

若有A與其左逆B,有 Ax=yAx=y 以及x=Byx=By, 則則Moore-Penrose僞逆爲A+=VD+UTA^+=VD^+U^T
U,D,V是矩陣A奇異值分解後得到的矩陣,對角矩陣的僞逆D+D^+是其非零元素取倒數之後再轉置得到的。
A 的列數大於行數,得到就是所有可行解中L2L_2範數最小的一個,如果相反,就是Axy||Ax−y||最小。

跡運算

跡運算返回的是矩陣的對角元素的和

Fobenius 範數 AF=Tr(AAT)||A||_F = \sqrt{Tr{(AA^T)}}

x = tf.constant([[1, 2], [3, 4]])
tr = tf.trace(x)  # 5
with tf.Session() as sess:
    print(sess.run(tr))
    sess.close()
5

行列式

det(A),將方陣A映射到實數的函數

主成分分析(PCA) 降維,壓縮

應用:

假設對100100的圖片進行分析,那麼100100=10000個特徵

第一步是將10000個特徵利用PCA壓縮爲1000個特徵

第二部是對訓練集運行學習算法(壓縮後的特徵集)

注意:

PCA只是在訓練集上使用,在交叉和測試集上不適用

訓練最好還是使用原始的特徵,除非算法運行太慢,或者佔用太多內存情況下

原理:

假設有m個點{x(1),...,x(m)x^{(1)},...,x^{(m)}},如果想對這些點進行有損壓縮,減小內存使用,同時希望損失的精度最小。

encode : f(x) = c

decode : x ≈ g(f(x)) 來近似x

我們選g© = Dc, 其中D是定義解碼器的矩陣

爲了又唯一解,限制D中所有列向量都有單位範數

1 、找到encode : 假設最優編碼爲cc^*

c=argminxg(c)22c^* = argmin{||x - g(c)||}_2^2

展開優化後最有得到c=DTxc = D^Tx, 那麼xr(x)=g(c)=Dc=DDTxx≈r(x) = g(c) = Dc = DD^Tx

2、找到decode :

利用Frobenius範數,對所有維度和所有點進行解碼,所以要最小化所有維度所有點的誤差矩陣範數(最小化距離)

D=argmin(xr(x))2=IlD^* = argmin\sqrt{\sum(x - r(x))^2} = I_l
帶入 d=argminx(i)ddTx(i)22=1d^* = argmin{\sum||x^{(i)} - dd^Tx^{(i)}||}_2^2 = 1

所以變成最小化問題 argminXXddT22=argminTr((XXddT)T(XXddT))argmin||X-Xdd^T||^2_2 = argminTr((X-Xdd^T)^T(X-Xdd^T)) (跡運算)

將上面展開,去掉無關項,得到:
argmaxTr(dTXTXd)argmaxTr(d^TX^TXd) subject to dTd=1d^Td = 1
通過特徵分解得到最優的d是XTXX^TX最大的特徵值對應的特徵向量

所以得到decode

類似的降維技術還有t-SNE 和自編碼器

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章