维度数 vs 维度值/形状

用几何坐标系视角来理解
维度数 vs 维度值/形状:【几何坐标系视角:轴的数量:每个轴上的元素数量】
- 维度数(秩):张量有多少个轴(axes)。【即" 几个轴 "[ 几何视角 ]或"这个张量有 多少层括号 "】。例如标量0维/0个轴,向量1维/1个轴,矩阵2维/2个轴。
- 维度的具体值(形状):每个轴上元素的数量(元素可以是多维的)。【即" 每个轴 的 元素数量 是多少/长度是多少"】。例如形状 (3,1) 表示第0维大小/元素数量为3,第1维大小/元素数量为1。
可以举一些例子
- 一个标量 3 的维度数是0,是点,具体值:没有任何轴(或者说每个维度的长度概念不适用),形状 ()。
- 一个向量 [3,2,3] 的维度数是1,有1个轴,具体值:0轴上有3个元素,形状 (3,)。
- 列向量 [[3],[2],[3]] 的维度数是2,有2个轴,具体值:第0轴/维上有3个元素,第1轴/维上有1个元素,形状 (3,1)。
- 行向量 [[3,2,3]] 的维度数是2,有2个轴,具体值:第0轴/维上有1个元素,第1轴/维上有3个元素,形状 (1,3)。
对应轴axis的运算
在 NumPy 中对ndarray多维数组运算时,axis 参数指明的是将被消去(压缩)的那个轴,结果形状是原形状去掉那个维度(默认keepdims=False情况)。如果想保留维度用 keepdims=True。
对于不同轴的运算很容易混淆,其实可以清晰的拆分2步来处理:
第1步:确定相应轴/维度上的元素(元素可以是多维的);【示例中:用**( )**蓝括号表示当前要处理的元素】
第2步:保持其他轴/维度上的元素数量不变:逐元素执行运算得到最终结果,去掉相应轴(默认keepdims = False 情况)
下面通过 2D 和 3D 的典型例子来直观体会。
1. 二维数组(矩阵)
python
import numpy as np
arr2d = np.array([[1, 2, 3],
[4, 5, 6]])
print("shape:", arr2d.shape) # (2, 3) 2行3列
axis=0
python
np.sum(arr2d, axis=0) # array([5, 7, 9]) shape: (3,)
【第1步:确定相应轴/维度上的元素(元素可以是多维的)】axis=0 对应的元素
**(** \[1, 2, 3\] **),** **(**\[4, 5, 6\] **)**
【第2步:保持其他轴/维度上的元素数量不变:逐元素执行运算得到最终结果】去掉0轴(默认keepdims = False情况):
**(** \[1+4, 2+5, 3+6\] **)** \] = \[5, 7, 9
axis=1
python
np.sum(arr2d, axis=1) # array([6, 15]) shape: (2,)
【第1步:确定相应轴/维度上的元素(元素可以是多维的)】axis=1 对应的元素:
\[**(**1**)**, **(**2**)**, **(**3**)**\], \[**(**4**)**, **(**5**)**, **(**6**)**\]
【第2步:保持其他轴/维度上的元素数量不变:逐元素执行运算得到最终结果】去掉1轴(默认keepdims = False 情况):
\[**(**1+2+3**)**\], \[**(**4+5+6**)**\] \]= \[6, 15
2. 三维数组(张量)
python
import numpy as np
arr3d = np.arange(24).reshape(2, 3, 4) # shape (2,3,4)
print(arr3d)
值如下(为了清晰,我们用 (块, 行, 列) 的结构观察):
python
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]] ← 第 0 块(2×3×4 中的第一块)
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]] ← 第 1 块(2×3×4 中的第二块)
axis=0
python
np.sum(arr3d, axis=0) # shape: (3, 4)
【第1步:确定相应轴/维度上的元素(元素可以是多维的)】axis=0 对应的元素:
**(** \[ \[ 0 1 2 3
4 5 6 7
8 9 10 11\] \] **)** , **(**\[ \[12 13 14 15
16 17 18 19
20 21 22 23\] \] **)**
【第2步:保持其他轴/维度上的元素数量不变:逐元素执行运算得到最终结果】去掉0轴(默认keepdims = False情况):
**(** \[ \[0+12, 1+13, 2+14, 3+15\], \[4+16, 5+17, 6+18, 7+19\], \[8+20, 9+21, 10+22, 11+23\] \] **)**
= [ [12, 14, 16, 18],
20, 22, 24, 26\], \[28, 30, 32, 34\]
axis=1
python
np.sum(arr3d, axis=1) # shape: (2, 4)
【第1步:确定相应轴/维度上的元素(元素可以是多维的)】axis=1 对应的元素:
\[ **(**\[ 0 1 2 3\]**)**, **(**\[ 4 5 6 7\]**)**, **(**\[ 8 9 10 11\]**)** \], \[ **(**\[12 13 14 15\]**)** **(**\[16 17 18 19\]**)** **(**\[20 21 22 23\]**)**\]
【第2步:保持其他轴/维度上的元素数量不变:逐元素执行运算得到最终结果】去掉1轴(默认keepdims = False情况):
\[ **(**\[ 0+4+8, 1+5+9, 2+6+10, 3+7+11 \]**)**\], \[ **(**\[12+16+20, 13+17+21, 14+18+22, 15+19+23\]**)**\]
=[ [12, 15, 18, 21],
48, 51, 54, 57\]
axis=2
python
np.sum(arr3d, axis=2) # shape: (2, 3)
【第1步:确定相应轴/维度上的元素(元素可以是多维的)】axis=2 对应的元素:
\[ \[ **(**0**)** **(**1**)** **(**2**)** **(**3**)**
**(**4**)** **(**5**)** **(**6**)** **(**7**)**
**(**8**)** **(**9**)** **(**10**)** **(**11**)**\]\], \[ \[**(**12**)** **(**13**)** **(**14**)** **(**15**)**
**(**16**)** **(**17**)** **(**18**)** **(**19**)**
**(**20**)** **(**21**)** **(**22**)** **(**23**)**\]\]
【第2步:保持其他轴/维度上的元素数量不变:逐元素执行运算得到最终结果】去掉2轴(默认keepdims = False情况):
\[ \[ **(**0**)** + **(**1**)** + **(**2**)** + **(**3**)**
**(**4**)** + **(**5**)** + **(**6**)** + **(**7**)**
**(**8**)** + **(**9**)** + **(**10**)**+ **(**11**)**\] \], \[ \[**(**12**)** +**(**13**)**+ **(**14**)**+ **(**15**)**
**(**16**)**+ **(**17**)**+ **(**18**)**+ **(**19**)**
**(**20**)**+ **(**21**)**+ **(**22**)**+ **(**23**)**\] \]
= [ [ 6, 22, 38],
54, 70, 86\]
默认keepdims=False情况,对于 shape = (2,3,4) 的数组:
-
形状变化:原形状为 (d0, d1, d2, ...),指定 axis=i,结果形状就是原形状去掉 d_i
-
axis=0 → 消去大小为 2 的轴 → 形状 (3,4)
-
axis=1 → 消去大小为 3 的轴 → 形状 (2,4)
-
axis=2 → 消去大小为 4 的轴 → 形状 (2,3)
keepdims=True时候 -
如果想保留被压扁的维度(以便广播运算),可以使用 keepdims=True
python
np.sum(arr3d, axis=0, keepdims=True).shape # (1, 3, 4)
np.sum(arr3d, axis=1, keepdims=True).shape # (2, 1, 4)
np.sum(arr3d, axis=2, keepdims=True).shape # (2, 3, 1)
keepdims=True示例:
python
np.sum(arr3d, axis=2, keepdims=True)
python
array([[[ 6],
[22],
[38]],
[[54],
[70],
[86]]])
Pytorch的张量Tensor中的多维数组中的维度数与维度值以及轴的相关概念本质是一样的。希望能帮助你理解Numpy、Pytorch中多维数组中的相关概念。^_^