Day24_【深度学习—广播机制】
广播机制用于判断两个不同形状的张量是否可以进行逐元素运算(如 +
, -
, *
等)。它的规则是从最后一个维度开始,从右往左逐一比较两个张量的维度大小。
只要每一个维度都满足以下三条规则中的任意一条,广播就可以成功。
📌 规则 1:维度大小相等
解释:两个张量在当前比较的这个维度上,它们的“长度”或“大小”是一样的。
例子:
a = torch.tensor([[1, 2, 3], # 形状: (2, 3)[4, 5, 6]])
b = torch.tensor([[7, 8, 9], # 形状: (2, 3)[10,11,12]])
我们从右往左比较:
- 第1维(列):
a
是3
,b
也是3
→ ✅ 相等,兼容 - 第0维(行):
a
是2
,b
也是2
→ ✅ 相等,兼容
✅ 所有维度都相等 → 可以直接运算,无需广播。
📌 规则 2:其中一个维度的大小为 1
解释:在当前比较的维度上,只要有一个张量的大小是 1,它就可以被“复制”多次,扩展到和另一个张量一样长。
例子:
a = torch.tensor([[1, 2, 3], # 形状: (2, 3)[4, 5, 6]])
b = torch.tensor([1, 1, 1]) # 形状: (3,)
从右往左比较:
第1维(列):
a
是3
,b
是3
→ ✅ 相等,兼容第0维(行):
a
是2
,b
是?
注意:b
只有一个维度,所以它没有第0维(见规则3),但我们先看这个维度的大小。实际上,在广播中,
b
被视为形状(1, 3)
(前面补一个1),所以:a
第0维:2
b
第0维:1
→ ✅ 有一个是 1,兼容
✅ 所有维度都兼容 → 可以广播!
广播过程: b = [1, 1, 1]
被自动扩展成:
[[1, 1, 1],[1, 1, 1]]
然后与 a
逐元素相加。
c = a + b
# 结果:
# [[2, 3, 4],
# [5, 6, 7]]
📌 规则 3:其中一个张量在该维度上不存在(即维度数更少)
解释:两个张量的总维度数不同,比如一个是 2D 矩阵,一个是 1D 向量。那么在比较时,维度数少的那个张量,前面缺失的维度被视为大小为 1。
这是广播中最容易混淆的一条,我们重点解释。
例子:
a = torch.tensor([[[1, 2], # 形状: (2, 2, 2)[3, 4]],[[5, 6],[7, 8]]])b = torch.tensor([10, 20]) # 形状: (2,)
a
是 3D 张量:形状(2, 2, 2)
b
是 1D 向量:形状(2,)
从右往左比较:
维度位置 | a 的大小 | b 的大小 | 是否兼容 | 说明 |
---|---|---|---|---|
第2维(最右) | 2 | 2 | ✅ 相等 | 规则1 |
第1维 | 2 | ? | ? | b 没有第1维 → 视为 1 ✅ |
第0维 | 2 | ? | ? | b 没有第0维 → 视为 1 ✅ |
所以 b
在广播中被视为形状 (1, 1, 2)
。
然后它被扩展为 (2, 2, 2)
:
[[[10, 20],[10, 20]],[[10, 20],[10, 20]]]
然后与 a
相加。
🔁 广播的“从右往左”原则(非常重要!)
广播总是从最后一个维度开始比较,而不是从第一个。
例子:
a = torch.randn(3, 1) # 形状: (3, 1)
b = torch.randn( 2) # 形状: (2,)
比较:
- 第1维(列):
a
是1
,b
是2
→ 一个为 1 ✅(规则2) - 第0维(行):
a
是3
,b
没有 → 视为 1 ✅(规则3)
✅ 可广播!结果形状 (3, 2)
但如果:
a = torch.randn(1, 3) # (1, 3)
b = torch.randn(2, ) # (2,)
- 第1维:
3
vs2
→ 不相等,且都不为 1 → ❌ 不兼容!广播失败!
✅ 总结:三条规则的通俗理解
规则 | 通俗说法 | 例子 |
---|---|---|
1. 大小相等 | “你们长度一样,可以直接比” | (3,) 和 (3,) |
2. 有一个是 1 | “你只有1个,我可以复制你” | (2, 1) 和 (2, 5) |
3. 一个不存在 | “你维度少,我把你前面补1” | (2, 3) 和 (3,) → (3,) 视为 (1, 3) |