张量作为有序的序列,也是具备数值索引的功能,并且基本索引方法和Python原生的列表、NumPy中的数组基本一致,当然,所有不同的是,PyTorch中还定义了一种采用函数来进行索引的方式。
1 张量的符号索引
一维张量的索引过程和Python原生对象类型的索引一致,基本格式遵循[start:end:step],索引的基本要点回顾如下。
注:张量索引出来的结果还是零维张量,而不是单独的数。要转化成单独的数,需要使用item()方法。
注:在张量的索引中,step位必须大于0
二维张量的索引逻辑和一维张量的索引逻辑基本相同,二维张量可以视为两个一维张量组合而成,而在实际的索引过程中,需要用逗号进行分隔,分别表示对哪个一维张量进行索引、以及具体的一维张量的索引。
在二维张量索引的基础上,三维张量拥有三个索引的维度。我们将三维张量视作矩阵组成的序列,则在实际索引过程中拥有三个维度,分别是索引矩阵、索引矩阵的行、索引矩阵的列。
理解:更为本质的角度去理解高维张量的索引,其实就是围绕张量的“形状”进行索引。
2 张量的函数索引
在PyTorch中,我们还可以使用index_select函数,通过指定index来对张量进行索引。
在index_select函数中,第二个参数实际上代表的是索引的维度。对于t1这个一维向量来说,由于只有一个维度,因此第二个参数取值为0,就代表在第一个维度上进行索引。
3 tensor.view()方法
PyTorch中的.view()方法会返回一个类似视图的结果,该结果和原张量对象共享一块数据存储空间,并且通多.view()方法,还可以改变对象结构,生成一个不同结构,但共享一个存储空间的张量。共享一个存储空间,就代表二者是“浅拷贝”的关系,修改其中一个,另一个也会同步进行更改。
“视图”的作用就是节省空间,在接下来的很多切分张量的方法中,返回结果都是“视图”,而不是新生成一个对象。
4 张量的分片函数
1)分块:chunk函数
chunk函数能够按照某维度,对张量进行均匀切分,并且返回结果是原张量的视图。
当原张量不能均分时,chunk不会报错,但会返回其他均分的结果。
2)拆分:split函数
split既能进行均分,也能进行自定义切分。返回结果也是view。
注意, 当第二个参数位输入一个序列时,序列的各数值的和必须等于对应维度下形状分量的取值。tensor的split方法和array的split方法有很大的区别,array的split方法是根据索引进行切分。
5 张量的合并操作
张量的合并操作类似于列表的追加元素,可以拼接,也可以堆叠。
1)拼接函数:cat
注意理解,拼接的本质是实现元素的堆积,也就是构成a、b两个二维张量的各一维张量的堆积,最终还是构成二维向量。
2) 堆叠函数:stack
和拼接不同,堆叠不是将元素拆分重装,而是简单的将各参与堆叠的对象分装到一个更高维度的张量里。
注意:对比二者区别,拼接之后维度不变,堆叠之后维度升高。拼接是把一个个元素单独提取出来之后再放到二维张量中,而堆叠则是直接将两个二维张量封装到一个三维张量中,因此。堆叠的要求更高,参与堆叠的张量必须形状完全相同。
6 张量维度变换
通过reshape方法,能够灵活调整张量的形状。而在实际操作张量进行计算时,往往需要另外进行降维和升维的操作,当我们需要除去不必要的维度时,可以使用squeeze函数,而需要手动升维时,则可采用unsqueeze函数。
1)squeeze函数:删除不必要的维度
简单理解,squeeze就相当于提出了shape返回结果中的1。
2)unsqeeze函数:手动升维