近年来,张量分解技术在数据挖掘领域得到了很好的应用,但关于张量的一些计算却与我们所熟悉的线性代数大相径庭,同时,张量计算相比以向量和矩阵计算为主导的线性代数更为抽象,这使得大量读者可能会觉得关于张量的内容很“难啃”。当然,就线性代数和多重线性代数而言,主流的观点将涉及到张量计算的内容归为“多重线性代数”(multilinear algebra,维基百科链接为:Multilinear algebra),并认为多重线性代数实际上是线性代数的延伸。
为了便于认识张量计算,这里将系统地介绍张量分解所需要的一些数学基础,该部分内容主要包括常见的Kronecker积、Khatri-Rao积、向量的外积、内积、F-范数、模态积的运算规则以及高阶奇异值分解。
Kronecker积在张量计算中非常常见,是衔接矩阵计算和张量计算的桥梁,实际上,Kronecker积的运算规则是很简单的,给定一个大小为的矩阵和一个大小为的矩阵,则矩阵和矩阵的Kronecker积为
很明显,矩阵的大小为,即行数为,列数为。举一个简单的例子,给定,,则
即,且行数为,列数为,其中,符号“”表示Kronecker积。
那么,试想一下:与是否相同呢?
即,显然,.
以为例,也可以考虑另外一个问题,即是否成立呢?
由于,
即,显然,.
给定大小为的矩阵和大小为的矩阵,则矩阵和矩阵的Khatri-Rao积为
举一个例子,给定矩阵,,则
即,由于,故.
需要注意的是,运算符号“”不只是用来表示Khatri-Rao积,有时候也可以表示两个相同大小的矩阵的点乘(element-wise product),如给定矩阵,,则
.
给定向量,向量,则,运算符号“”表示外积。另给定向量,若,则
,
,
,
其中,是一个三维数组(有三个索引),对于任意索引上的值为,在这里,向量, , 的外积即可得到一个第三阶张量(third-order tensor),如图1所示。
图1 向量, , 的外积
在大量的文献中,Kronecker积的符号“”有时也用来表示向量的外积。
众所周知,向量的内积是一个标量,如给定向量,向量,则向量, 的内积为
当给定两个大小相同的第三阶张量和,如,,,,则
.
即两个大小相同的张量其内积是一个标量,这可能也是内积有时候被称为标量积(scalar product)的原因。
给定张量为,,则该张量的F-范数为
即张量F-范数的平方等于其所有元素的平方和,正是这样,很多涉及到矩阵分解或张量分解的优化问题中常常会出现残差矩阵的平方和最小化或是残差张量的平方和最小化,目标函数也多以相应的残差矩阵或残差张量的F-范数的平方形式进行书写。
在实际应用中,由于高阶张量比向量、矩阵都抽象,最简单地,向量和矩阵可以很轻松地书写出来并进行运算,而高阶张量则不那么直观,如何将高阶张量转换成二维空间的矩阵呢?这就是张量的展开,有时,也将张量的展开称为张量的矩阵化(Matricization: transforming a tensor into a matrix)。
给定大小为的张量,其中,矩阵,矩阵,按照模态1(mode-1, 即对应着张量的第一阶)展开可以得到,
即矩阵,其大小为.
按照模态2(mode-2, 即对应着张量的第二阶)展开可以得到,
即矩阵,其大小为.
按照模态3(mode-3, 即对应着张量的第三阶)展开可以得到,
即矩阵,其大小为.
类似地,如果给定一个大小为的第四阶张量,则在各个模态下的展开分别为
,
,
,
.
举一个例子,若,,,,则
,
,
,
.
可惜的是,张量的展开虽然有一定的规则,但并没有很强的物理意义,对高阶张量进行展开会方便使用相应的矩阵化运算。除此之外,高阶张量可以展开自然也就可以还原(即将展开后的矩阵还原成高阶张量,这个过程称为folding)。
张量与矩阵相乘(又称为模态积)相比矩阵与矩阵之间的相乘更为抽象,如何理解呢?
假设一个大小为的张量,同时给定一个大小为的矩阵,则张量与矩阵的模态积(-mode product)记为,其大小为,对于每个元素而言,有
其中,,我们可以看出,模态积是张量、矩阵和模态(mode)的一种“组合”运算。另外,与是等价的,这在接下来的例子里会展现相应的计算过程。
上述给出张量与矩阵相乘的定义,为了方便理解,下面来看一个简单的示例,若给定张量为,,其大小为,另外给定矩阵,试想一下:张量和矩阵相乘会得到什么呢?
假设,则对于张量在任意索引上的值为,这一运算规则也不难发现,张量的大小为,以位置为例,
再以位置为例,,这样,可以得到张量为
,
,
即,.
其中,由于模态积的运算规则不再像Kronecer积和Khatri-Rao积那么“亲民”,所以有兴趣的读者可以自己动手计算一遍。
实际上,(会得到大小为的张量)或(会得到大小为的张量)也可以用上述同样的运算规则进行计算,这里将不再赘述,有兴趣的读者可以自行推导。需要注意的是,有一个恒等的计算公式,即,由于,则
满足,即采用张量矩阵化的形式进行运算可以使问题变得更加简单,从这里也可以看出高阶张量进行矩阵化的优点。
矩阵的奇异值分解(singular value decomposition,简称SVD)是线性代数中很重要的内容,通常,给定一个大小为的矩阵,奇异值分解的形式为
其中,矩阵的大小分别为,矩阵是由左奇异向量(left singular vector)构成的,矩阵是由右奇异向量(right singular vector)构成的,矩阵对角线上的元素称为奇异值(singular value),这一分解过程很简单,但实际上,关于奇异值分解的应用是非常广泛的。
就高阶奇异值分解而言,著名学者Tucker于1966年给出了计算Tucker分解的三种方法,第一种方法就是我们这里要提到的高阶奇异值分解,其整个分解过程也是由矩阵的奇异值分解泛化得到的。
对于给定一个大小为的张量,将模态下的展开记为,则模态的矩阵进行奇异值分解,可以写成
这里的是通过矩阵的奇异值分解得到的,如果取出各个模态下得到的矩阵,则张量的高阶奇异值分解可以写成如下形式:
其中,是核心张量,其计算公式为,在这里,这条计算公式等价于(也是恒成立的)。
细心的读者可能会发现,根据奇异值分解的定义,这里的核心张量的大小为,而矩阵的大小则分别为.
我们也知道,对于矩阵的奇异值分解是可以进行降维(dimension reduction)处理的,即取前个最大奇异值以及相应的左奇异向量和右奇异向量,我们可以得到矩阵的大小分别为,这也被称为截断的奇异值分解(truncated SVD),对于高阶奇异值分解是否存在类似的“降维”过程(即truncated HOSVD, 截断的高阶奇异值分解)呢?
给定核心张量的大小为,并且,,...,,则对于模态的矩阵进行奇异值分解取前个最大奇异值对应的左奇异向量,则矩阵的大小为,对矩阵进行奇异值分解,知道了后,再计算核心张量,我们就可以最终得到想要的Tucker分解了。
本文主要参考了Gene H. Golub和Charles F. Van Loan合著的经典著作《Matrix computations (4th edition)》,有兴趣的读者可以阅读第12章的12.3 Kronecker Product Computations, 12.4 Tensor Unfoldings and Contractions和12.5 Tensor Decompositions and Iterations;另外,Tamara G. Kolda和Brett W. Bader于2009年发表的一篇经典综述论文《Tensor decompositions and Applications》(链接为:http://public.ca.sandia.gov/~tgkolda/pubs/pubfiles/TensorReview.pdf)也是本文的主要参考资料。
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数