3x4x5的張量:
x = torch.tensor([[[1, 2, 3, 4, 5],
? ? ? ? ? ? ? ? ? ?[6, 7, 8, 9, 10],
? ? ? ? ? ? ? ? ? ?[11, 12, 13, 14, 15],
? ? ? ? ? ? ? ? ? ?[16, 17, 18, 19, 20]],
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? [[21, 22, 23, 24, 25],
? ? ? ? ? ? ? ? ? ?[26, 27, 28, 29, 30],
? ? ? ? ? ? ? ? ? ?[31, 32, 33, 34, 35],
? ? ? ? ? ? ? ? ? ?[36, 37, 38, 39, 40]],
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? [[41, 42, 43, 44, 45],
? ? ? ? ? ? ? ? ? ?[46, 47, 48, 49, 50],
? ? ? ? ? ? ? ? ? ?[51, 52, 53, 54, 55],
? ? ? ? ? ? ? ? ? ?[56, 57, 58, 59, 60]]])
dim=0:代表3個元素的維度,每個元素是一個4x5的矩陣。
dim=1:代表4個元素的維度,每個元素是一個5維的向量。
dim=2:代表5個元素的維度,每個元素是一個標量。
?3 維 tensor 的sun操作理解
參考Pytorch從入門到實踐:dim維度的使用(終極版)_pytorch tensor dim-CSDN博客
3 個括號代表的維度從左往右分別為 0, 1, 2,在第 0 維遍歷得到矩陣,在第 1 維遍歷得到向量,在第 2 維遍歷得到標量
?更詳細一點
所以,我們明白了:標量,向量,矩陣, 三維張量之間的關系,三維張量里面包含了二維的矩陣,二維矩陣里面包含了一維的向量,一維向量里面包含了零維的標量。
b = torch.tensor([[[3, 2], [1, 4]], [[5, 6], [7, 8]]])
print(b)tensor([[[3, 2],[1, 4]],[[5, 6],[7, 8]]])
將 b 在第 0 維相加,第 0 維為最外層括號,最外層括號中的元素為矩陣[[3, 2], [1, 4]]和[[5, 6], [7, 8]]。在第 0 維求和,就是將第 0 維中的元素(矩陣)相加
s = torch.sum(b, dim=0)
print(s)
tensor([[ 8, ?8],[ 8, 12]])
?求 b 在第 1 維的和,就是將 b 第 1 維中的元素[3, 2]和[1, 4], [5, 6]和 [7, 8]相加,所以
?[3,2]+[1,4]=[4,6],[5,6]+[7,8]=[12,14]
s = torch.sum(b, dim=1)
print(s)
tensor([[ 4, ?6],[12, 14]])
則在 b 的第 2 維求和,就是對標量 3 和 2, 1 和 4, 5 和 6 , 7 和 8 求和
s = torch.sum(b, dim=2)
print(s)
tensor([[ 5, ?5],[11, 15]])
如果想要保持結果的維度不變,設置參數keepdim=True
即可。
各階張量
0階張量(標量):
0階張量是一個單獨的數字或數值,沒有維度。
示例:x = 5
1階張量(向量):
1階張量是有序的一維數組,具有一個維度。
示例:x = [1, 2, 3, 4]
在PyTorch中,形狀表示為:(4,)
2階張量(矩陣):
2階張量是一個二維數組,具有兩個維度:行和列。
示例:x = [[1, 2], [3, 4]]
在PyTorch中,形狀表示為:(2, 2)
3階張量(三維數組):
3階張量是一個具有三個維度的數組,例如圖片數據,其中維度可以理解為高度、寬度和通道數。
示例:x = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
在PyTorch中,形狀表示為:(2, 2, 2)
dim
一些常見操作
import torch
x = torch.tensor([[0, 1, 2], [3, 4, 5]]) # shape (2, 3)
# 沿行(縱向)壓縮 → 每列求和
x.sum(dim=0) # tensor([3, 5, 7]) shape (3,)
# 沿列(橫向)壓縮 → 每行求和
x.sum(dim=1) # tensor([3, 12]) shape (2,)y = torch.tensor([[[1,2],[3,4]], [[5,6],[7,8]]]) # shape (2, 2, 2)
# 沿最外層維度壓縮 → 同位置元素取最大值
y.max(dim=0)
# values: tensor([[5,6], [7,8]]), indices: tensor([[1,1], [1,1]])
# 沿中間維度壓縮 → 每行取最大值
y.max(dim=1)
# values: tensor([[3,4], [7,8]]), indices: tensor([[1,1], [1,1]])x = torch.tensor([[1, 2], [3, 4]]) # (2, 2)
y = torch.tensor([[5, 6]]) # (1, 2)
# 沿行(dim=0)拼接 → 新增行
torch.cat([x, y], dim=0)
# tensor([[1, 2],
# [3, 4],
# [5, 6]]) shape (3, 2)
# 錯誤示例:列數不匹配時 dim=0 會報錯!
z = torch.tensor([[7], [8]])
torch.cat([x, z], dim=1) # 正確:沿列拼接 → 新增列t = torch.arange(10).reshape(5, 2) # (5, 2)
# 沿行(dim=0)切分為 2 行和 3 行
parts = t.split([2, 3], dim=0)
# part1: shape (2, 2), part2: shape (3, 2)x = torch.zeros(3, 1, 2) # (3, 1, 2)
x.squeeze(dim=1) # 移除 dim=1 → (3, 2)
x.unsqueeze(dim=0) # 在 dim=0 添加維度 → (1, 3, 1, 2)x = torch.randn(2, 3, 5) # (2, 3, 5)
x.permute(2, 0, 1) # 重排為 (5, 2, 3)
mean操作
import torch
x = torch.arange(24).view(2, 3, 4).float() # 形狀 (2, 3, 4)
"""
x 內容:
[[[ 0., 1., 2., 3.],[ 4., 5., 6., 7.],[ 8., 9., 10., 11.]],[[12., 13., 14., 15.],[16., 17., 18., 19.],[20., 21., 22., 23.]]]
"""
?不同維度的均值計算?:
?操作? | ?計算邏輯? | ?輸出形狀? | ?結果? |
---|---|---|---|
x.mean(dim=0) | 沿通道(第0維)求平均 | (3, 4) | [[6., 7., 8., 9.], [10., 11., 12., 13.], [14., 15., 16., 17.]] |
x.mean(dim=1) | 沿寬度(第1維)求平均 | (2, 4) | [[4., 5., 6., 7.], [16., 17., 18., 19.]] |
x.mean(dim=2) | 沿高度(第2維)求平均 | (2, 3) | [[1.5, 5.5, 9.5], [13.5, 17.5, 21.5]] |
x.mean(dim=[1,2]) | 沿寬度和高度同時求平均 | (2,) | [5.5, 17.5] |
dim=-2
?的操作效果(三維張量等價于?dim=1
):
將中間維度(大小為3)壓縮為1,結果形狀變為?(2, 1, 4)
?→ 實際輸出?(2, 4)
(因默認壓縮空維度),dim=k
?表示沿維度?k
?壓縮(該維度消失),
例如:
原始張量:? [3,3,4]? ->? [3,4]
[[[ 0, ?1, ?2, ?3], ? ?# 第1個矩陣
? [ 4, ?5, ?6, ?7],
? [ 8, ?9, 10, 11]],?[[12, 13, 14, 15], ? ?# 第2個矩陣
? [16, 17, 18, 19],
? [20, 21, 22, 23]]]沿 dim=-2 求和后: ?
[[ 12, 15, 18, 21], ? ?# 0+4+8, 1+5+9, ... ?
?[48, 51, 54, 57]] ? ? # 12+16+20, 13+17+21, ...
?
實際計算示例
假設場景:
transport = incident_lights * incident_areas * n_d_i? # 逐元素相乘:
# 結果維度:(num_pts, num_sample, 3)
# ? incident_lights: (num_pts, num_sample, 3)
# ? incident_areas:? ?(num_pts, num_sample, 1)
# ? n_d_i: ? ? ? ? ?(num_pts, num_sample, 1)
num_pts=1
(1個表面點)num_sample=2
(2個采樣方向)- 數據:
incident_lights = [[[1.0, 0.5, 0.2], [0.8, 0.3, 0.1]]] # (1,2,3) incident_areas = [[0.6], [0.6]] # (1,2,1) n_d_i = [[[0.9], [0.7]]] # (1,2,1)
分步計算:
# 第一步:逐元素相乘
term1 = incident_lights * incident_areas # [[[1.0 * 0.6, 0.5 * 0.6, 0.2 * 0.6] = [0.6, 0.3, 0.12]# [0.8 * 0.6, 0.3 * 0.6, 0.1 * 0.6] = [0.48, 0.18, 0.06]]]
term2 = term1 * n_d_i # [[[0.6 * 0.9, 0.3 * 0.9, 0.12 * 0.9] = [0.54, 0.27, 0.108]# [0.48 * 0.7, 0.18 * 0.7, 0.06 * 0.7] = [0.336, 0.126, 0.042]]]# 第二步:沿采樣維度(dim=-2)求平均
diffuse_light = term2.mean(dim=-2) # [(0.54+0.336)/2, (0.27+0.126)/2, (0.108+0.042)/2]# = [0.438, 0.198, 0.075]