(四)广播、矩阵乘法与形状调整
# 项目文件:demos/shapes.py
import torch
x = torch.arange(6, dtype=torch.float32).reshape(2, 3)
bias = torch.tensor([10, 20, 30])
print("广播相加", (x + bias).tolist()) # 每条样本加同一份三个特征偏置。
w = torch.tensor([[1.0], [0.0], [-1.0]])
print("矩阵乘法", (x @ w).tolist(), tuple((x @ w).shape))
transposed = x.transpose(0, 1)
print("转置连续", transposed.is_contiguous())
print("reshape 展平", transposed.reshape(-1).tolist())
# reshape 保持元素次序;遇到这种非连续布局会准备合适的数据副本。
print("拼批次", tuple(torch.cat([x, x], dim=0).shape))
print("增加一轴", tuple(torch.stack([x, x], dim=0).shape))x 的两行分别为 [0, 1, 2] 和 [3, 4, 5]。长度为三的偏置 [10, 20, 30] 沿每行复用,结果为 [[10, 21, 32], [13, 24, 35]]。广播按末尾维度对齐,先写出各轴长度再做运算,读法与 NumPy 相同。
矩阵乘法 x @ w 的形状是 (2, 3) @ (3, 1) → (2, 1)。第一条结果为 0×1+1×0+2×(-1)=-2,第二条也是 -2。中间的长度三表示每条样本参与加权的三个特征。
transpose 调换轴,改变读取次序。例中转置后的数据不连续,reshape(-1) 按转置后的逻辑次序得到 [0, 3, 1, 4, 2, 5];它会按布局选择复用或复制数据。需要明确的独立数据时使用 clone,不要根据方法名猜共享关系。
cat 沿已有轴接起来,两个 (2, 3) 沿轴零拼成 (4, 3);stack 增加一根轴,把两份数据组织为 (2, 2, 3)。图像批次稍后会用“样本、通道、高、宽”四根轴。