(3)多线性代数基础

1.多线性代数中的张量单秩分解

1.1 多线性代数又称张量分解

思考:矩阵(二阶张量)存在本征值分解、奇异值分解等,对于更高阶的张量,是否存在类似的分解?
举例:考虑矩阵 M M M(简要起见设 M M M为实矩阵)的奇异值分解,记第 n n n个左、右奇异向量分别为 u ( n ) u^{(n)} u(n) v ( n ) v^{(n)} v(n),证明如下等式:
已知奇异值分解 M = U Λ V † M = U\Lambda V^\dag M=UΛV
——将 M M M与第 n n n个左奇异向量做矩阵乘(缩并),得到的刚好是第 n n n个奇异值乘上第 n n n个右奇异值向量:
∑ a u a ( n ) M a b = Λ ( n ) v b ( n ) \sum_a u_a^{(n)}M_{ab} = \Lambda^{(n)}v_b^{(n)} aua(n)Mab=Λ(n)vb(n)
用图形表示为:
在这里插入图片描述
——将 M M M与第 n n n个右奇异向量做矩阵乘(缩并),得到的刚好是第 n n n个奇异值乘上第 n n n个左奇异值向量:

∑ b M a b v b ( n ) = Λ ( n ) u a ( n ) \sum_b M_{ab}v_b^{(n)} = \Lambda^{(n)}u_a^{(n)} bMabvb(n)=Λ(n)ua(n)
用图形表示为:
在这里插入图片描述
其中, Λ ( n ) \Lambda^{(n)} Λ(n)为第 n n n个奇异值,且有 Λ ( n ) = ∑ a b u a ( n ) M a b v b ( n ) \Lambda^{(n)} = \sum_{ab} u_a^{(n)}M_{ab}v_b^{(n)} Λ(n)=abua(n)Mabvb(n)
提示:利用变换矩阵的正交性

1.1.1 代码实例

import numpy as np

#验证第n组左右奇异向量与奇异值满足自洽方程

dim = 4
M = np.random.randn(dim,dim) #随机生成矩阵
U,S,V = np.linalg.svd(M) #进行svd分解,存储左右奇异矩阵和奇异值
n = 2 #检查第n个组左右奇异向量
u = U[:,n]
s = S[n]
v = V[n,:]
print(s*v) #第2个奇异值乘以第二个右奇异向量
print(u.dot(M))#第2个左奇异向量乘以矩阵

1.2 计算最大奇异值及奇异向量的迭代算法

类似于矩阵的幂级数算法
(a)随机初始化归一向量 u u u v v v
(b)利用下面式子,计算 u u u M M M的收缩并归一化,更新 v v v,归一化因子记为 Λ \Lambda Λ
∑ a u a M a b = Λ v b \sum_a u_aM_{ab} = \Lambda v_b auaMab=Λvb
(c)利用下面式子,计算 v v v M M M的收缩并归一化,更新 u u u,归一化因子记为 Λ \Lambda Λ
∑ b M a b v b = Λ u a \sum_b M_{ab}v_b = \Lambda u_a bMabvb=Λua
(d)如果 u u u v v v(以及 Λ \Lambda Λ)收敛,则返回 u 、 v 和 Λ u、v和\Lambda uvΛ;否则,返回执行步骤(b);
最后我们发现 u u u v v v刚好是 M M M的最大的左右奇异向量, Λ \Lambda Λ刚好对于 M M M的最大的奇异值
定义:
——仅最大奇异向量为上述迭代过程的稳定不动点
——当矩阵为是实对称时,上述算法可获得绝对值最大的本征值及对应的本征向量;

1.2.1 代码实例

——定义一个函数

#假设矩阵M为实矩阵
def svd0(mat,it_time = 100,tol = 1e-15):
	"""
	mat:输入矩阵(假设是实矩阵)
	it_time:最大迭代次数
	tol:错误阈值
	u:左奇异向量
	s:奇异值
	v:右奇异向量
	"""
	dim0,dim1 = mat.shape#dim0为行数,dim1为列数
	#随机初始化奇异向量
	u,v = np.random.randn(dim0,),np.random.randn(dim1,)
	#归一化初始向量
	u,v = u/np.linalg.norm(u),v/np.linalg.norm(v)
	s = 1
	
	for t in range(it_time):
		#更新v和s
		v1 = u.dot(mat)
		s1 = np.linalg.norm(v1)
		v1 /= s1 #归一化v1
		#更新u和s
		u1 = mat.dot(v1)
		s1 = np.linalg.norm(u1)
		u1 /= s1
		#计算收敛程度
		conv = np.linalg.norm(u - u1) / dim0 + np.linalg.norm(v - v1) / dim1
		u,s,v = u1,s1,v1
		#判断是否跳出循环
		if conv < tol:
		   break
	return u,s,v

验证上面算法的正确性
利用numpy库中的svd函数计算最大奇异值及对应的奇异向量

M = np.random.randn(3,5)
U,S,V = np.linalg.svd(M) #自带的svd中都是非升序排列的
u0,s0,v0 = U[:,0],S[0],V[0,:]
#利用上述算法计算最大奇异值及对应的奇异向量
u1,s1,v1 = svd0(M)
print(u0)
print(u1)
print(v0)
print(v1)
print(s0)
print(s1)

1.3 自然地将上述自洽方程组推广到高阶张量的单秩分解(rank-1分解;以三阶张量T为例)

假设: T = Λ u ⨂ v ⨂ w T = \Lambda u\bigotimes v\bigotimes w T=Λuvw
满足如下自洽方程组:
∑ a b T a b c u a v b = Λ w c \sum_{ab}T_{abc}u_av_b = \Lambda w_c abTabcuavb=Λwc ∑ a c T a b c u a w c = Λ v b \sum_{ac}T_{abc}u_aw_c = \Lambda v_b acTabcuawc=Λvb ∑ b c T a b c v b w c = Λ u a \sum_{bc}T_{abc}v_bw_c = \Lambda u_a bcTabcvbwc=Λua
注:第一个式子是 u a , v b u_a,v_b ua,vb T a b c T_{abc} Tabc进行收缩,以下两个同理
其中 u , v , w u,v,w u,v,w为归一化向量,方程组成立时有 Λ = ∑ a b c T a b c u a v b w c \Lambda = \sum_{abc}T_{abc}u_av_bw_c Λ=abcTabcuavbwc被称为rank-1分解系数
类似于奇异值分解的迭代算法,上述方程组可迭代求解。

1.4 Rank-1分解

Rank-1分解对应于如下优化问题:
给定张量 T T T,求解张量 T ~ = Λ ∏ ⨂ n v ( n ) \widetilde{T} = \Lambda\prod_{\bigotimes n}v^{(n)} T =Λnv(n),使得 T T T T ~ \widetilde{T} T 之间的范数 f = ∣ T − T ~ ∣ f = |T - \widetilde{T}| f=TT 极小。(注:张量的范数这里定义为张量元平方和之后开方)
可以证明:Rank-1分解得到的向量与系数构成的 T ~ \widetilde{T} T ,使范数 f f f极小
思考:当 T T T为二阶张量时,Rank-1分解与矩阵奇异值分解对应的最优问题之间的关系。

1.4.1 代码实例

import numpy as np
import copy

def rank1decomp(x,it_time = 100,tol = 1e-15)
	"""
	x:待分解的张量
	it_time:最大迭代步数
	tol:迭代终止的阈值
	vs:存储rank-1分解各个向量的list
	k:rank_1系数
	"""
	ndim = x.ndim #读取张量x的阶数
	dims = x.shape #读取张量x各个指标的维数

	#初始化vs中的各个向量并归一化
	vs = list() #vs用以存储rank-1分解得到的各个向量
	for n in range(ndim):
        _v = np.random.randn(dims[n])
        vs.append(_v / np.linalg.norm(_v))
    k = 1
	for t in range(it_time):
		vs0 = copy.deepcopy(vs) #暂存各个向量以计算收敛情况
		for _ in range(ndim):
			#收缩前(ndim-1)个向量,更新最后一个向量
			x1 = copy.deepcopy(x)
			for n in range(ndim - 1):
				x1 = np.tensordot(x1,vs[n],[[0],[0]])
			#归一化得到的向量,并更新常数k
			k = np.linalg.norm(x1)
			x1 /= k
			#将最后一个向量放置到第0个位置
			vs.pop()
			vs.insert(0,x1)
			#将张量最后一个指标放置到第0位置
			x = x.transpose([ndim - 1] + list(range(ndim - 1))) #transpose()函数的作用是调换数组的行列值的索引值,类似于求矩阵的转置
		#计算收敛情况
		conv = np.linalg.norm(np.hstack(vs0) - np.hstack(vs))#np.hstack()在水平方向上平铺
		if conv < tol:
			break
	return vs,k
		

测试rank-1分解程序

tensor = np.random.randn(2,2,2,3,4)
vecs,coeff = rank1decomp(tensor)
print('The vectors by rank-1 decomposition = ')
for x in vecs:
	print(x)
print('\nThe rank-1 coefficient = ' + str(coeff))

注:以上代码是对于任意阶张量而言的

2.高阶奇异值分解

在rank-1分解中,我们将最大奇异值及奇异向量的方法推广到了高阶张量,下面我们考虑将完整的奇异值分解进行推广
——高阶奇异值分解(Higher-order singular value decomposition,简称HOSVD),又称Tucker分解
定义如下(以三阶实张量T为例):
T a b c = ∑ i j k G i j k U a i V b j W c k ( 从 右 向 左 叫 T u c k e r 积 ) T_{abc} = \sum_{ijk}G_{ijk}U_{ai}V_{bj}W_{ck}(从右向左叫Tucker积) Tabc=ijkGijkUaiVbjWckTucker
将一个高阶张量分解为一个同阶的张量和三个矩阵的缩并
Tucker分解的图形表示:
在这里插入图片描述
⇓ \Downarrow
在这里插入图片描述

其中,变换矩阵满足正交性 U U T = V V T = W W T = I UU^T = VV^T = WW^T =I UUT=VVT=WWT=I,张量 G G G被称为核张量(core tensor),满足如下性质:
①定义 G G G的键约化矩阵(bond reduced matrix),以指标 i i i为例,其键约化矩阵定义为:
J i i ′ = ∑ j k G i j k G i ′ j k J_{ii^{'}} = \sum_{jk}G_{ijk}G_{i^{'}jk} Jii=jkGijkGijk
(只露出一个指标,其它指标进行缩并)
核张量的任意 G G G的任意键约化矩阵为非负定对角阵,且元素按非升序排列( J 00 ≥ J 11 ≥ … … ≥ 0 J_{00}\geq J_{11}\geq……\geq0 J00J110
②高阶奇异值分解的HOSVD算法(以三阶实张量 T T T为例)
(a)计算各个指标的键约化矩阵;
I a a ′ = ∑ b c T a b c T a ′ b c I_{aa^{'}} = \sum_{bc}T_{abc}T_{a^{'}bc} Iaa=bcTabcTabc J b b ′ = ∑ a c T a b c T a b ′ c J_{bb^{'}} = \sum_{ac}T_{abc}T_{ab^{'}c} Jbb=acTabcTabc K c c ′ = ∑ a b T a b c T a b c ′ K_{cc^{'}} = \sum_{ab}T_{abc}T_{abc^{'}} Kcc=abTabcTabc
(b)计算每个键约化矩阵的本征值分解:
键约化矩阵一定是实对称的
I = U Ω U T I = U\Omega U^T I=UΩUT J = V Π V T J = V\Pi 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_{ijk} = \sum_{abc}T_{abc}U_{ai}V_{bj}W_{ck} Gijk=abcTabcUaiVbjWck
最终得到高阶奇异值分解: T a b c = ∑ i j k G i j k U a i V b j W c k T_{abc} = \sum_{ijk}G_{ijk}U_{ai}V_{bj}W_{ck} Tabc=ijkGijkUaiVbjWck
注:
各个本征谱中,非零值得个数被称为张量的Tucker秩
张量的Tucker低秩近似可通过HOSVD,HOOL等算法实现

2.1 代码实例

import numpy as np
import torch as tc
import copy

#求解hosvd的算法
def hosvd(x):
    """
    :param x: 待分解的张量
    :return G: 核张量
    :return U: 变换矩阵
    :return lm: 各个键约化矩阵的本征谱
    """
    ndim = x.ndim
    U = list()  # 用于存取各个变换矩阵
    lm = list()  # 用于存取各个键约化矩阵的本征谱
    x = tc.from_numpy(x)#将x 转换为torch类型
    for n in range(ndim):
        index = list(range(ndim))
        index.pop(n)
        _mat = tc.tensordot(x, x, [index, index])
        _lm, _U = tc.symeig(_mat, eigenvectors=True)#求对称矩阵的特征值和特征向量 如果eigenvectors为False,则仅计算特征值。如果为True,则同时计算特征值和特征向量。
        lm.append(_lm.numpy())#_lm.numpy()将_lm又转换为numpy()类型
        U.append(_U)
    # 计算核张量
    G = tucker_product(x, U)
    U1 = [u.numpy() for u in U]#转化类型
    return G, U1, lm


#从右到左的tucker积
def tucker_product(x, U, dim=1):
    """
    :param x: 张量
    :param U: 变换矩阵
    :param dim: 收缩各个矩阵的第几个指标
    :return G: 返回Tucker乘积的结果
    """
    ndim = x.ndim
    if type(x) is not tc.Tensor:
        x = tc.from_numpy(x)
        
    U1 = list()
    for n in range(len(U)):
        if type(U[n]) is not tc.Tensor:
            U1.append(tc.from_numpy(U[n]))
        else:
            U1.append(U[n])
    
    ind_x = ''
    for n in range(ndim):
        ind_x += chr(97 + n)
    ind_x1 = ''
    for n in range(ndim):
        ind_x1 += chr(97 + ndim + n)
    contract_eq = copy.deepcopy(ind_x)
    for n in range(ndim):
        if dim == 0:
            contract_eq += ',' + ind_x[n] + ind_x1[n]
        else:
            contract_eq += ',' + ind_x1[n] + ind_x[n]
    contract_eq += '->' + ind_x1
    # print(x.shape, U[0].shape, U[1].shape, U[2].shape)
    # print(type(contract_eq), contract_eq)
    G = tc.einsum(contract_eq, [x] + U1)#爱因斯坦求和公式
    G = G.numpy()
    return G

检查Tucker分解

tensor = np.random.randn(3, 4, 2)
Core, V, LM = hosvd(tensor)

print('检查Tucker分解等式是否成立:')
tensor1 = tucker_product(Core, V, dim=0)
error = np.linalg.norm(tensor - tensor1)
print('Tucker分解误差 = ' + str(error))

print('\n检查各个变换矩阵为正交阵:')
for n, v in enumerate(V):
    print('\n对于第' + str(n) +'个变换矩阵,VV.T = ')
    print(v.dot(v.T))

3.拓展:张量的CP分解与CP秩

回顾:单秩张量(rank-1分解)满足的形式为 T ~ = Λ ∏ ⨂ n v ( n ) \widetilde{T} = \Lambda\prod_{\bigotimes n}v^{(n)} T =Λnv(n),易得,单秩张量的Tucker秩为(1,1,…,1)
——将单秩张量的形式稍作扩展,定义CP积,设N阶张量 T T T R R R个单秩张量的求和:
T = ∑ r = 0 R − 1 T ~ ( r ) = ∑ r = 0 R − 1 Λ ( r ) ∏ ⨂ n = 0 N − 1 v ( r , n ) T = \sum_{r =0}^{R - 1}\widetilde{T}^{(r)} =\sum_{r =0}^{R - 1}\Lambda^{(r)}\prod_{\bigotimes n = 0}^{N - 1}v^{(r,n)} T=r=0R1T (r)=r=0R1Λ(r)n=0N1v(r,n)
注:从右向左是CP积
——将 Λ \Lambda Λ看成向量, v ( r , n ) v^{(r,n)} v(r,n)看成矩阵,则上式的CP形式也可以写成如下的形式:
T a 1 a 2 . . . = ∑ r = 0 R − 1 Λ r ∏ ⨂ n = 0 N − 1 V r a n ( n ) T_{a_1a_2...} = \sum_{r =0}^{R - 1}\Lambda_{r}\prod_{\bigotimes n = 0}^{N - 1}V^{(n)}_{ra_n} Ta1a2...=r=0R1Λrn=0N1Vran(n)
其中, Λ \Lambda Λ为R 维向量, V ( n ) V^{(n)} V(n)为对应于第n个指标的矩阵,由R个列向量组成
——进一步改写CP积的形式
T a 1 a 2 . . . = ∑ r = 0 R − 1 Λ r ∏ ⨂ n = 0 N − 1 V r a n ( n ) = ∑ r = 0 R − 1 ∑ r 1 r 2 . . . δ r , r 1 r 2 . . . Λ r ∏ ⨂ n = 0 N − 1 V r a n ( n ) T_{a_1a_2...} = \sum_{r =0}^{R - 1}\Lambda_{r}\prod_{\bigotimes n = 0}^{N - 1}V^{(n)}_{ra_n} = \sum_{r =0}^{R - 1}\sum_{r_1r_2...}\delta_{r,r_1r_2...}\Lambda_{r}\prod_{\bigotimes n = 0}^{N - 1}V^{(n)}_{ra_n} Ta1a2...=r=0R1Λrn=0N1Vran(n)=r=0R1r1r2...δr,r1r2...Λrn=0N1Vran(n)
其中, δ \delta δ为(N+1)阶推广的超对角张量(N为张量 T T T的阶数),第一个指标的维数为R,其余指标的维数与 T T T指标的维数相等
——推广的超对角张量 δ \delta δ满足:对于任意 r r r(逗号之前的指标),张量 δ r , r 1 r 2 . . . \delta_{r,r_1r_2...} δr,r1r2...满足:
δ r , r 1 r 2 . . . = { 0   其 它 情 况 下 1   当 r 1 = r 2 = . . . = r N , ∀ r \delta_{r,r_1r_2...} = \{^{1\ 当r_1 = r_2 = ...=r_N}_{0\ 其它情况下},\forall r δr,r1r2...={0 1 r1=r2=...=rNr
在这个情况下三阶CP积的图形表示为:
在这里插入图片描述

⇓ \Downarrow 在这里插入图片描述

——定义CP分解:
给定张量 T T T,求解 Λ \Lambda Λ V V V,满足 T a 1 a 2 . . . = ∑ r = 0 R − 1 Λ r ∏ ⨂ n = 0 N − 1 V r a n ( n ) T_{a_1a_2...} = \sum_{r =0}^{R-1}\Lambda_{r}\prod_{\bigotimes n = 0}^{N - 1}V^{(n)}_{ra_n} Ta1a2...=r=0R1Λrn=0N1Vran(n)
——定义CP秩:
使得CP分解严格成立的最小的R取值
——定义CP低秩近似:
给定R,使得CP分解式中左右之间的范数极小
CP分解中还存在尚未解决的关键科学问题:
①计算任意给定张量的CP秩是一个NP难问题
②目前存在多种CP低秩近似的算法,但是都无法保证获得的近似是最优的
③当取R = 1时,CP分解退化成rank-1分解;但CP分解中贡献最大的项(如 Λ \Lambda Λ绝对值最大的元素对应的rank-1张量)不一定对应于rank-1分解所得的张量

4.重要内容总结

  1. 张量的基本定义:是用指标标记的一堆数
  2. 不同的标记方式由reshape、transpose等命令相互转换;
  3. 张量的图形表示:张量本身由节点(圆圈或方块等)表示,指标由连接节点的边
    表示;不同张量的共有指标由连接对应节点的边表示,默认进行求和;
  4. 本征值分解的形式与性质;
  5. 最大本征问题对应的最优化问题;
  6. 最大本征问题的幂级数求解法;
  7. 奇异值分解的形式与性质,与矩阵秩的定义;
  8. 基于奇异值分解的矩阵低秩近似问题,与裁剪误差;
  9. 最大奇异值/向量的迭代算法;
  10. 张量的单秩分解与最优单秩近似问题;
  11. 高阶奇异值分解与Tucker秩;
  12. 高阶奇异值分解的HOSVD算法;
  13. 张量的Tucker低秩近似问题(HOOI);
  14. CP分解与CP秩
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值