《神经网络与PyTorch实战》——3.4.3 张量点积和Einstein求和
3.4.3 张量点积和Einstein求和
本节介绍张量点积和Einstein求和。
张量点积(tensor dot)是一种利用元素乘法和加法定义的运算,张量点积可以看作矩阵乘法在张量运算中的推广。为了直观了解张量点积的定义,来看几个张量点积的特殊情况。
一维张量和一维张量之间的张量点积:考虑两个相同大小的一维张量和,则张量和张量的张量点积为
你可能已经发现,这种情况下的张量点积和矩阵论中两个实列向量之间的点积非常相似。在矩阵论中,考虑两个实列向量和,这两个实列向量之间的点积(又称内积)正是。因此,两个一维张量之间的张量点积可以理解成对应的两个实列向量之间的点积。
在PyTorch中,两个一维张量之间的张量点积用函数torch.dot() 实现,示例如下:
x = torch.arange(4)
y = torch.arange(1, 5)
torch.dot(x, y)
由以上代码得到数值20,即
二维张量和一维张量之间的张量点积:考虑大小为的二维张量和大小为的一维张量,如果,则可以定义张量关于最后一维(即第一维)和张量的张量点积为,它是大小为的一维张量,其第个元素为
你可能已经发现,在这种情况下的张量点积与矩阵论中矩阵和列向量之间的矩阵乘法非常相似。在矩阵论中,考虑矩阵和列向量
,矩阵和列向量之间的矩阵乘法的结果是一个列向量,其第个元素正是。因此,二维张量的最后1维和一维张量之间的张量点积可以理解成矩阵和列向量之间的矩阵乘法。
在PyTorch中,这样的张量点积用函数torch.mv() 实现,示例如下:
x = torch.arange(4).view(2, 2)
y = torch.arange(2)
torch.mv(x, y)
以上代码的输出为张量。
二维张量和二维张量之间的张量点积:考虑大小为的二维张量和大小为的二维张量,如果,则可以定义张量关于最后1维(即第1维)和张量第0维的张量点积为,它是大小为的二维张量,其第个元素为
你可能已经发现,在这种情况下的张量点积与矩阵论中矩阵和矩阵之间的矩阵乘法非常相似。在矩阵论中,考虑矩阵和矩阵,矩阵乘法的积的元素的值和上式相似。因此,二维张量的最后1维和二维张量的第0维之间的张量点积可以理解成两个矩阵之间的矩阵乘法。
在PyTorch中,这样的张量点积用函数torch.mm() 实现,示例如下:
x = torch.arange(6).view(2, 3)
y = torch.arange(6).view(3, 2)
torch.mm(x, y)
以上代码的输出为张量。
在以上三个例子中,对于两个张量和,我们计算了张量关于最后1维和张量关于第0维的张量点积。对于一般的情形,张量的大小为,张量的大小为,并且有,那么张量关于最后1维和张量关于第0维的张量点积的大小为,其第个元素的值为
我们来看一个具体的例子。考虑大小为的张量和大小为的张量。张量的第1维和张量的第0维大小相同,张量的第2维和张量的第4维大小相同,张量的第3维和张量的第1维相同。因此,可以考虑张量关于维度和张量关于维度的张量点积。这样的张量点积的结果张量的维度为,大小为,其第个元素的值为
注意:本书中用到的点积符号“”只表示前一个张量的最后1维和后一个张量的第0维的张量点积。
以上各个例子对前一个张量的最后1维和后一个张量的第0维进行了张量点积运算。事实上,张量点积的定义不仅限于以上情况。例如,可以在两个张量中各取多个维度进行张量点积运算,取的维度也不一定需要是前一个张量的最后几维或后一个张量的前几维。对于一般的情况,从维度为的张量中取出个维度,并且在大小为的张量中取出大小相同的个维度,也可以做张量点积运算,得到的结果张量的维度是。例如,可以从大小为的张量取出第维,从大小为的张量取出第维,得到的张量点积的大小是。对于这样的情况,就不能用点积符号“”表示。为了解决这一问题,爱因斯坦(Einstein,研究相对论的物理学家)引入了Einstein求和约定(Einstein summation convention)。本小节后面将介绍Einstein求和约定。
下面介绍什么是Einstein求和约定。Einstein求和约定用一个字符串来表示一个张量或多个张量的运算。首先来看一些字符串的例子:
'i,j->ij'
'bn,anm,bm->ba'
'bij,bjk->bik'
在这些字符串中,有一个英文连字符和英文大于号组成的“->”符号。这个符号之前表示运算的输入,之后表示运算的输出。运算的输入部分是由英文逗号“,”分隔的一些英文小写字母串。每个英文小写字母串代表一个张量,每个英文小写字母串中的一个英文小写字母代表张量的1个维度。例如,字符串 'bn,anm,bm->ba' 表示将一个二维张量、一个三维张量、一个二维张量进行运算,得到一个二维张量。
如果输出张量中代表某个维度的字母只在输入张量中出现1次,则代表将该维度的所有元素都和其他张量相乘,并且保留各乘积结果。字符串 'i,j->ij' 表示将一维张量和一维张量运算得到二维张量,其形式为
再例如,字符串 'ijk,lmno->ijklmno' 表示将三维张量和四维张量运算得到七维张量。如果三维张量的大小是,四维张量的大小是,那么七维张量的大小是。
在输入部分,如果同一个英文小写字母出现两次,那么这两个维度就要被缩并(contraction)。缩并处理的两个维度必须大小相同。缩并是这样操作的:先将对应指标元素相乘,再将乘积相加,相当于做了点积。例如,字符串 'ij,ik->jk' 中字母i出现了两次,那么字母i对应的两个维度就要被缩并。例如,可以将张量和张量进行运算得到,其中
这就相当于将的第0维和的第0维做了张量点积。
在PyTorch中,可以使用函数torch.einsum() 来实现用Einstein求和约定表示的张量点积。torch.einsum() 函数有两个参数:第0个参数就是像 'ij,ik->jk' 这样的表达式,第1个参数是张量的元组,表示这个表达式要对哪些张量进行运算。代码清单3-17给出了用Einstein求和约定进行张量点积运算的例子。
代码清单3-17 利用Einstein求和约定实现张量点积运算
loper = torch.arange(4).reshape(2, 2)
roper = torch.arange(6).reshape(2, 3)
torch.einsum('ij,jk->ik', (loper, roper))
- 点赞
- 收藏
- 关注作者
评论(0)