公司动态

15天深度学习入门:从CNN到Transformer的实战路径

📅 2026/8/30 16:41:34
15天深度学习入门:从CNN到Transformer的实战路径
深度学习这条路现在确实不挑出身了。做计算机视觉、自然语言处理、量化分析、生物信息、医学影像的人最后都要落到同一个技能栈上神经网络 CNN Transformer PyTorch。这次这篇文章就把“15 天入门深度学习”的路径拆开讲清楚每天学什么、做什么实验、用什么代码验证不搞“从入门到放弃”的拖延流程。这套学习路径的核心思路是先搭语言和数学底座再用 PyTorch 把神经网络、CNN、Transformer 逐个跑通最后落到一个真实任务上。整个过程中最关键的不是背公式而是能自己写出训练循环、调通模型、看到损失下降和结果变化。环境方面建议一台带 NVIDIA 显卡的电脑显存 6G 以上体验会比较顺但不强求CPU 也能跑通大部分入门实验只是慢一些。操作系统 Windows 10/11 或者 Ubuntu 20.04 之后都可以。这篇文章会给出完整的学习路径表、PyTorch 安装命令、网络结构代码、训练验证步骤和常见报错排查方法。你跟着走完 15 天应该能具备独立完成一个图像分类或文本分类小项目的能力也为后续读论文、复现代码、转向大模型相关方向打好底子。1. 15 天学习路径总览先给总表。整个路径分成五个阶段每阶段都有明确的产出物不是“看视频”式的学习而是“写代码”式的学习。阶段天数核心内容每天的验证产出阶段一第1-3天Python 基础、NumPy、导数与矩阵用 NumPy 实现矩阵乘法和梯度计算阶段二第4-6天神经网络基础、激活函数、反向传播从零实现一个两层网络并跑通 MNIST阶段三第7-9天卷积网络 CNN、池化、经典结构用 PyTorch 训练 CNN 完成 CIFAR-10 分类阶段四第10-11天PyTorch 框架核心张量、自动求导、训练循环写出规范的训练/验证/测试流程阶段五第12-13天Transformer 架构、注意力机制、位置编码从零实现一个简化版 Transformer 编码器阶段六第14-15天综合实战与交叉学科应用完成一个图像或文本分类项目并导出结果学习工具链建议是Python 3.9 或 3.10PyTorch 2.xJupyter Notebook 或 VS Code。数学部分不需要先系统刷完整本《高等数学》遇到导数、链式法则、矩阵形状变换时现查现用效率更高。深度学习入门阶段真正高频用到的数学不超过 10 个概念导数、偏导、链式法则、矩阵乘法、向量点积、Softmax、交叉熵、均值方差、归一化、梯度下降。2. 第 1-3 天Python 与数学基础这一阶段的目标不是学会整个 Python 语言而是先具备“能写训练脚本”的能力。重点是 NumPy 和高频数学概念。先检查 Python 环境python --version pip install numpy matplotlib jupyter然后做一个典型实验线性回归的梯度下降。import numpy as np # 生成数据 x np.linspace(0, 10, 100) y 2.5 * x 1.0 np.random.normal(0, 0.5, sizex.shape) # 初始化参数 w, b 0.0, 0.0 lr 0.01 for epoch in range(500): y_pred w * x b loss np.mean((y_pred - y) ** 2) dw np.mean(2 * (y_pred - y) * x) db np.mean(2 * (y_pred - y)) w - lr * dw b - lr * db if epoch % 100 0: print(fepoch {epoch}, loss {loss:.4f}, w {w:.4f}, b {b:.4f})这个例子把导数、链式法则、梯度下降和矩阵运算全部串起来了。第 2 天一定还要做一次矩阵乘法形状的手动推导明确(A, B) (B, C) - (A, C)这个规则因为后面几乎所有公式都和它有关。第 3 天要开始接触 PyTorch 张量但先不装完整 PyTorch先在 NumPy 里做 Softmaxdef softmax(logits): exp_logits np.exp(logits - np.max(logits)) return exp_logits / np.sum(exp_logits) print(softmax(np.array([1.0, 2.0, 3.0])))这一步的意义是让你知道“网络输出变成概率”到底发生了什么。搞懂 Softmax 和交叉熵后续分类任务的损失函数会顺畅很多。3. 第 4-6 天神经网络核心概念这一阶段从“一个神经元”开始逐步扩到多层网络。要掌握的核心概念线性层、激活函数、损失函数、反向传播、过拟合、训练集验证集划分。第 4 天先手动实现一个神经元的计算过程import numpy as np def sigmoid(x): return 1 / (1 np.exp(-x)) def neuron(x, w, b): z np.dot(x, w) b return sigmoid(z) x np.array([0.5, 0.8]) w np.array([0.2, -0.3]) b 0.1 print(neuron(x, w, b))第 5 天写一个两层全连接网络。建议直接基于 NumPy 从零实现别用 PyTorch 的自动求导这样才能理解反向传播每一步在做什么import numpy as np def relu(x): return np.maximum(0, x) def relu_derivative(x): return (x 0).astype(float) np.random.seed(42) X np.random.randn(100, 10) y np.random.randint(0, 2, size(100, 1)) # 初始化 input_dim, hidden_dim, output_dim 10, 8, 1 W1 np.random.randn(input_dim, hidden_dim) * 0.1 b1 np.zeros((1, hidden_dim)) W2 np.random.randn(hidden_dim, output_dim) * 0.1 b2 np.zeros((1, output_dim)) lr 0.05 for epoch in range(1000): # 前向传播 z1 X W1 b1 a1 relu(z1) z2 a1 W2 b2 a2 sigmoid(z2) # 损失 loss -np.mean(y * np.log(a2 1e-8) (1 - y) * np.log(1 - a2 1e-8)) # 反向传播 dz2 a2 - y dW2 a1.T dz2 / len(X) db2 np.sum(dz2, axis0, keepdimsTrue) / len(X) da1 dz2 W2.T dz1 da1 * relu_derivative(z1) dW1 X.T dz1 / len(X) db1 np.sum(dz1, axis0, keepdimsTrue) / len(X) # 更新 W2 - lr * dW2 b2 - lr * db2 W1 - lr * dW1 b1 - lr * db1 if epoch % 100 0: print(fepoch {epoch}, loss {loss:.4f})这步做完你已经掌握了神经网络的“内力”。第 6 天把同样的逻辑迁移到 PyTorch 实现体验自动求导带来的简化。今天不准备一次讲完分点说第 4 天线性层 Sigmoid 单个神经元。第 5 天两层网络从零实现重点是反向传播。第 6 天用 PyTorch 改写两层的反向传播版本。第 6 天代码示例import torch import torch.nn as nn import torch.optim as optim torch.manual_seed(42) X torch.randn(100, 10) y torch.randint(0, 2, (100, 1)).float() model nn.Sequential( nn.Linear(10, 8), nn.ReLU(), nn.Linear(8, 1), nn.Sigmoid() ) criterion nn.BCELoss() optimizer optim.SGD(model.parameters(), lr0.05) for epoch in range(1000): y_pred model(X) loss criterion(y_pred, y) optimizer.zero_grad() loss.backward() optimizer.step() if epoch % 100 0: print(fepoch {epoch}, loss {loss.item():.4f})4. 第 7-9 天卷积网络 CNNCNN 要掌握四个操作卷积、池化、全连接、Dropout。它解决的核心问题是图像数据的空间局部性不需要把每个像素都展开成全连接向量而是通过卷积核提取局部特征。第 7 天先理解卷积的输入输出形状变化。PyTorch 里nn.Conv2d的参数是(in_channels, out_channels, kernel_size)。假设输入是(batch, 3, 32, 32)经过一个nn.Conv2d(3, 16, 3, padding1)后输出是(batch, 16, 32, 32)。第 8 天搭建一个简单 CNN用于 CIFAR-10 分类。CIFAR-10 是 60 张 3 通道 32x32 的彩色图片包含飞机、汽车、鸟等 10 类是入门视觉最常用的数据集之一。如果显卡显存不够把 batch size 调小一点import torch import torch.nn as nn import torchvision import torchvision.transforms as transforms transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ]) trainset torchvision.datasets.CIFAR10(root./data, trainTrue, downloadTrue, transformtransform) trainloader torch.utils.data.DataLoader(trainset, batch_size64, shuffleTrue, num_workers2) class SimpleCNN(nn.Module): def __init__(self): super().__init__() self.conv1 nn.Conv2d(3, 16, 3, padding1) self.conv2 nn.Conv2d(16, 32, 3, padding1) self.pool nn.MaxPool2d(2, 2) self.fc1 nn.Linear(32 * 8 * 8, 256) self.fc2 nn.Linear(256, 10) self.dropout nn.Dropout(0.3) def forward(self, x): x self.pool(torch.relu(self.conv1(x))) x self.pool(torch.relu(self.conv2(x))) x x.view(x.size(0), -1) x torch.relu(self.fc1(x)) x self.dropout(x) x self.fc2(x) return x model SimpleCNN() print(model)第 9 天尝试调整结构把卷积核数量翻倍或者加上 BatchNorm观察训练速度变化。这里要重点理解的是模型容量和过拟合的平衡不要一味把网络堆深CIFAR-10 这种小数据集上几层卷积网络就已经能跑出不错的效果。5. 第 10-11 天PyTorch 环境搭建与核心操作到了第 10 天你会发现前面几天的代码已经用到了 PyTorch但没有系统梳理过。这一阶段把 PyTorch 的核心能力完整过一遍。先讲安装。PyTorch 官网的安装命令生成器是动态的以当前版本示例GPU 版常见安装命令是# CPU 版本 pip install torch torchvision torchaudio # CUDA 11.8 版本示例具体以官网为准 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118安装后验证 CUDA 是否可用import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else CPU only)如果你的显卡是 NVIDIA 30 系、40 系建议直接装 CUDA 11.8 或更新版本对应的 PyTorch。集成显卡或者没有 NVIDIA 显卡就装 CPU 版本入门实验照样能跑只是训练时间会长一些。然后要逐个掌握以下内容torch.Tensor的创建、形状、dtype、device。view、reshape、squeeze、unsqueeze的形状变化。torch.autograd自动求导。torch.nn.Module的搭建方式。torch.utils.data.Dataset和DataLoader。写一个典型的训练脚本结构后面所有任务都套这个框架import torch import torch.nn as nn import torch.optim as optim # 1. 定义模型 model SimpleCNN() # 2. 定义损失和优化器 criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) # 3. 训练循环 for epoch in range(10): model.train() running_loss 0.0 for images, labels in trainloader: optimizer.zero_grad() outputs model(images) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() print(fEpoch {epoch1}, loss {running_loss / len(trainloader):.4f}) # 4. 验证 model.eval() correct 0 total 0 with torch.no_grad(): for images, labels in testloader: outputs model(images) _, predicted torch.max(outputs, 1) total labels.size(0) correct (predicted labels).sum().item() print(fAccuracy: {100 * correct / total:.2f}%)这个框架到后面做 Transformer、目标检测、图像分割几乎都是同样的套路。6. 第 12-13 天Transformer 架构Transformer 是现在大模型的基础架构。它和 CNN 最大的区别在于CNN 通过卷积核处理局部特征Transformer 通过注意力机制直接建模任意两个位置之间的关系。重点掌握注意力公式、多头注意力、位置编码、编码器结构。先看最核心的缩放点积注意力Scaled Dot-Product Attention公式Attention(Q, K, V) softmax(QK^T / sqrt(d_k)) V这里Q是查询K是键V是值。d_k是键的维度除以sqrt(d_k)是为了防止点积结果过大导致 Softmax 梯度消失。用 PyTorch 实现一个简化版注意力import torch import torch.nn as nn import torch.nn.functional as F def scaled_dot_product_attention(Q, K, V): d_k Q.size(-1) scores torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_k, dtypetorch.float32)) weights F.softmax(scores, dim-1) return torch.matmul(weights, V) # 示例输入: batch2, seq_len4, d_model8 Q torch.randn(2, 4, 8) K torch.randn(2, 4, 8) V torch.randn(2, 4, 8) output scaled_dot_product_attention(Q, K, V) print(output.shape) # torch.Size([2, 4, 8])第 12 天把上面的代码跑通重点观察QK^T的形状(batch, seq_len, d_k)乘以(batch, d_k, seq_len)得到(batch, seq_len, seq_len)的注意力权重矩阵。这个矩阵的语义是“序列中每个位置对其他位置的关注程度”。第 13 天实现一个带多头注意力的编码器层。多头就是把d_model拆成多个头分别做注意力再拼起来。目的是一方面降低每头计算量另一方面让不同头关注不同语义信息。这里贴一个简化版多头注意力的核心部分帮助你理解结构import torch import torch.nn as nn import torch.nn.functional as F class MultiHeadAttention(nn.Module): def __init__(self, d_model, num_heads): super().__init__() assert d_model % num_heads 0 self.num_heads num_heads self.d_k d_model // num_heads self.W_q nn.Linear(d_model, d_model) self.W_k nn.Linear(d_model, d_model) self.W_v nn.Linear(d_model, d_model) self.W_o nn.Linear(d_model, d_model) def forward(self, x): batch_size, seq_len, _ x.size() # 1. 生成 Q, K, V 并拆成多头 Q self.W_q(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2) K self.W_k(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2) V self.W_v(x).view(batch_size, seq_len, self.num_heads, self.d_k).transpose(1, 2) # 2. 注意力计算 scores torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.d_k, dtypetorch.float32)) weights F.softmax(scores, dim-1) context torch.matmul(weights, V) # 3. 拼接多头输出 context context.transpose(1, 2).contiguous().view(batch_size, seq_len, -1) return self.W_o(context) x torch.randn(2, 4, 8) mha MultiHeadAttention(d_model8, num_heads2) print(mha(x).shape) # torch.Size([2, 4, 8])Transformer 的完整编码器还包含位置编码、残差连接、LayerNorm 和前馈网络。第 13 天不必先从零写出完整的 Transformer但要把编码器结构图吃透。建议在纸上画出输入经过多头注意力、残差连接、LayerNorm、前馈网络、再次残差连接和 LayerNorm 的完整流程然后动手实现其中一个子模块。如果对“位置编码”不熟悉可以记一个直观结论Transformer 本身是并行处理序列的没有 CNN 或 RNN 天然的先后顺序信息因此必须在输入中加入位置信息否则“我爱你”和“你爱我”会被当作同一个输入。7. 第 14-15 天综合实战与交叉学科案例最后两天把前面所有内容串起来做一个完整项目。推荐二选一图像分类或文本分类。如果时间充足可以两个都做。图像方向直接用第 9 天的 CNN 做 CIFAR-10 分类扩展到完整训练流程包括数据增强、学习率调度、测试集评估。文本方向用 PyTorch 搭一个简化版 Transformer 编码器做垃圾邮件分类或情感分类。文本方向需要的中文分词与词表构建并不复杂可以用最简单的字级别模型。下面给一个文本分类的简化示例把 Transformer 编码器的一部分和分类头接在一起import torch import torch.nn as nn import torch.nn.functional as F class TransformerClassifier(nn.Module): def __init__(self, vocab_size, d_model, num_heads, num_layers, num_classes): super().__init__() self.embedding nn.Embedding(vocab_size, d_model) encoder_layer nn.TransformerEncoderLayer(d_modeld_model, nheadnum_heads, batch_firstTrue) self.encoder nn.TransformerEncoder(encoder_layer, num_layersnum_layers) self.classifier nn.Linear(d_model, num_classes) def forward(self, x): x self.embedding(x) x self.encoder(x) x x.mean(dim1) # 全局池化 return self.classifier(x) model TransformerClassifier(vocab_size1000, d_model64, num_heads2, num_layers2, num_classes2) x torch.randint(0, 1000, (2, 32)) print(model(x).shape) # torch.Size([2, 2])第 14 天跑通这个模型第 15 天做两件事训练并记录准确率曲线、把模型导出为 TorchScript 或 ONNX 格式。导出这一步很重要它让你体验“模型能从 PyTorch 跑到推理服务”的完整链路model.eval() example_input torch.randint(0, 1000, (1, 32)) traced_model torch.jit.trace(model, example_input) traced_model.save(transformer_classifier.pt)如果是交叉学科场景比如医学图像、遥感图像、金融时序预测重点不是换模型而是换数据。把 CIFAR-10 换成自己的领域数据保持训练流程不变就能完成一个领域基础实验。这也是 15 天学习路径最核心的价值掌握一套可复用的训练方法论。8. 常见问题与排查方法问题现象可能原因排查方式解决方案pip install torch下载慢网络源问题查看 pip 源配置使用国内镜像源或官方指定 index-urltorch.cuda.is_available()返回 FalseCUDA 版本不匹配或显卡驱动过旧运行nvidia-smi查看驱动与 CUDA 版本安装匹配的 PyTorch 版本或更新显卡驱动显存不足CUDA out of memorybatch size 过大或输入分辨率过高观察报错信息中的显存占用减小 batch size、降低分辨率或使用混合精度训练 loss 一直不下降学习率过小或网络初始化问题打印每次梯度范数调大学习率或改用 Adam 优化器或检查数据归一化验证集准确率远低于训练集过拟合对比训练准确率和验证准确率增加 Dropout、数据增强减小模型容量模型输出全是同一个类别类别不平衡或学习率过大查看每个类别的输出分布调整类别权重调低学习率尝试 class_weightTransformer 训练很慢序列太长注意力计算量太大观察显存占用和单步耗时缩短序列长度减小模型维度使用梯度累积RuntimeError: shape mismatch张量形状不对查看报错中期望形状和实际形状统一 batch size、embedding 维度等参数Jupyter 内核崩溃内存不足观察系统内存占用减小数据量关掉不用的进程首推的调试方法是“先小后大”先用小数据集、小模型、少量 epoch 把代码跑通再逐步放大。不要一开始就在完整数据集上反复等待那样定位问题会很慢。9. 最佳实践与学习建议把这 15 天的经验浓缩成几条可以长期使用的做法。第一所有实验都要有一套固定的工程目录。建议这样组织project/ ├── data/ # 数据集缓存 ├── models/ # 保存模型权重 ├── outputs/ # 训练日志和可视化结果 └── scripts/ # 训练和测试脚本这样无论是跑实验还是复盘都能快速定位文件。别把模型权重和代码堆在同一个目录里。第二模型训练代码尽量统一成“配置文件 主训练脚本”的结构。用 Python 字典或 YAML 管理参数config { batch_size: 64, lr: 1e-3, epochs: 20, num_classes: 10, model_name: SimpleCNN, device: cuda, }之后更换数据集或调参时只改配置不改动训练代码。这个习惯越早养成越受益。第三每学完一个模型至少做一次“从零实现”和一次“PyTorch 原生实现”的对照。从零实现帮助你理解记忆PyTorch 原生实现帮助你真正落地。这一步虽然费时间但对于后续看懂论文代码、自己搭网络结构至关重要。第四显存不足时先别急着加显卡。可以依次尝试以下手段减小 batch size。降低输入图像分辨率。使用混合精度训练。使用梯度累积模拟大 batch size。关掉不需要的中间变量缓存注意 Python 脚本中不要一直持有大的历史张量。第五遇到不懂的概念不要只看视频建议直接看 PyTorch 官方文档和源码。比如nn.Linear的 forward 实现、nn.TransformerEncoderLayer的源码这些资料比任何教程都精准。刚入门时看源码可能吃力但到第 10 天之后你应该具备“直接看文档理解 API”的能力。10. 总结与下一步这 15 天学完你手里应该有一套完整可运行的 PyTorch 训练流程不再依赖某一份教程的完整代码才能动手而是具备自己搭建网络、跑通训练、排查报错、导出模型的基础能力。CNN 和 Transformer 两条主线也已经铺开后续无论是往计算机视觉方向继续深入还是转向自然语言处理、大模型微调都不会觉得陌生。最容易踩的坑有三个第一个是数学基础不足时硬啃公式导致卡壳这个直接用“用到什么学什么”的方式解决第二个是环境问题比如 CUDA 版本不匹配建议严格按照 PyTorch 官网的安装命令生成器操作第三个是训练流程不熟练总是复制别人代码但跑不出结果解决方法很简单每次实验都强制自己独立写一遍训练循环。下一步可以做的事就是挑一个自己领域的数据集把完整流程跑通。比如你是做医学的就找一个小型医学图像数据集做分类你是做量化的就找一份金融时间序列数据做趋势预测。核心代码保持不变换数据、调参数、看效果这就是深度学习入门到实践最快的一条路径。