Numpy,Tensor维度的理解方式
就像学数学一样,对加减乘除各方式都需要一个理解的入门方法。
import numpy as np
b = np.array([[[1,2], [3,4], [5,6]],
[[11,12],[13,14],[15,16]],
[[21,22],[23,24],[25,26]],
[[31,32],[33,34],[35,36]]])
print(b.ndim) # 3
print(b.shape) # (4,3,2)
上面数组的维度为3,形状为(4,3,2)
一.维度的获取(中括号划分):
查看维度最方便的可视化方式是"数中括号的层数",上面数组最外层的中括号有3个,所以其维度是3.
二.形状的获取(逗号划分):
获取Numpy数组或Tensor的形状,需要像剥洋葱一样,从外往内,同时也需要用到逗号切分与小学的整体代入思维法,而剥开的依据是中括号’[]’,切分的方式是逗号,且切分后的元素需要用视为一个整体。然后对各元素重复进行逗号划分求个数,直到没有中括号为止。
方式:从外往内,以中括号划分维度,以逗号划分元素。
第一维:第一个中括号内有3个逗号,由逗号划分后有4个整体元素,所以第一维形状为4,划分为:
[[1,2], [3,4], [5,6]]
[[11,12],[13,14],[15,16]]
[[21,22],[23,24],[25,26]]
[[31,32],[33,34],[35,36]]
第二维:由逗号划分后的各元素,其形状都是一致的,所以只看其中一个就行。这里我们看第一个[[1,2], [3,4], [5,6]],
这个中括号里有2个逗号,划分后得3个整体元素,所以第二维的形状是3,划分结果:
[1,2]
[3,4]
[5,6]
第三维:最后每个元素还有一个中括号,所以还需要划分一次,里面有一个逗号,所以划分出2个元素,所以这第三维的形状是2,我们只看划分出的第一个元素划分结果为:
1
2
所以最终的形状为(4,3,2)
三.值的获取
值的获取方式主要有3种方式。这三种方式是:
1. 通过对应维度的索引获取值,比如对b取值:
b[0,1,0] 这里有3个值,表示按顺序先从1维取元素,取到一维的元素后,再从该元素中取第二维的元素,直到取到第3维度元素(每进入里面一个中括号则表示进入下一维)所以:
第一维度取索引为0,得到元素:[[1,2], [3,4], [5,6]]
再从该元素中取索引为1的元素得到(取第二维):[3,4]
最后再从第二维获取的元素中取索引维0的第三维元素(取第三维):3
所以:b[0,1,0] = 3
同理:b[2,1]表示先从第一维取索引为2的元素,得到:[[21,22],[23,24],[25,26]],
再从该元素中其中取索引为1的元素,得到:[23,24]
2. 单维度简写法,使用:指代某维的所有元素:全取某个维度,然后再取其他维度的索引获取值,比如:
b[:,1,0] 表示第一维的元素全要,第一维取值得到:
[[1,2], [3,4], [5,6]]
[[11,12],[13,14],[15,16]]
[[21,22],[23,24],[25,26]]
[[31,32],[33,34],[35,36]]
之后再对所有元素取索引为索引为1的值,第二维取值为:
[3,4],
[13,14],
[23,24],
[33,34]
再对所有取出的元素取索引为0的值,第三维值为:
3
13
23
33
3. 多维度简写法,使用…来指代维度: 通过一个三点省略…来全取前面的所有维度,具体省略多少维,则需要根据剩下需要取的维度个数来判定,且使用…省略取法,整个式子中有且仅有一个… 比如:
b[…,0] , 其中只有一个数字(那个0),也可以看逗号,只留下一个具体维度对应的0索引,因为b的维度为3,所以…表示省略了2个维度。那么就是前2个维度全取,第一维全取,得到元素:(注意盯住中括号,每对中括号中的元素就是该一维的所有元素)
[[1,2], [3,4], [5,6]]
[[11,12],[13,14],[15,16]]
[[21,22],[23,24],[25,26]]
[[31,32],[33,34],[35,36]]
第二维全取(从第一维全取的所有元素中,取所有元素,遍历一维所有获取第二维元素) :
从第一维的元素整体:[[1,2], [3,4], [5,6]] 取里面第二维的所有元素得到 [1,2], [3,4], [5,6]
从第一维的元素整体:[[11,12],[13,14],[15,16]]取里面第二维的所有元素得到 [11,12],[13,14],[15,16]
从第一维的元素整体:[[21,22],[23,24],[25,26]]取里面第二维的所有元素得到 [21,22],[23,24],[25,26]
从第一维的元素整体:[[31,32],[33,34],[35,36]]取里面第二维的所有元素得到 [31,32],[33,34],[35,36]
最后一维即第三维只从第二维取出的所有元素中取索引为0的元素:
从第二维的元素整体:[1,2], [3,4], [5,6] 取里面的索引为0的值得到 1,3,5
从第二维的元素整体: [11,12],[13,14],[15,16] 取里面的索引为0的值得到 11,13,15
从第二维的元素整体:[21,22],[23,24],[25,26] 取里面的索引为0的值得到 21,23,25
从第二维的元素整体:[31,32],[33,34],[35,36] 取里面的索引为0的值得到 31,33,35
所以b[…,0]为:
1,3,5
11,13,15
21,23,25
31,33,35
同理求b[…,0,1],先看除了三点省略,还有两个具体索引,表示只留下剩下的2维,而b总共3维,所以b[…,0,1]表示第一维全要,然后取第二维索引为0的全部元素,再从取得的元素中取索引为1的第三维的元素。
步骤:
第一维全要,得到:
[[1,2], [3,4], [5,6]]
[[11,12],[13,14],[15,16]]
[[21,22],[23,24],[25,26]]
[[31,32],[33,34],[35,36]]
第二维只取索引为0的所有值,得到
[[1,2], [3,4], [5,6]] -> [1,2]
[[11,12],[13,14],[15,16]] -> [11,12]
[[21,22],[23,24],[25,26]] -> [21,22]
[[31,32],[33,34],[35,36]] -> [31,32]
第三维只取索引为1的全部元素,得到:
[1,2] -> 2
[11,12] ->12
[21,22] -> 22
[31,32] -> 32
同理再看b[0,…,0], 一样,看见有2个数字,即有2维留下,留下的是第一维与最后一维,而b总共3维,所以第二维全要了,所以b[0,…,0]表示取第一维索引为0的元素,之后第二维的元素全要,之后再从第三维中取索引为0的元素。
步骤:
取第一维索引为0的元素:[[1,2], [3,4], [5,6]]
第二维元素全要:[[1,2], [3,4], [5,6]] -> [1,2], [3,4], [5,6]
第三维取索引为0的元素:[1,2], [3,4], [5,6] -> 1,3,5
所以b[0,…,0]为 1,3,5
最后看一下b[0,…] ,由上面可知,第一维只取索引为0的元素,其他维度全要,得到:
[[1,2], [3,4], [5,6]]
这个结果其实就是b[0]
维度的表示意义:
任何数学概念其实都是为了解决现实的问题,维度的存在也有其现实表示意义。
首先: 所谓维度的高低区别
维度高低是由外向里,中括号[]越靠近外面则越表示低维,越是靠近里面则越表示高维。
其次: 与深度学习中的高低层的区别
这里将其放在一起对比更容易理解。
- 深度学习中对层的描述是高低层,对张量Tensor的描述才能用高低维。
- CNN中常说的低层,是靠近输入图片或者其他样本原始数据的层,因为越低层越靠近原始数据所以其细节越多;而越高层是越靠近输出端的层,一般是经过N多个卷积操作或者隐空间映射后,虽然细节丢失严重,但由于它的感受野越大,所以整个特征元素的包涵越多。
- 对于numpy数组或者张量来说,高维更能表示属性特征,而低维更能表示数量与类别特征。比如:样本结构是:[人数,班级,年龄,性别,学号],这里的人数可以理解为batch_size,越靠近外面的则越是低维,表示数量与类别信息较多,而越是高维则越靠近本身样本固有特征,其固有属性表示的越多。
总结:
1.括号看维度,逗号分元素。
2.通过维度与索引可获取具体某维某索引的值。
3.维度从外往内一层一层剥,操作哪维就对哪层的中括号内的元素进行操作。
4.每一维中的元素都以逗号拆分,拆分后的元素在该维需要视为一个整体。
5.维度可以看作是对中括号的索引,可当作层级位置。
6.所谓的升维或降维,就是把该层里面的所有元素(当前维的各元素视为整体)全拿出来,多加一个中括号或者减去一个中括号,之后再塞回去。如果再某维左边也就是更低维处增维,那么直接把原维度整个增加一个中括号即可,如果在某维的右边也就是更高维处增维,那么就需要把原维的所有元素单独包裹添加一个中括号。具体升维方式可参考:《两句话理解np.newaxis》 7.中括号越靠外,则越表示低维,越靠近里面则越表示高维。低维常用来表示数量与类别,而高维越能表示固有属性。