深度学习入门最常见的问题不是算法本身,而是路线混乱。打开搜索页,神经网络、卷积网络、Transformer、PyTorch会同时出现在眼前,视频课程动辄上百集,收藏夹越来越满,真正打开命令行时却不知道先装环境还是先补数学。解决这个问题,靠的不是“再多看几遍”,而是建立一条有依赖关系的主线:先理解神经网络如何通过反向传播更新参数,再用卷积网络处理图像,再用注意力机制处理长序列和全局关系,最后用 PyTorch 把每一部分都跑成可验证的代码。
15 天入门到起飞,并不是要把所有视频刷完,而是按主线完成三件事:搭好环境、跑通最小模型、能看懂训练日志。本文按“概念 -> 环境 -> 实现 -> 验证 -> 排错 -> 优化”的顺序展开,前两周分别用 MNIST 和 CIFAR-10 作为验证数据集,第三周进入 Transformer 机制与最小实现,最后给出高频报错排查路径和工程化建议。
1. 先理清路线:为什么神经网络、卷积网络、Transformer 是一条主线
1.1 神经网络是整个链条的地基
深度学习里反复出现的反向传播、梯度下降、激活函数、损失函数、优化器,几乎全部来自神经网络。一个最简单的神经网络由线性变换加非线性激活组成:
- 线性变换负责把输入向量映射到新的空间。
- 激活函数负责引入非线性,否则多层线性变换等价于一层。
- 损失函数衡量预测和真实值的差距。
- 反向传播计算每个参数对损失的梯度。
- 优化器根据梯度更新参数。
先掌握这些概念,再看卷积网络和 Transformer,会发现它们只是在“神经网络如何组织连接”上做了不同设计。如果一上来直接读 Transformer 论文,里面的 Q、K、V 和层归一化会让人困惑,因为你还不清楚它为什么要比全连接层复杂。
1.2 卷积网络解决的是图像里“参数爆炸”的问题
把一张 32x32 的彩色图片展开成向量,长度是 3072,接一个 1024 维全连接层,参数就有约 300 万个。真实图片分辨率更高,全连接层的参数量会大到无法训练。
卷积网络通过两个机制压缩参数:
- 局部连接:每个卷积核只观察输入的一小块区域。
- 权值共享:同一个卷积核在整张图上滑动,提取同一种局部特征。
这种设计天然适合图像,因为图像中的边缘、纹理、颜色变化都是局部模式。CNN 也因此成为计算机视觉的基础模型,后来出现的 Swin Transformer 等视觉 Transformer 也在很多场景下保留了卷积的归纳偏置思路。
1.3 Transformer 解决的是长序列建模问题
在 Transformer 出现之前,RNN、LSTM 是处理文本和时间序列的主流模型。它们的问题是按顺序处理输入,序列越长,计算越慢,且容易丢失早期信息。注意力机制允许每个位置直接和序列中所有位置计算相关性,从而并行处理整个序列,并捕捉长距离依赖。
Transformer 不依赖循环结构,而是依靠“查询-键-值”机制获得全局上下文。因为这个特性,它成了大模型的核心结构。理解 Transformer,不只是为了看懂热门模型,更是为了理解当前深度学习在文本、图像、语音、时间序列上的通用底座。
1.4 15 天学习计划表:每天完成一个可验证的小目标
| 阶段 | 时间 | 核心内容 | 可运行成果 | 验收标准 |
|---|---|---|---|---|
| 环境与基础 | 第 1-3 天 | Python、PyTorch 安装、张量、自动求导、线性层、激活函数 | 在 PyTorch 中完成一次反向传播 | 能打印出x.grad |
| 神经网络实战 | 第 4-6 天 | 损失函数、优化器、训练循环、DataLoader | 用两层神经网络训练 MNIST | loss 下降,训练集准确率超过 90% |
| 卷积网络实战 | 第 7-11 天 | 卷积、池化、填充、图像分类、过拟合排查 | 用 CNN 训练 CIFAR-10 | 测试集准确率超过 60% |
| Transformer 实战 | 第 12-15 天 | 注意力机制、位置编码、多头注意力、TransformerEncoder | 实现一个迷你 Transformer 分类器 | loss 下降,预测结果符合预期 |
每天的时间建议按 1 小时概念理解、2 小时代码实践、半小时笔记整理来分配。不要追求看完所有资料,每天能跑通一个代码,并知道它为什么能跑通,就完成了当天的目标。
2. 第 1 周:神经网络基础与 PyTorch 环境搭建
2.1 先确认 Python、CUDA 与 PyTorch 版本
不管是什么操作系统,建议都用虚拟环境隔离项目依赖。使用 conda 创建环境,可以避免 system Python 被污染:
conda create -n deepintro python=3.10 -y conda activate deepintroCPU 环境在学习和理解算法阶段完全够用。如果电脑有 NVIDIA 显卡,先执行nvidia-smi确认驱动和 CUDA 版本:
nvidia-smi输出中顶部会显示 CUDA Version,比如 12.1。安装 PyTorch 时,以官网给出的匹配命令为准。CPU 版本示例:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cpuGPU 版本示例:
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121安装完成后,用一行代码验证环境是否可用:
python -c "import torch; print(torch.__version__, torch.cuda.is_available())"如果输出True,说明 CUDA 环境正常;如果输出False,接下来所有练习还是可以基于 CPU 完成,只是训练需要更长时间。
| 环境项 | 推荐值 | 说明 |
|---|---|---|
| Python | 3.10 或 3.11 | PyTorch 2.x 支持较好 |
| PyTorch | 2.x 稳定版 | 先看官网选择匹配版本 |
| CUDA(GPU 环境) | 以nvidia-smi显示为准 | 驱动保持最新,避免版本冲突 |
| torchvision | 与 torch 版本对应 | 包含 MNIST、CIFAR-10 等数据集接口 |
2.2 最小代码:张量与自动求导
PyTorch 的核心不是把模型写出来,而是自动求导。你只需要定义计算过程,框架会记录运算图并计算梯度。
import torch x = torch.tensor([2.0, 3.0], requires_grad=True) y = x.pow(2).sum() y.backward() print(x.grad)预期输出是tensor([4., 6.])。x.pow(2)的导数是2*x,所以 2 对应 4,3 对应 6。这段代码说明了三件事:
requires_grad=True表示要追踪这个张量上的运算。backward()从损失开始反向传播。x.grad保存每个输入对y的梯度。
理解这个机制后,训练神经网络就只是一个循环:前向计算损失、反向传播梯度、优化器更新参数。
2.3 跑通一个完整训练循环:两层网络训练 MNIST
MNIST 是 28x28 的手写数字灰度图,共 10 类。它是最适合入门的数据集,因为你可以在 CPU 上几秒内完成一次训练。
import torch import torch.nn as nn from torch.utils.data import DataLoader from torchvision import datasets, transforms transform = transforms.ToTensor() train_data = datasets.MNIST(root="./data", train=True, download=True, transform=transform) train_loader = DataLoader(train_data, batch_size=64, shuffle=True) model = nn.Sequential( nn.Flatten(), nn.Linear(28 * 28, 128), nn.ReLU(), nn.Linear(128, 10), ) loss_fn = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) for epoch in range(3): total_loss = 0 for images, labels in train_loader: optimizer.zero_grad() outputs = model(images) loss = loss_fn(outputs, labels) loss.backward() optimizer.step() total_loss += loss.item() print(f"epoch {epoch + 1}, avg_loss={total_loss / len(train_loader):.4f}")关键点有三个。第一,optimizer.zero_grad()必须放在反向传播之前,否则梯度会累积。第二,nn.CrossEntropyLoss()内部已经包含 softmax,不需要在模型最后再手动加 softmax。第三,DataLoader会自动把数据拆成 batch,batch_size影响显存占用和训练稳定性。
2.4 验证:loss 下降只是第一步,还要看准确率
loss 下降只能说明模型在“学”,不能说明分类准。需要单独统计正确率:
correct = 0 total = 0 with torch.no_grad(): for images, labels in train_loader: outputs = model(images) preds = outputs.argmax(dim=1) correct += (preds == labels).sum().item() total += labels.size(0) print(f"train accuracy: {correct / total:.4f}")两层网络训练 3 轮后,训练集准确率通常可以达到 95% 以上,具体数值取决于随机初始化。使用with torch.no_grad()是为了在评估时不构建计算图,避免浪费内存和算力。
这一周最常遇到的坑是忘记zero_grad(),导致 loss 反复震荡;另一个是把数据直接输入网络而没有用Flatten(),导致Linear层收到三维张量报 shape 错误。
3. 第 2 周:卷积神经网络与图像实战
3.1 从全连接到卷积:局部连接、权值共享、平移不变性
卷积层保持输入的空间结构,不把图像展开成一维向量。每个卷积核是一个小窗口,比如 3x3,在图像上滑动并计算点积。
- 局部连接:每个输出值只看输入对应位置的局部区域。
- 权值共享:同一个卷积核在所有位置复用,因此参数量只和卷积核尺寸、输入输出通道数有关,和图片大小无关。
- 平移不变性:同一类特征无论出现在图像左上角还是右下角,都会被同一个卷积核检测到。
padding的作用是控制特征图尺寸。kernel_size=3, padding=1时,输出尺寸和输入尺寸保持一致。stride控制滑动步长,步长大于 1 可以主动降采样。MaxPool2d是常见的下采样方式,它取局部区域最大值,保留显著特征并减少计算量。
3.2 用 PyTorch 搭建 CNN 训练 CIFAR-10
CIFAR-10 是 32x32 的彩色图像,共 10 类,比 MNIST 更难。下面的模型包含两个卷积块和一个分类头:
import torch.nn as nn class SimpleCNN(nn.Module): def __init__(self): super().__init__() self.features = nn.Sequential( nn.Conv2d(3, 16, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2), nn.Conv2d(16, 32, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2), ) self.classifier = nn.Sequential( nn.Flatten(), nn.Linear(32 * 8 * 8, 10), ) def forward(self, x): return self.classifier(self.features(x))输入是 3 通道的 32x32 图片。第一个MaxPool2d(2)后变成 16x16,第二个之后变成 8x8,所以Flatten后维度是32 * 8 * 8。这个数字不是猜出来的,而是根据输入尺寸和池化次数推导出来的。实际项目里可以用一行代码打印中间 shape 来确认:
import torch x = torch.randn(1, 3, 32, 32) model = SimpleCNN() print(model.features(x).shape)输出torch.Size([1, 32, 8, 8]),与全连接层的输入对应。
加载 CIFAR-10 时要注意归一化。图像像素在 0 到 255 之间,ToTensor()会缩放到 0 到 1。为了让数据分布更稳定,通常还要用数据集的均值和标准差做标准化:
from torchvision import datasets, transforms transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)), ]) train_data = datasets.CIFAR10(root="./data", train=True, download=True, transform=transform)训练循环可以复用第 2.3 节的代码。如果继续用 Adam,lr=0.001是一个稳妥起点;如果用 SGD,一般需要更小学习率,并搭配动量。
3.3 Conv2d 参数速查表
| 参数 | 含义 | 常见值 | 错误表现 |
|---|---|---|---|
in_channels | 输入通道数 | 灰度图为 1,RGB 为 3 | 输入通道不匹配会直接报错 |
out_channels | 卷积核数量,也是输出通道数 | 16、32、64 | 输出通道过多导致显存压力大 |
kernel_size | 卷积核大小 | 3、5 | 感受野改变,特征尺度变化 |
stride | 滑动步长 | 1、2 | 步长过大会丢失细节 |
padding | 输入边缘填充 | 0、1 | 特征图尺寸会变小 |
bias | 是否加偏置 | True | 影响参数量和表达能力 |
3.4 用 TensorBoard 观察训练曲线
只盯着终端里的 loss 数字,很难判断过拟合和训练是否稳定。建议从第一天开始就使用 TensorBoard:
pip install tensorboard在训练循环中写入指标:
from torch.utils.tensorboard import SummaryWriter writer = SummaryWriter("runs/cnn_cifar10") step = 0 for epoch in range(10): for images, labels in train_loader: optimizer.zero_grad() outputs = model(images) loss = loss_fn(outputs, labels) loss.backward() optimizer.step() step += 1 writer.add_scalar("train/loss", loss.item(), step)启动命令:
tensorboard --logdir runs打开终端输出的地址,就能看到 loss 曲线。如果训练集 loss 一直下降,测试集准确率却停滞或下降,就说明过拟合。常见缓解方式是增加数据增强、加入 Dropout、降低模型容量或提前停止训练。
CIFAR-10 的简单 CNN 训练十几个 epoch 后,测试准确率参考值在 60% 到 70% 之间,具体取决于随机种子、数据增强和优化器设置。不要和三年前的 SOTA 结果比,这一阶段的目标是验证“模型确实在学,而且没写错”。
4. 第 3 周:Transformer 机制与进阶实践
4.1 注意力机制:用“查询、键、值”理解
注意力机制可以理解为在一个数据库里做检索。给定一个问题,即查询向量 query,和所有候选答案的标识 key,先计算 query 和每个 key 的相似度,再用相似度作为权重去加权求和对应 value。
缩放点积注意力的公式为:
Attention(Q, K, V) = softmax(Q * K^T / sqrt(d_k)) * V
用 PyTorch 实现最小版本:
import torch import torch.nn.functional as F def attention(query, key, value): d_k = query.size(-1) scores = torch.matmul(query, key.transpose(-2, -1)) / (d_k ** 0.5) weights = F.softmax(scores, dim=-1) return torch.matmul(weights, value)除以sqrt(d_k)是为了防止点积结果过大,导致 softmax 进入梯度饱和区。初学者最容易忽略这一步。
4.2 Transformer 的核心组件
一个标准的 Transformer 编码器由以下部分组成:
- Embedding:把离散 token 映射为连续向量。
- 位置编码:给每个位置注入顺序信息。最简单的方法是使用可学习的位置编码,经典实现是正弦位置编码。
- 多头注意力:把 Q、K、V 投影到多个子空间,分别计算注意力,再拼接线性变换,让模型能关注不同关系。
- 前馈网络:对每个位置的表示做逐位置非线性变换,一般是两层 Linear 加 ReLU。
- LayerNorm 和残差连接:稳定训练,缓解深层网络梯度问题。
理解 Transformer 时不要一次性陷进所有细节,先看完整的模块连接关系,再逐步拆解多头注意力。实际工作中大多数场景不需要从零造轮子,直接使用 PyTorch 的nn.TransformerEncoderLayer就足够。
4.3 用 PyTorch 实现一个迷你 Transformer 分类器
下面是一个文本二分类的最小模型。这里使用可学习位置编码,适合入门;经典论文里的正弦位置编码在代码仓库中更容易找到。
import torch import torch.nn as nn class MiniTransformerClassifier(nn.Module): def __init__(self, vocab_size, d_model=64, nhead=4, num_layers=2, num_classes=2, max_len=128): super().__init__() self.embedding = nn.Embedding(vocab_size, d_model) self.pos_encoding = nn.Parameter(torch.randn(1, max_len, d_model)) encoder_layer = nn.TransformerEncoderLayer( d_model=d_model, nhead=nhead, batch_first=True, ) self.encoder = nn.TransformerEncoder(encoder_layer, num_layers=num_layers) self.classifier = nn.Linear(d_model, num_classes) def forward(self, x): emb = self.embedding(x) + self.pos_encoding[:, : x.size(1), :] hidden = self.encoder(emb) return self.classifier(hidden.mean(dim=1))使用说明:
batch_first=True让输入形状是(batch, sequence_length),更符合 PyTorch 常见习惯。hidden.mean(dim=1)是对序列所有位置取平均,作为整句表示,再送入分类器。- 如果处理文本,需要先把句子转成 token id 列表,并保证同 batch 内等长。
构造一个很小的训练数据:
sentences = [ ("good movie and great plot", 1), ("bad film and boring story", 0), ] vocab = {} for text, _ in sentences: for word in text.split(): if word not in vocab: vocab[word] = len(vocab) def encode(text, max_len=8): ids = [vocab[word] for word in text.split()] ids = ids[:max_len] ids += [0] * (max_len - len(ids)) return torch.tensor(ids, dtype=torch.long) x = torch.stack([encode(text) for text, _ in sentences]) y = torch.tensor([label for _, label in sentences]) model = MiniTransformerClassifier(vocab_size=len(vocab), d_model=32, nhead=2) output = model(x) print(output.shape)这里用0作为 padding id,但模型内部没有 padding mask。在真实项目中,遇到变长 batch 时通常会生成 attention mask,避免 padding 位置参与注意力计算。这个细节可以作为第三周的扩展练习。
训练循环仍可复用第 2.3 节的结构,唯一区别是输入从图像变成了 token id 张量。
4.4 进阶扩展:TCN、Swin Transformer 与浮点数格式选型
Transformer 并不是唯一的序列建模方案。TCN,即时间卷积网络,使用因果卷积和膨胀卷积处理时间序列,在股票预测、传感器数据预测等场景中被频繁使用。它的优点是结构简单、训练稳定,缺点是感受野受卷积层数和膨胀系数限制。入门阶段可以用“TCN + Transformer 预测股票价格”的公开案例来练习数据处理和预测评估,但不要把它当作投资建议,这类项目更适合学习特征工程、序列切分和模型评估。
视觉方向可以继续阅读 Swin Transformer。它在窗口内计算注意力,窗口之间通过移动窗口完成信息交互,解决了直接在整张图上计算注意力导致的计算量过大的问题。
训练和部署阶段都会遇到浮点数格式选择。常见的四种格式如下:
| 格式 | 位数 | 特点 | 典型场景 |
|---|---|---|---|
| fp32 | 32 | 精度高,范围广,默认格式 | 学习和稳定训练 |
| fp16 | 16 | 节省显存,动态范围小,需要 loss scaling | 混合精度训练 |
| bf16 | 16 | 动态范围接近 fp32,精度较低 | 大模型训练 |
| tf32 | 不用于存储 | NVIDIA Tensor Core 上的截断格式,降低计算精度提升吞吐 | 大规模矩阵运算加速 |
学习阶段默认使用 fp32。显存不足或在训练大模型时,可以使用混合精度:
scaler = torch.cuda.amp.GradScaler() for images, labels in train_loader: optimizer.zero_grad() with torch.autocast(device_type="cuda", dtype=torch.float16): outputs = model(images) loss = loss_fn(outputs, labels) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()这个写法只在 CUDA 环境有效。CPU 环境直接使用 fp32 即可。
5. 高频报错与排查路径:15 天内最常遇到的坑
5.1 PyTorch 安装后torch.cuda.is_available()为 False
现象:代码能运行,但训练速度很慢,打印 CUDA 状态时输出 False。
可能原因:安装的是 CPU 版 PyTorch;NVIDIA 驱动版本过低;GPU 硬件过老或非 NVIDIA 显卡。
检查方式:
nvidia-smi python -c "import torch; print(torch.__version__)"处理建议:先确认显卡是否为 NVIDIA GPU;再确认torch.__version__中是否包含cu118或cu121等标识;如果不包含,重新按官网命令安装 GPU 版本。AMD 或 Intel 显卡则要查找对应 ROCm 或其他后端说明,不能照搬 NVIDIA 的安装命令。
5.2 张量形状不匹配
现象:
RuntimeError: mat1 and mat2 shapes cannot be multiplied可能原因:全连接层的输入维度和上一层的输出不一致;卷积层的通道数填错;nn.Flatten()放错位置。
处理方式:在模型forward里临时打印 shape,分步确认:
def forward(self, x): x = self.features(x) print(x.shape) return self.classifier(x)推荐做法:先写清楚每一层输入输出的推导公式,再写代码。比如 CIFAR-10 经过两个MaxPool2d(2),尺寸从 32 变成 8,通道数是 32,因此Linear的输入是32 * 8 * 8。
5.3 CUDA out of memory
现象:
RuntimeError: CUDA out of memory.可能原因:batch_size过大;输入图片尺寸过大;多个进程同时占用显存;模型在训练后没有释放计算图。
处理建议:
- 调小
batch_size,比如从 64 降到 32 或 16。 - 降低输入图片分辨率。
- 检查是否有其他进程占用 GPU:
nvidia-smi- 在评估代码中使用
with torch.no_grad(),减少显存占用。 - 确实需要大 batch 时,可以使用梯度累积,将多个小 batch 的梯度累加后再更新参数。
5.4 训练 loss 不下降或出现 NaN
可能原因:学习率过大,梯度更新不稳定;数据没有归一化;损失函数和模型输出不匹配;标签编码错误。
排查顺序:
- 打印第一个 batch 的 loss,确认不是数据问题。
- 尝试小学习率,比如
1e-4。 - 检查数据中是否存在 NaN 或极端值。
- 确认分类任务使用了
CrossEntropyLoss,标签是整数索引而不是 one-hot。 - 如果使用 float16 训练,检查是否遗漏了
GradScaler。
5.5 过拟合:训练集准确率很高,测试集准确率低
这是样本数量少时最常见的现象,也是“深度学习样本数量少的缺点”的直接体现。处理思路按优先级排列:
| 优先级 | 方法 | 说明 |
|---|---|---|
| 1 | 增加数据增强 | 随机裁剪、翻转、旋转等,扩大有效数据分布 |
| 2 | 降低模型容量 | 减少卷积核数量或隐藏层宽度 |
| 3 | 加入 Dropout | 在分类头之前加nn.Dropout(0.5) |
| 4 | 早停 | 监控验证集指标,不再下降时停止训练 |
| 5 | 迁移学习 | 使用 ImageNet 预训练模型做微调,而不是从零训练 |
6. 从 15 天练习到工程化:资料选择、环境差异与长期路线
6.1 学习资料选择:官方文档优先,视频只做辅助
入门阶段最重要的资料是 PyTorch 官方教程和torchvision自带的示例代码。官方文档的代码能运行、能验证,且版本同步。视频课程的优点是讲解直观,缺点是容易让人产生“看懂了”的错觉。
更有效的学习方式是“最小闭环法”:每学一个模型,立刻找一个公开数据集跑通,记录 loss 曲线、准确率和碰到的问题。不要同时开三本书,也不要从一个零散项目跳到另一个零散项目。
推荐记录格式:
- 模型结构
- 数据来源和预处理方式
- 超参数:batch_size、学习率、epoch 数
- 训练集 loss 曲线
- 测试集指标
- 下一次想改变什么
6.2 学习环境与生产环境的差异
学习环境可以很随意:CPU 或单显卡、小数据集、不追求效率。生产环境必须额外考虑:
- 数据管线是否稳定,训练数据是否带版本。
- 日志是否完整,能否定位到具体训练步骤。
- 模型版本是否记录,谁改过结构、改过参数。
- 推理延迟和吞吐是否满足业务要求。
- 模型异常时如何回滚。
- 数据分布发生变化时如何监控。
学习代码里最常见的“只保证能跑”的写法,在生产里都要打上补丁。例如训练脚本里直接写死路径、不保存 checkpoint、不记录超参数,这些在 15 天练习阶段可以接受,但进入真实项目前要补全。
6.3 不同学科背景的补充学习建议
如果数学基础偏弱,不需要先把所有数学课学完再开始。按需要补:
- 线性代数:重点看矩阵乘法、维度变化,卷积和注意力都用得到。
- 概率统计:重点看 softmax、交叉熵、采样,理解模型输出如何解释为概率。
- 微积分:重点看链式法则,它是反向传播的基础。
如果 Python 基础偏弱,先补numpy、列表推导、函数定义、文件读写和调试技能。深度学习的代码 60% 时间花在数据清洗和 shape 调整上,Python 基本功直接决定效率。
如果是物理、材料、金融、医学等非计算机背景,可以把精力放在“如何把本专业问题变成输入输出映射”。比如物理问题可以用 PINN(物理信息神经网络)建模偏微分方程;材料数据可以用图神经网络 GNN 表示分子结构;金融时序数据可以用 TCN 或 Transformer 做预测。这些方向都需要先有前 15 天的主线基础,再进入领域定制。
6.4 15 天后的延伸方向
15 天学完并不是终点。真正让新手和熟练开发者拉开差距的,是每次训练结束后能不能说明白为什么收敛、为什么卡住,以及下一步该改什么。
可以选择的延伸方向:
- 视觉方向:继续学习 Swin Transformer、目标检测模型、图像分割。
- 序列方向:继续学习 LSTM、TCN、Transformer 的时间序列预测。
- 图数据方向:学习图神经网络 GNN,处理社交网络、知识图谱和分子结构。
- 物理融合方向:学习 PINN,理解如何把物理方程作为约束加入训练。
- 工业部署方向:学习 ONNX 导出、fp16/bf16 量化、TensorRT 和 GPU 加速推理。
- 大模型方向:学习预训练、微调、LoRA、RLHF 的基础链路。
6.5 可复用清单
环境检查清单:
- [ ] Python 版本与虚拟环境是否激活。
- [ ] PyTorch 版本是否与 CUDA 匹配。
- [ ]
nvidia-smi输出是否正常。 - [ ]
torch.cuda.is_available()是否输出 True,或者确认 CPU 环境可用。
训练前检查清单:
- [ ] 输入数据的 shape 是否符合模型要求。
- [ ] 是否做了归一化或标准化。
- [ ] 损失函数是否和任务类型匹配。
- [ ] 优化器是否创建在
model.parameters()上。 - [ ] 每次迭代是否调用了
optimizer.zero_grad()。 - [ ] 是否保存了 checkpoint,路径和命名是否包含轮次。
收尾评估清单:
- [ ] 训练集和测试集都统计了准确率或对应指标。
- [ ] 记录了训练过程中的 loss 曲线。
- [ ] 保存了模型结构和超参数信息。
- [ ] 必要时导出混淆矩阵,确认哪些类别最容易混淆。
- [ ] 写下一轮实验的修改点,而不是盲目调参。
建议用固定模板记录每一次实验。坚持记录三个完整项目后,你会发现自己能快速定位问题,也能在面试和实际协作中清楚描述自己的训练过程。那时的“入门”才算真正结束。