张量和线性代数基础
这是本人在暑期学习中对有关张量网络算法知识的一些梳理,有什么错误请大家批评指正,喜欢的给点个赞。
一、张量基础
1. 张量的定义
0阶张量(点)----标量(scalar):0
1阶张量(线)----向量(vector):[1,2,3,4,5]
2阶张量(面)----矩阵(matrix):
[
1
0
2
1
]
\left[\begin{array}{ll}1 & 0 \\2 & 1\end{array}\right]
[1201]
3阶张量(体)----张量(tensor):[[[1,2,3],[4,5,6],[7,8,9]],[[1,2,3],[4,5,6],[7,8,9]],[[1,2,3],[4,5,6],[7,8,9]]]
这样子看起来不是很直观,张量的图形表示更加直观,如下图。从图中我们可以看出,0阶张量就是一个点,就像一个天安门站岗的士兵;1阶张量就是N多个0阶张量排成一行,就像天安门的升国旗对的士兵们排成的一列队伍;2阶张量就像阅兵时那些军人们排出的一个阵列;3阶张量就像每个军区的不同兵种排成的一个大阵列以此类推,N阶张量就是按照如上规律继续进行排列。
按照上面张量的表示方法,当张量的阶数越高,表示也会越麻烦,于是另外一种用bond来表示阶数的图形表示则会更加简洁,如下图。张量用连着N个腿(bond)的圆圈、方块或者其它图形来表示,每一条腿代表张量的一个阶,N条腿就代表张量有N阶。注意:腿的形状不影响张量的阶数
2. 张量的基本操作和运算
张量可进行切片操作提取相关的元素,以三阶张量为例,如图。切片操作就是在张量中抽取矩阵的操作,保留两个维度的变化。这个方式可能不太好理解,也或多或少有点绕(要是你不觉得绕,当我没说)。
换一种理解方式,我们可以理解为对一个维度进行切割,就像Frontal slices是对 n 3 n_{3} n3这个维度进行切割,Horizontal slices是对 n 1 n_{1} n1这个维度进行切割,Lateral slices是对 n 2 n_{2} n2这个维度进行切割,就像我们平时切豆腐,可以对三个不同的维度进行切割,这一块主要是理解记忆。
切片之后张量的展开自然是不能少的,张量展开通俗点来讲就是把切片之后的张量一片一片拼凑起来,拼凑方式有下图三种,可以 n 1 n_{1} n1维度进行拼接,可以 n 2 n_{2} n2维度进行拼接,也可以 n 3 n_{3} n3维度进行拼接。
有没有点点的混乱,下面上我们带有数字和颜色的图,配上下图是不是感觉好多了。
张量的基本运算主要有以下几个:
向量的内积:
C
=
∑
a
x
a
y
a
C=\sum_{a} x_{a} y_{a}
C=a∑xaya
向量乘矩阵:
v
b
=
∑
a
x
a
M
a
b
=
x
M
v_{b}=\sum_{a} x_{a} M_{a b}=x M
vb=a∑xaMab=xM
矩阵乘矩阵:
M
a
c
=
∑
b
A
a
b
B
b
c
=
A
B
M_{a c}=\sum_{b} A_{a b} B_{b c}=A B
Mac=b∑AabBbc=AB
张量的缩并:
T
a
c
d
e
=
∑
b
A
a
b
c
B
b
d
e
T_{a c d e}=\sum_{b} A_{a b c} B_{b d e}
Tacde=b∑AabcBbde
由下面的图我们很容易可以看出,只要下标相同,我们就可以把它们缩并,这也是张量运算的核心所在,后面还会遇到很多类似的情况。
二、线性代数基础
1. 本征值分解与最大本征值问题
本征值分解
本征向量与本征值又称特征向量与特征值,相信学过线性代数的小伙伴是不会陌生的。对于给定D × D的方阵M, 设D维归一化向量
v
v
v与标量
λ
\lambda
λ ,当其满足
M
v
=
λ
v
\boldsymbol{M} \boldsymbol{v}=\boldsymbol{\lambda} \boldsymbol{v}
Mv=λv 时,称
v
v
v与
λ
\lambda
λ分别为M的本征向量与本征值。本征值分解,又称特征分解(eigenvalue decomposition ) ,满足:
M
=
U
Γ
U
+
M=U \Gamma U^{+}
M=UΓU+
其中 U被称为变换矩阵,其每一列为M的本征向量,且满足正交归一性 U U † = I ; Γ U U^{\dagger}=I ; \Gamma UU†=I;Γ 为对角矩阵,称为本征谱。
最大本征值问题
假设矩阵本征值为实数,求解给定矩阵的最大本征值及其本征态。最大本征值问题对应的优化问题就是对于给定的矩阵
M
M
M,求解归一化向量
v
v
v,使得函数
f
=
∣
v
T
M
v
∣
\mathrm{f}=\left|\mathrm{v}^{\mathrm{T}} \mathrm{Mv}\right|
f=∣∣vTMv∣∣ 的值极大化,f 对应最大的本征值的绝对值。此证明采用数值证明法,要是小伙伴有其它的好方法评论区留言哦!
数值证明的代码实现:
import numpy as np
import copy
import matplotlib.pyplot as plt#画图
dim=4
M=np.random.randn(dim,dim)
M=M+M.T #对称化保证本征分解存在
print(M)
#求本征值和本征向量
lm,u=np.linalg.eig(M)
print("Eigenvalues:\n",lm)
print("Eigenvectors:\n",u)
#求绝对值最大的本征值及其对应的本征向量
n_max=np.argmax(abs(lm))
lm_max=lm[n_max]
v_max=u[:,n_max]
print(v_max)
#f=vMv'
f_max=abs(v_max.dot(M).dot(v_max))
print(f_max)
#随机建立多个归一化向量
num_v=200
vecs=np.random.randn(num_v,dim)
vecs=np.einsum('na,n->na',vecs,1/np.linalg.norm(vecs,axis=1))
#计算每个向量的f
f=abs(np.einsum('na,ab,nb->n',vecs,M,vecs.conj()))
#print(np.ones(num_v,))
#画图展示最大本征值
x=np.arange(num_v)
y=np.ones(num_v,)*f_max
plt.plot(x,y,'-')
plt.plot(x,f,'r')
plt.show()
随机建立200个归一化向量所得到的结果,由图可以看出,当随机生成的归一化向量越多,向量的本征值会越来越靠近最大本征值的绝对值,但永远不会大于最大本征值的绝对值。
num_v=200 | num_v=600 |
最大本征值问题的幂级数求解法
考虑实对称矩阵
M
M
M,设
Γ
\Gamma
Γ和u
(
0
)
^{(0)}
(0) 为其绝对值最大的唯一本征值及本征向量,则
lim
K
→
∞
M
K
=
Γ
0
K
u
(
0
)
u
(
0
)
T
\lim _{K \rightarrow \infty} M^{K}=\Gamma_{0}^{K} u^{(0)} u^{(0) T}
K→∞limMK=Γ0Ku(0)u(0)T
证明:
设M的本征值分解为M
=
U
Γ
U
T
,
=U \Gamma U^{T}, \quad
=UΓUT,
有
M
K
=
U
Γ
U
T
U
Γ
U
T
…
U
Γ
U
T
M^{K}=U \Gamma U^{T} U \Gamma U^{T} \ldots U \Gamma U^{T}
MK=UΓUTUΓUT…UΓUT
由
U
U
T
=
U
T
U
=
I
\mathrm{由} U U^{T}=U^{T} U=I
由UUT=UTU=I 得,
M
K
=
U
Γ
K
U
T
=
Γ
i
K
U
(
Γ
Γ
i
)
K
U
T
\quad M^{K}=U \Gamma^{K} U^{T}=\Gamma_{i}^{K} U\left(\frac{\Gamma}{\Gamma_{i}}\right)^{K} U^{T}
MK=UΓKUT=ΓiKU(ΓiΓ)KUT
令
Γ
i
=
Γ
0
\Gamma_{\mathrm{i}}=\Gamma_{0}
Γi=Γ0
则
lim
K
→
∞
(
Γ
Γ
0
)
K
=
lim
K
→
∞
[
Γ
0
/
Γ
0
⋯
0
⋮
⋱
⋮
0
⋯
Γ
D
−
1
/
Γ
0
]
∗
∗
K
=
diag
(
[
1
0
\lim _{K \rightarrow \infty}\left(\frac{\Gamma}{\Gamma_{0}}\right)^{K}=\lim _{K \rightarrow \infty}\left[\begin{array}{ccc}\Gamma_{0} / \Gamma_{0} & \cdots & 0 \\ \vdots & \ddots & \vdots \\ 0 & \cdots & \Gamma_{D-1} / \Gamma_{0}\end{array}\right] * * \mathrm{K}=\operatorname{diag}([1 \quad 0
limK→∞(Γ0Γ)K=limK→∞⎣⎢⎡Γ0/Γ0⋮0⋯⋱⋯0⋮ΓD−1/Γ0⎦⎥⎤∗∗K=diag([10
得
lim
k
→
∞
M
x
=
Γ
0
z
U
[
1
⋯
0
⋮
⋱
⋮
0
⋯
0
]
U
T
=
U
[
1
⋯
0
⋮
⋱
⋮
0
⋯
0
]
[
1
⋯
0
⋮
⋱
⋮
0
⋯
0
]
U
T
=
Γ
0
K
u
(
0
)
u
(
0
)
T
\lim _{k \rightarrow \infty} \mathrm{M}^{\mathrm{x}}=\Gamma_{0}^{\mathrm{z}} \mathrm{U}\left[\begin{array}{ccc}1 & \cdots & 0 \\ \vdots & \ddots & \vdots \\ 0 & \cdots & 0\end{array}\right] \mathrm{U}^{\mathrm{T}}=\mathrm{U}\left[\begin{array}{lll}1 & \cdots & 0 \\ \vdots & \ddots & \vdots \\ 0 & \cdots & 0\end{array}\right]\left[\begin{array}{ccc}1 & \cdots & 0 \\ \vdots & \ddots & \vdots \\ 0 & \cdots & 0\end{array}\right] \mathrm{U}^{\mathrm{T}}=\Gamma_{0}^{\mathrm{K}} \mathrm{u}^{(0)} \mathrm{u}^{(0) T}
limk→∞Mx=Γ0zU⎣⎢⎡1⋮0⋯⋱⋯0⋮0⎦⎥⎤UT=U⎣⎢⎡1⋮0⋯⋱⋯0⋮0⎦⎥⎤⎣⎢⎡1⋮0⋯⋱⋯0⋮0⎦⎥⎤UT=Γ0Ku(0)u(0)T
证毕
最大本征值问题的幂级数求解法的代码实现:
#使用scipy中的eigs求最大几个本征值和本征向量
import numpy as np
import scipy.sparse.linalg as la
import copy
dim=4
M=np.random.randn(dim,dim)#随机生成4×4的张量
M=M+M.T
lm1,v1=la.eigs(M,k=1,which='LM')#求最大的本征值和本征向量
print(lm1)
print(M)
#最大本征值问题的幂级数求解法:
def eig0(mat,it_time=1000,tol=1e-15):
v1=np.random.randn(mat.shape[0],)
v0=copy.deepcopy(v1)
lm=1
for n in range(it_time):
v1=mat.dot(v0)
lm=np.linalg.norm(v1)#求本征值
v1/=lm #归一化
#判断是否收敛
conv=np.linalg.norm(v1-v0)
if conv<tol:
break
else:
v0=copy.deepcopy(v1)
return lm,v1
lm2,v2=eig0(M)
print(lm2)
print(v2.reshape(-1,))
2. 奇异值分解与最优低秩近似问题
注意这个很重要,后面会有很多很多和这个有关的知识点。
奇异值分解(SVD)
奇异值分解(singular value decomposition):给定D × D’的矩阵M,有
M
=
U
Λ
V
†
M=U \Lambda V^{\dagger}
M=UΛV†
其中
U
U
U 与V每一列分别被称为
M
M
M 的左、右奇异向量,且满足正交归一性
U
U
†
=
I
,
V
V
†
=
I
U U^{\dagger}=I, \quad V V^{\dagger}=I
UU†=I,VV†=I
Λ
\Lambda
Λ 为非负定实对角矩阵,称为奇异谱, 其元素称为奇异值。矩阵的非零奇异值个数定义为矩阵的秩。类似于本征值分解,但是进行奇异值分解的矩阵可以不是方阵。如图所示:
矩阵的低秩近似问题
给定
D
×
D
′
D \times D^{\prime}
D×D′ 的矩阵M,设其秩为
R
R
R 求解秩为
R
′
R^{\prime}
R′ 的矩阵
M
′
M^{\prime}
M′ 有
R
>
R
′
>
0
R>R^{\prime}>0
R>R′>0 且极小化二矩阵间的范数
ε
=
∣
∣
M
−
M
′
∣
∣
=
∑
i
j
(
M
i
j
−
M
i
j
′
)
2
∼
∥
Λ
R
′
:
R
−
1
∥
(
裁剪误差
)
\varepsilon=|| M-M^{\prime}||=\sqrt{\sum_{i j}\left(M_{i j}-M_{i j}^{\prime}\right)^{2} \sim\left\|\Lambda_{R^{\prime}: R-1}\right\|}(\text { 裁剪误差 })
ε=∣∣M−M′∣∣=ij∑(Mij−Mij′)2∼∥ΛR′:R−1∥( 裁剪误差 )
低秩近似问题的最优解为:
M
′
=
U
[
:
,
0
:
R
′
]
∧
[
0
:
R
′
,
0
:
R
′
]
V
[
:
,
0
:
R
′
]
†
M^{\prime}=U\left[:, 0: R^{\prime}\right] \wedge\left[0: R^{\prime}, 0: R^{\prime}\right] \quad V\left[:, 0: R^{\prime}\right]^{\dagger}
M′=U[:,0:R′]∧[0:R′,0:R′]V[:,0:R′]†
代码实现:
import numpy as np
import matplotlib.image as pimg
import matplotlib.pyplot as plt
img=pimg.imread('C:/Users/86177/Pictures/Saved Pictures/ice.jpg')#导入图片
img=np.sum(img,axis=2) /3 #设置为灰度图片
print('shape of the image data = '+str(img.shape))
plt.imshow(img)
plt.show()
import scipy.sparse.linalg as la
#进行图片SVD分解
def img_compress(img,k):
u,lm,v=la.svds(img,k=k)
img1=u.dot(np.diag(lm)).dot(v)
num_para=2*k*u.shape[0]
#print(num_para)
return img1,num_para
for k in range(10,100,40):
img1,num_para=img_compress(img,k)
plt.imshow(img1)
plt.show()
#进行奇异值分解后的相对误差
print('error = '+str(np.linalg.norm(img-img1)/np.linalg.norm(img)))
print('k = ',k)
由图可以看出当特征值取10个时图片很模糊,此时裁剪误差约13.9%;当特征值取50个时图片肉眼可见整理构图元素,此时裁剪误差约5.2%;当特征值取90个时图片很清晰,此时裁剪误差约3.2%,此时误差已经很小并且图片清晰度很高。可以采用此算法进行图片压缩从而减少所占存储空间。
高阶奇异值分解
高阶奇异值分解(简称HOSVD),又称Tucker分解
T
a
b
c
=
∑
i
j
k
G
i
j
k
U
a
i
V
b
j
W
c
k
T_{a b c}=\sum_{i j k} G_{i j k} U_{a i} V_{b j} W_{c k}
Tabc=ijk∑GijkUaiVbjWck
变换矩阵满足正交性
U
U
T
=
V
V
T
=
W
W
T
=
I
U U^{T}=V V^{T}=W W^{T}=I
UUT=VVT=WWT=I
张量G被称为核张量。定义G的键约化矩阵,以指标
i
i
i为例,其键约化矩阵定义为:
J
i
i
′
=
∑
j
k
G
i
j
k
G
i
′
j
k
J_{i i^{'}}=\sum_{j k} G_{i j k} G_{i^{'}j k}
Jii′=jk∑GijkGi′jk
高阶奇异值分解算法
a.计算各指标的键约化矩阵(相同的指标进行缩并处理):
I
a
a
′
=
∑
j
k
T
a
b
c
T
a
′
b
c
J
b
b
′
=
∑
i
k
T
a
b
c
T
a
b
′
c
K
c
c
′
=
∑
i
j
T
a
b
c
T
a
b
c
′
\begin{aligned} I_{a a^{\prime}} &=\sum_{j k} T_{a b c} T_{a^{\prime} b c} \\ J_{b b^{\prime}} &=\sum_{i k} T_{a b c} T_{a b^{\prime} c} \\ K_{c c^{\prime}} &=\sum_{i j} T_{a b c} T_{a b c^{\prime}} \end{aligned}
Iaa′Jbb′Kcc′=jk∑TabcTa′bc=ik∑TabcTab′c=ij∑TabcTabc′
b.计算每个键约化矩阵的本征值分解:
I
=
U
Ω
U
T
I=U \Omega U^{T}
I=UΩUT
J = V ∏ V T J=V \prod V^{T} J=V∏VT
K = W Υ W T K=W\Upsilon W^{T} K=WΥWT
c.计算核张量:
G
i
j
k
=
∑
a
b
c
T
a
b
c
U
a
i
V
b
j
W
c
k
G_{i j k}=\sum_{a b c} T_{a b c} U_{a i} V_{b j} W_{c k}
Gijk=abc∑TabcUaiVbjWck
最终得到高阶奇异值分解:
T
a
b
c
=
∑
i
j
k
G
i
j
k
U
a
i
V
b
j
W
c
k
T_{a b c}=\sum_{i j k} G_{i j k} U_{a i} V_{b j} W_{c k}
Tabc=ijk∑GijkUaiVbjWck
有没有感觉奇异值分解也不是很难呢?
本人资质愚钝,我刚开始其实也是学了大概1 or 2个月才弄明白,如果没有懂,可以多查查资料或者欢迎评论区见。反正每天多思考,久而久之不懂的地方自然也就明白了。
2. 多线性代数中的张量单秩问题
记第n个左、右 奇异向量分别为u
(
n
)
^{(n)}
(n) 和
v
(
n
)
v^{(n)}
v(n) 证明如下等式:
∑
a
u
a
(
n
)
M
a
b
=
Λ
(
n
)
v
b
(
n
)
∑
b
M
a
b
v
b
(
n
)
=
Λ
(
n
)
u
a
(
n
)
\begin{array}{l} \sum_{a} u_{a}^{(n)} M_{a b}=\Lambda^{(n)} v_{b}^{(n)} \\ \sum_{b} M_{a b} v_{b}^{(n)}=\Lambda^{(n)} u_{a}^{(n)} \end{array}
∑aua(n)Mab=Λ(n)vb(n)∑bMabvb(n)=Λ(n)ua(n)
其中,
Λ
(
n
)
\quad \Lambda^{(n)}
Λ(n) 为第n个奇异值,
\quad
且有
Λ
(
n
)
=
∑
a
b
u
a
(
n
)
M
a
b
v
b
(
n
)
\Lambda^{(n)}=\sum_{a b} u_{a}^{(n)} M_{a b} v_{b}^{(n)}
Λ(n)=ab∑ua(n)Mabvb(n)
计算最大奇异值及奇异向量的迭代算法(和矩阵的幂级数算法有点类似,不懂可以往前再看看哦!):
(a)随机初始化归一向量u和v;
(b) 利用第一个式子,计算u和M的收缩并归一化,更新v,归一化因子记为
Λ
\Lambda
Λ
(c)利用第二个式子,计算v和M的收缩并归一化,更新u, 归一化因子记为
Λ
\Lambda
Λ
(d)如果u和v(以及
Λ
\Lambda
Λ ) 收剑,则返回u、v和
Λ
\Lambda
Λ; 否则,返回执行步骤
(b)最后我们会发现u和v刚好对应于M最大左、右奇异向量, 对应最大的奇异值。
将上述自洽方程组推广到高阶张量,得到如下自洽方程组(以三阶张量为例):
∑
a
b
T
a
b
c
u
a
v
b
=
Λ
w
c
\sum_{a b} T_{a b c} u_{a} v_{b}=\Lambda w_{c}
ab∑Tabcuavb=Λwc
∑ a c T a b c u a w c = Λ v b \sum_{a c} T_{a b c} u_{a} w_{c}=\Lambda v_{b} ac∑Tabcuawc=Λvb
∑ b c T a b c v b w c = Λ u a \sum_{b c} T_{a b c} v_{b} w_{c}=\Lambda u_{a} bc∑Tabcvbwc=Λua
u、v和w为归一化向量,方程组成立时满足:
Λ
=
∑
a
b
c
T
a
b
c
u
a
v
b
w
c
\Lambda=\sum_{a b c} T_{a b c} u_{a} v_{b} w_{c}
Λ=abc∑Tabcuavbwc
其被称为rank-1分解,迭代求解的方法与二阶张量相同。
我学习张量有关的知识也不是很久,有很多东西也不懂。我是一只正在不断学习、希望早日成为小白的小小白,这是我第一次写博客,有什么错误欢迎大家批评指正,喜欢的请点个赞哦!