Lab 3 — 张量操作工具箱
概述
PyTorch 张量(Tensor)操作的完整练习。覆盖创建、变形、索引切片、数学逻辑四大类,加上 4 个实战练习。这是深度学习的数据准备基础——所有模型输入都是张量。
四类核心操作
1. 创建
从 Python list、NumPy、pandas 创建,或用工厂函数:
torch.tensor([1, 2, 3]) # 从 list
torch.from_numpy(np_array) # 从 numpy
torch.zeros(3, 4) # 全零
torch.ones(2, 3) # 全一
torch.rand(2, 3) # 均匀分布随机
torch.arange(0, 10, 2) # 等差序列
2. 变形(Shape Ops)
改变张量的维度结构,不改变数据本身:
x.unsqueeze(0) # 在位置 0 插入长度 1 的维度 → (3,) 变 (1, 3)
x.unsqueeze(1) # 在位置 1 插入 → (3,) 变 (3, 1)
x.squeeze() # 删除所有长度 1 的维度
x.reshape(2, 3) # 重排数据到新形状
x.transpose(0, 1) # 交换维度 0 和 1
torch.cat((a, b), dim=0) # 沿维度 0 拼接
3. 索引与切片
x[0] # 第 0 行
x[:, 1:3] # 所有行的第 1~2 列
x[x > 5] # 布尔掩码:取大于 5 的元素
x[[0, 2, 4]] # 花式索引:取指定行
x.item() # 标量张量 → Python 数值
4. 数学与逻辑
a * b # 逐元素乘
a @ b # 矩阵乘(matmul)
a.mean() # 均值
a.std() # 标准差
(a > 5) & (b < 3) # 布尔逻辑组合
实战练习
练习 1:销售分析
给定 3 个产品 × 3 个月的销售数据 sales_data(shape [3, 3]),计算产品 B 的总销售额,并找出产品 C 月销售额超过 130 的月份。
total_sales_product_b = sales_data[1].sum()
high_sales_mask_product_c = sales_data[2] > 130
练习 2:图像批变换
有一批图像 image_batch(shape [10, 32, 32],即 10 张 32×32 灰度图)。需要:加通道维度 → 转置成 [10, 32, 32, 1] 格式。
image_batch_with_channel = image_batch.unsqueeze(1)
# shape: [10, 1, 32, 32]
image_batch_transposed = image_batch_with_channel.transpose(1, 3)
# shape: [10, 32, 32, 1]
练习 3:传感器加权平均
温度和湿度两组传感器数据,用权重 [0.6, 0.4] 计算加权平均值。
combined_data = torch.cat(
(temperature.unsqueeze(0), humidity.unsqueeze(0)), dim=0)
weights = torch.tensor([0.6, 0.4])
weighted_data = combined_data * weights.unsqueeze(1)
weighted_average = torch.sum(weighted_data, dim=0)
练习 4:出租车特征工程
行程数据 trip_data(距离、小时),构造"高峰期长距离行程"特征列。
distances = trip_data[:, 0]
hours = trip_data[:, 1]
is_long_trip = distances > 10.0
is_morning_rush = (hours >= 8.0) & (hours < 10.0)
is_evening_rush = (hours >= 17.0) & (hours < 19.0)
is_rush_hour_long_trip_mask = (is_morning_rush | is_evening_rush) & is_long_trip
new_feature_col = is_rush_hour_long_trip_mask.float().unsqueeze(1)
关键理解
第 0 维 = 批。PyTorch 约定 [batch, features...]。一个张量 [10, 3, 32, 32] 是"10 张 3 通道 32×32 的图"——第 0 维永远是"有几个样本"。
unsqueeze(dim) 的位置决定语义。unsqueeze(0) 加的是"批维度"(从 [3] 变 [1, 3],表示 1 个样本 3 个特征);unsqueeze(1) 加的是"特征维度"(从 [3] 变 [3, 1],表示 3 个样本各 1 个特征)。位置不同,含义完全不同。
广播从最右维对齐。两个张量运算时,维度从右往左对齐。长度为 1 的维度会被"拉伸"复制。所以 [3, 4] * [4] 能算(4 对齐),但 [3, 4] * [3] 会报错(3 和 4 对不上)。
reshape vs transpose。reshape 重排数据到新形状(内存里数据顺序不变,只是切分方式不同);transpose 交换两个维度的顺序(数据排列方式改变)。混用会导致数据错位。