阶段:S0-环境搭建与验证 | 预计耗时:45-60 分钟 | 前置:S0-01 环境验证 代码:本篇代码要你自己敲成
model-learn/s0_tensor_warmup.py(照 S0-01 的方式跑)
学习目标
- 理解张量 = 多维数组,训练里所有数据(图片、表格、文字、参数)都是张量
- 掌握 5 个日常操作:看形状
shape、取数据索引、变形reshape、沿维度聚合、广播 - 能解释 MNIST 的一个 batch 为什么是
(64, 1, 28, 28)而不是(64, 28, 28)
核心知识
1. 张量就是"带形状的数组"
- 0 维 = 标量(一个数,比如 loss);1 维 = 向量(一层参数);2 维 = 矩阵(一批灰度图);4 维 = 一批彩色图
- 两个最重要的属性:
shape(形状)和dtype(元素类型)。训练中 80% 的报错都是 shape 或 dtype 不对
2. reshape 不复制数据
reshape/view 只是换个方式"看"同一块内存——60000 张 28×28 图和 60000×784 的矩阵是同一份数据的两种形状。
3. 广播(broadcasting):形状不同的张量做运算的补齐规则
从最后一位往前比:相等、或其中一方是 1,就能对上;对不上的维度报错。
4. 本机习惯:device 永远是 cpu
你无 CUDA。代码里可以写 x.to(device) 配合 device = "cuda" if torch.cuda.is_available() else "cpu"——这样以后拿到 GPU 机器代码不用改。
实验任务
任务 1:敲出热身脚本(20 分钟)
把下面代码敲成 model-learn/s0_tensor_warmup.py,每行输出先自己预测再运行:
# s0_tensor_warmup.py —— 张量热身:形状、索引、变形、聚合、广播
import torch
a = torch.arange(12).reshape(3, 4)
print("a =", a)
print("shape:", a.shape, "dtype:", a.dtype)
print("a[1, 2] =", a[1, 2]) # 单个元素
print("a[:, 1] =", a[:, 1]) # 整列
print("reshape(2, 6) 形状:", a.reshape(2, 6).shape)
print("按行求和 shape:", a.sum(dim=1).shape, a.sum(dim=1)) # 每行 4 个数加起来
print("按列求和 shape:", a.sum(dim=0).shape, a.sum(dim=0)) # 每列 3 个数加起来
b = torch.ones(3, 1)
print("广播 (3,4)+(3,1) →", (a + b).shape) # 列向量加到每一列
# MNIST 的真实形状链
batch = torch.zeros(64, 1, 28, 28)
print("一个 MNIST batch:", batch.shape,
"占内存:", batch.numel() * 4 / 1024**2, "MB")
print("展平后:", batch.reshape(64, 784).shape)
任务 2:广播判断题(10 分钟,先猜再验证)
import torch
# 每行先写"能不能运算、结果形状",再运行验证
print((torch.zeros(3, 4) + torch.zeros(4)).shape) # (3,4)+(4,)?
# print((torch.zeros(3, 4) + torch.zeros(3)).shape) # (3,4)+(3,)? 猜完再取消注释
print((torch.zeros(3, 1) + torch.zeros(1, 4)).shape) # (3,1)+(1,4)?
任务 3:和 numpy 互转(5 分钟)
import numpy as np
n = np.arange(6).reshape(2, 3)
t = torch.from_numpy(n) # numpy → tensor(共享内存)
back = t.numpy() # tensor → numpy
print(t, back.dtype)
验收标准
衔接下一阶段
张量会玩了 → S1-00 训练是什么:这些数组是怎么被"训练"起来的。