☰
从零搭建深度学习环境:三天跑通PyTorch CNN手写数字识别
2026/10/10 7:05:18 网站建设 项目流程

从零搭建一个能跑通的深度学习环境,我用了整整三天

作为一个正在准备考研的工科生,我的日常本来是数学、英语、政治轮番轰炸。但偏偏在复习《机器学习》这门课的时候,看到“深度学习”这四个字就怎么也绕不过去了。一开始只是想搞懂反向传播的数学推导,结果一头扎进去,从“知道”到“动手做”,中间隔着一整个环境配置的深渊。

这篇记录,就是我作为考研er从零开始做深度学习的第一个项目实录——从环境搭建、基础理论梳理、到跑通第一个真正的PyTorch模型。不吹不黑,只想把这条路上的坑和心得体会写下来,尤其是那些教学视频里不会告诉你的东西,给同样准备入坑的考研人一个参照系。

1. 项目整体设计:为什么考研党也要动手做深度学习

1.1 考研er做深度学习项目的定位与动机

很多人觉得奇怪:考研复习都忙不过来了,干嘛还要碰深度学习项目?我个人的理由有三点,说出来可能跟你想的不太一样。

第一,深度学习在近年考研复试里面出现频率越来越高。尤其是计算机、自动化、电子类的复试环节,很多导师会直接问“你有没有实际跑过模型”“你对深度学习的理解是停留在课本还是真正实践过”。如果只背了课本上“卷积神经网络由卷积层、池化层、全连接层构成”这种话,基本一戳就破。

第二,动手学习确实能反过来帮助理解理论。我一开始推导BP算法的时候,公式看了一遍又一遍,“梯度消失”这个概念总是理解得很抽象。直到自己用代码写了一个两层的全连接网络,把每一层的梯度值打印出来,看到前面几层的梯度真的变得非常小,那一刻才真正懂了什么叫“梯度消失”。这种“看见”的感觉,是纯看课本换不来的。

第三,考研er做深度学习项目其实有一个天然优势——数学基础。因为准备考研,线性代数、概率论这些正在复习中,而深度学习的核心恰恰就是矩阵运算、概率分布和求导链式法则。与其说这是不务正业,不如说是一种知识的交叉验证。

1.2 项目目标设定:不追求SOTA,只追求跑通

我给自己定的目标非常克制:不追任何SOTA(State of the Art)模型,不搞分布式训练,不研究论文复现,就做一件事——在本地电脑上完整跑通一个“用卷积神经网络识别手写数字”的项目。

为什么选手写数字?因为MNIST数据集在深度学习里的地位,跟英语初学者背的ABC差不多:足够小、足够经典、资料足够多。整个数据集就几万张28x28像素的小图,我的笔记本CPU也能扛得住。如果上来就想着跑ImageNet那种千万级数据集,没等训练完,人先放弃了。

项目范围锁定在以下几个方面:

  • 搭建可用的深度学习环境(Python + PyTorch + CUDA可选)
  • 理解数据集加载与预处理流程
  • 搭建一个简单的CNN模型并训练
  • 记录并可视化训练损失和准确率变化
  • 排查并解决训练过程中最常见的问题

这个定位,本质上就是把“深度学习项目开发”这个宽泛概念,缩小成一个考研er在有限时间内能完成、能理解、能复现的最小闭环。

1.3 方案选型:PyTorch而不是TensorFlow

工具选型这一步,其实比很多人想象中更影响后续学习曲线。我在调研阶段对比过TensorFlow和PyTorch,最终选了PyTorch,理由是三个字:舒服、直观、主流。

PyTorch的代码风格非常接近Python原生的写法。比如定义网络结构时,你只需要写一个继承自nn.Module的类,然后在forward里面直接写张量怎么流动。这种“写起来像写普通Python函数”的体验,对初学者极其友好。相比之下,TensorFlow 2.x虽然也改进了很多,但它的Keras高层API封装太狠了,初学者往往会“用得很爽但不知道内部发生了什么”,这对于决心吃透原理的我来说反而不是好事。

另外还有一个很现实的理由:现在的学术圈和大部分深度学习开源项目都在用PyTorch。考研复试如果跟导师聊项目经历,提到PyTorch绝对比提到TensorFlow更贴近当前的研究主流。

2. 深度学习入门知识框架:先理清这棵知识树

2.1 从感知机到深度学习的演进逻辑

我觉得很多考研er第一次接触深度学习,最大的问题不是概念难,而是不知道概念之间怎么串联。在这里我用自己的语言重新梳理一遍这条逻辑链。

一切的核心起点是感知机——一个最简单的二分类模型,输入特征经过加权求和再加偏置,最后过一个阶跃函数输出0或1。感知机的问题在于它只能解决线性可分问题,遇到异或这类简单非线性问题就完全没辙了。为了解决这个问题,人们把多个感知机叠加起来形成“多层感知机”,引入了激活函数让网络拥有非线性表达能力。

接下来就是把多层感知机不断做宽做深。所谓“深度学习”中的“深度”,指的就是网络层数足够多。理论上层数越多,网络的表达能力越强,能拟合越复杂的函数。但随之而来的是两个问题:一是参数量太大,训练很慢;二是梯度在反向传播过程中逐层衰减,前面的层几乎学不到东西,这就是“梯度消失”。

2012年,AlexNet在ImageNet图像识别大赛上以碾压性的优势夺冠,深度学习正式登上历史舞台。AlexNet之所以成功,不只是因为“深”,更因为它用了一系列trick:ReLU激活函数缓解梯度消失、Dropout防止过拟合、数据增强扩充样本量。从此刻开始,深度学习从一个学术边缘话题,变成了改变整个AI行业格局的核心力量。

2.2 机器学习与深度学习的边界在哪里

“机器学习和深度学习到底什么关系”这个问题,如果去问文科大一的学生,我会用一个比方来解释。

机器学习是一大类方法的总称,它的核心是“从数据中自动学习规律”。就像你告诉一个没见过猫的小孩:“有尖耳朵、有胡须、会喵喵叫的就是猫”,然后给他一堆猫和狗的图片,让他自己总结这些特征。传统机器学习方法(比如支持向量机、决策树)的特点在于,它们需要人来“设计特征”——也就是说,你得先告诉算法应该注意哪些特征(比如颜色、纹理、形状),算法再在这堆特征上进行分类或回归。

深度学习则把这个逻辑往前推了一步:特征设计也交给机器自己完成。卷积神经网络通过层层卷积核自动从原始像素中提取边缘、纹理、形状等层次化特征,完全不需要人工指定“该看什么”。还是用猫狗分类的例子:你只需要给网络一大堆打标签的图片,它自己会琢磨出哪些模式是最有区分度的。

所以这个边界其实很清晰:传统机器学习需要人工特征工程,深度学习是端到端自动学习特征。理解了这一点,“为什么深度学习在图像、语音、自然语言处理这些具有复杂高维数据的领域表现碾压传统方法”就顺理成章了。

2.3 深度强化学习、多任务学习这些进阶方向离我有多远

搜索深度学习相关热词的时候,我看到了“深度强化学习”“多智能体深度学习”“如何调整多个loss之间的比例”这些问题。一开始我也焦虑过:是不是这些才是深度学习真正的前沿?我是不是应该一开始就去学这些?

后面我冷静下来分析了一下。深度强化学习(DRL,Deep Reinforcement Learning)研究的思路是让智能体通过与环境交互试错来学习策略,代表作有AlphaGo、自动驾驶决策系统。但这类项目对硬件的要求非常高,套路也极其依赖奖励函数设计,别说考研er,很多硕士研究生入门阶段都啃不动。多任务学习(MTL,Multi-Task Learning)关注的是怎么用一个模型同时完成多个任务,核心难点在于如何平衡多个loss之间的比例——这个问题涉及大量经验调参和理解任务间关系的能力,同样不适合新手阶段去碰。

我的结论是:这些进阶方向跟我的项目无关,但并非完全无关。理解它们的存在和位置,能帮我建立一张关于深度学习全貌的地图,知道我现在做的CNN图像分类只是其中一小块领地。真正的路径应该是先打好基础,把单一任务的CNN吃透,后续再考虑迁移到这些进阶领域。

3. 深度学习环境配置全记录:这个坎,人人都要过

3.1 硬件摸底:我手里的笔记本到底能不能跑

深度学习环境配置是劝退率最高的环节,没有之一。我见过太多人还没跑起来第一个模型,就先被安装依赖搞到崩溃。这个环节,我建议先做硬件摸底,再决定安装策略。

我的机器情况比较尴尬:一台Windows笔记本,8GB内存,显卡是集成显卡,没有独立的NVIDIA GPU。这意味着CUDA(英伟达显卡的并行计算平台)这件事跟我无缘了,只能用CPU跑训练。很多人可能听到CPU训练就觉得不行,其实对于MNIST这种小数据集,CPU训练完全可以接受——一个epoch也就几十秒到几分钟的事。

如果你的电脑有NVIDIA独立显卡,那恭喜你,可以按标准流程安装CUDA和cuDNN;如果没有,老老实实用CPU版本,不要纠结。我的排查思路很简单:显卡决定你能否用CUDA加速,没有NVIDIA显卡就安装CPU版PyTorch,一切以“能跑通”为最高优先级。

3.2 Python虚拟环境与PyTorch安装实操

我选择用Anaconda来管理Python环境和依赖包。为什么不直接用系统Python?因为深度学习涉及的依赖太多太杂,不同项目可能需要不同版本的库,用虚拟环境可以隔离它们,避免“装了这个库把那个库搞崩”的恶性循环。

具体操作步骤,我完整走了一遍:

第一,去Anaconda官网下载Windows版安装包,安装时勾选“Add Anaconda to my PATH environment variable”(网上很多教程让你别勾选,但考研er用命令行多,勾上会省去一堆麻烦)。

第二,打开Anaconda Prompt,创建一个独立的深度学习环境,Python版本不要选太新的,我用的是3.9。命令如下:

conda create -n dl_env python=3.9 conda activate dl_env

第三,安装PyTorch。这里最关键的一点是:不要直接pip install torch,而应该去PyTorch官网的Get Started页面选择自己的配置生成安装命令。因为不同平台、不同CUDA版本对应的安装源不同。CPU版本的命令长这样:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu

这里解释一下为什么我要强调"官网生成命令"。PyTorch的安装包针对CUDA 11.8、12.1等不同版本会分别编译,如果随便安装了一个带CUDA的版本,但你本机没有对应的NVIDIA驱动,运行时就会报错,提示找不到CUDA库。这是环境配置阶段最常见的坑。

3.3 验证安装是否成功:两行代码胜过一切教程

安装完成后,怎么确认环境没问题?不要急着写模型,先跑两行验证经典代码:

import torch print(torch.__version__)

如果显示了版本号,比如2.2.1,说明PyTorch核心模块没问题。再跑一行确认是否能用GPU:

print(torch.cuda.is_available())

我的机器上输出的是False,因为没显卡。如果你的输出是True,说明CUDA环境完全就绪。这里顺便解释一下:torch.cuda.is_available()返回True后,训练代码里还要写device = torch.device("cuda" if torch.cuda.is_available() else "cpu"),然后手动把模型和数据都搬到GPU上,这个操作是初学者特别容易忘的。

3.4 环境配置失败的三大常见原因

第一,Python版本太新。有些博客为了蹭新,让你装Python 3.11或3.12,结果某些依赖库还没有适配,编译报错一堆。建议稳定压倒一切,3.9或3.10最稳妥。

第二,镜像源配置问题。国内直接pip下载速度很慢,甚至超时。我设置了清华镜像源:

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

第三,conda和pip混合安装导致依赖混乱。正确做法是:优先用conda安装能装的东西,conda装不了再用pip,不要两个来回倒腾同一个包。

4. 第一个CNN模型从零搭建:L2正则化的PyTorch实现

4.1 准备数据集:每个人都要过数据处理这一关

MNIST数据集包含10类手写数字,训练集6万张,测试集1万张。我的大项目自然不需要局限在MNIST,但对于这个入门阶段的项目来说,它就是最好的练手数据。

在PyTorch中,加载MNIST只需要用torchvision.datasets.MNIST这个API即可自动下载。不过有两个处理细节必须注意。

第一个细节是数据增强与标准化。深度学习中,input数据的分布对训练稳定性的影响很大。MNIST的原始像素值是0到255之间的整数,直接喂给网络会让loss数值不稳定,收敛也很慢。标准做法是用ToTensor转换为0到1区间的浮点张量,再用Normalize做标准化,让像素均值接近0、方差接近1。对应代码:

transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ])

0.1307和0.3081不是随便写的,这个就是MNIST全体像素的均值和标准差。用这两个值做标准化,相当于把所有图片统一到同一种“尺度”上,网络学起来会舒服很多。

第二个细节是DataLoader机制。PyTorch没有要求一次性把6万张图全搬进内存训练,而是通过DataLoader每次取一小批(batch)数据。这个过程类似流水线作业:一批一批地送进网络,训练完这批再送下一批。标准的配置是batch_size取64或128。

4.2 CNN网络结构拆解:卷积层、池化层、全连接层各司其职

我搭建的网络结构非常经典,结构如下:

  • 第一个卷积块:1个输入通道映射到32个通道,卷积核大小为3x3,padding为1保证特征图尺寸不变,激活函数用ReLU,后面接一个2x2的最大池化层。
  • 第二个卷积块:32个通道映射到64个通道,同样3x3卷积核,ReLU激活,2x2最大池化。
  • 全连接层:将最后一层特征图展平成一维向量,映射到128维,再接ReLU和Dropout。
  • 输出层:128维映射到10维,对应10个数字类别。

为什么这样设计?我可以拆开来说。卷积层负责提取局部特征,比如边缘、拐角、弧线这些笔画特征。卷积核大小选3x3,是因为它是最小的能提取“中心点+周围邻域”信息的尺寸,计算量也小,叠加两层3x3卷积的感受野等效于一个5x5卷积,但参数量更少。池化层的作用是降维,把特征图尺寸减半,这样既能减少计算量,又能增强模型的平移不变性——数字稍微偏移几个像素,池化操作让结果不容易受影响。全连接层则负责把前面提取到的高层特征综合起来做最终分类判断。

这个网络结构虽然简单,但该有的部件都有,而且是理解后续更复杂网络(VGG、ResNet等)的基础底座。

4.3 L2正则化的PyTorch代码实现与原理

L2正则化是热词里提到的重要知识点,也是过拟合的头号杀手。它的思想非常朴素:在损失函数后面加上所有权重参数的平方和乘以一个系数λ,相当于“惩罚”那些数值过大的参数。

引入L2正则化后为什么能防止过拟合?我的理解是这样:模型过拟合的本质是某些权重过大,导致对训练数据中的噪声也进行了精确刻画。L2正则化在损失函数里加一个“参数越大,惩罚越大”的项,这就逼着网络在训练时尽量把权重控制在较小的范围内。权重小了,模型学到的是更平滑、更泛化的规律,而不是死记硬背每一个噪声点。

在PyTorch里实现L2正则化简直不要太方便,因为它的优化器本身就内置了L2正则化参数——weight_decay。很多人不知道,weight_decay的真实身份就是L2惩罚项的系数λ。我的训练配置是:

optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)

这里lr=0.001是Adam优化器最常见的默认学习率,跳过太小收敛慢、太大震荡剧烈的坑;weight_decay=1e-4的数值选择则参考了PyTorch官方示例和经验值,不是越大越好——太大了模型会“过拟合于权重小”这件事本身,导致欠拟合。

如果你非要用自定义方式实现L2正则化,也就是手动在loss上加上惩罚项,代码大致长这样:

l2_lambda = 0.0001 l2_norm = sum(p.pow(2).sum() for p in model.parameters()) loss = loss_func(outputs, labels) + l2_lambda * l2_norm

我建议直接用优化器内置参数,理由有二:一是代码更简洁;二是优化器对正则化的实现做了底层优化(尤其是在Adam中,weight_decay的实现方式跟手写L2并不是完全等价,而是采用了解耦权重衰减的策略),效果更稳定。

4.4 训练循环怎么写:不要被网上那些花哨框架迷惑

网上很多教程喜欢用高级封装来训练模型,比如PyTorch Lightning或者Keras的model.fit()。但我强烈建议至少第一个项目要手写训练循环,因为这样才能看清深度学习训练的本质逻辑。

一个标准的手写训练循环包含六大步骤:

  • 前向传播:输入数据过网络得到预测结果。
  • 计算损失:比较预测结果和真实标签,算出数值。
  • 梯度清零:每个batch训练前要把上一轮保留的梯度清零,否则会累积。
  • 反向传播:计算loss对每个参数的梯度。
  • 更新参数:优化器根据梯度调整参数。
  • 记录数据:保留loss和准确率数值用于后续画图。

这个循环可以简单理解为“考试→改卷→订正”的迭代过程:前向传播是做题,计算损失是判分,反向传播是找出错在哪,更新参数就是订正错题。每个batch重复这个过程,模型就在一圈一圈中被调整得越来越精准。

一个典型训练循环的核心代码如下:

for epoch in range(num_epochs): running_loss = 0.0 for images, labels in train_loader: images, labels = images.to(device), labels.to(device) outputs = model(images) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() running_loss += loss.item() print(f'Epoch {epoch+1}, Loss: {running_loss/len(train_loader):.4f}')

4.5 训练过程中loss曲线的解读与调试心法

我跑了5个epoch,训练日志大概是这样(因为每次运行会有一点点随机波动,这里展示的是我记录的核心pattern):

  • Epoch 1:loss下降很快,从2.3附近一路冲到0.6左右,这说明网络正在快速学习基础的图像特征。
  • Epoch 2–3:loss继续下降,但速度减缓,说明网络进入精细调整阶段。
  • Epoch 4–5:loss趋近于0.1,准确率稳定在98%以上,基本确定模型已经收敛。

怎么判断模型真的在学好?我的判断标准不是只看loss,而是要同时盯一套组合指标:训练loss是否稳定下降、验证准确率是否同步上升、两者之间是否出现背离。

我在这次训练中观察到的典型的场景:训练集loss很低但验证集准确率停止增长甚至下降,这就是过拟合的典型信号。这个时候就该去调大weight_decay,或者增加Dropout的丢弃比例,或者引入数据增强。反过来,如果训练loss本身降不下去,说明模型容量不够(这种情况下就要加更多层或更多通道)或学习率设定不合理。

5. 动手深度学习过程中最该避开的几道弯

5.1 别让“知识焦虑”打乱你的项目节奏

新手做深度学习项目最容易踩的第一个坑,其实是心态问题。我在接触这个领域的时候,经常看到“深度强化学习”“多智能体深度学习”“多任务loss平衡”这些高端名词,一瞬间觉得自己学的东西是不是太小儿科了。这种“知识焦虑”会直接导致两件事:一是频繁换方向,今天看NLP,明天看CV,后天又想去搞强化学习,结果哪个都没学透;二是好高慕远,总想一步到位,看到别人做“基于深度学习的车牌识别与停车场出入管理系统”,就觉得自己做一个“手写数字识别”上不了台面。

拉回来自己的节奏很重要。吴恩达的深度学习课程我专门花时间看了课后题,最大的收获不是某一个具体知识点,而是他反复强调的一条原则:在真正未能在简单问题上取得满意结果之前,不要试图用复杂方法解决简单问题。手写数字识别虽然经典,但把它的完整链路——数据加载到模型训练再到结果评估——全部理清楚,机器学习与深度学习的核心方法论就到手了一半。后续想向“车牌识别”“人脸识别”这类具体应用场景延伸,无非是把数据集换掉、把网络结构调复杂一点、把预处理流程适配一下,思路是完全一致的。

5.2 MNIST上常见的隐蔽陷阱:验证集划分、数据顺序、随机种子

MNIST虽然简单,但坑并不少。我第一次跑的时候,发现验证集准确率一直比网上别人报告的95%低很多,百思不得其解。排查了半天,最后锁定在一个细节上:torchvision.datasets.MNIST的默认划分是直接给训练集和测试集,但我们通常会从训练集里再切出一部分当验证集。网上常见的做法是用torch.utils.data.random_split按7:3切分,问题在于随机切分之后,训练集和验证集的数据分布可能会发生变化,尤其在类别不平衡的情况下更明显。

解决这个问题的最好姿势是设置随机种子:

torch.manual_seed(42)

这样一来,每次运行程序切出来的数据集都是一样的,结果就可复现了。这个设定对深度学习项目来说是基本素养——没有固定的随机种子,你连自己昨天的实验结果都复现不出来,调试就变成了玄学。

另一个隐蔽的问题是数据顺序。DataLoader默认会打乱顺序(shuffle=True),这是合理的。如果shuffle设置为False,模型会先看到所有0再看到1,训练过程会产生非常奇怪的震荡,loss曲线看起来就像心电图。

5.3 边缘计算与云平台:什么时候必须迁移训练环境

我的CPU笔记本能跑MNIST,但如果后续的项目变大——比如做“人声抑制+深度学习”的音频处理任务,或者“基于深度学习的车牌识别与停车场出入管理系统”这种复杂的视觉项目,本机CPU绝对扛不住。有两种方案摆在面前。

第一是本地GPU升级版,即配备RTX 4060或以上显卡的台式机或笔记本。这种方案的优势是完全掌握在自己手里,自由度最高。硬件成本不低,但显卡的算力水平决定你未来一年能玩多大、多快的训练任务。考研党如果预算有限,二手市场的上一代显卡也是不错的选择。

第二是深度学习云平台。目前主流的方案包括AutoDL、阿里云GPU实例、腾讯云GPU服务器等。云平台的本质是租用别人的GPU,按小时计费,结合Jupyter Notebook远程开发。好处显而易见:前期投入小,按需付费,配置环境也比你想象的方便——平台一般会预装好常见的深度学习镜像,上去就能跑。坏处是中长跑训练时费用会积累,如果一天24小时跑,一个月下来也不便宜。

我的建议很明确:用于学习和练手,优先考虑云平台“便宜时段的入门实例”;用于长期研究和复现论文,攒钱配一台自己的NVIDIA独显机器更划算。

5.4 思考题:吴恩达课后题里的经典理念

提到吴恩达深度学习课后题,我想特别展开一点,因为它对考研er的启示价值很大。吴恩达课程的核心逻辑是一个自上而下的框架:先把深度学习拆成“结构化机器学习项目”“神经网络”“卷积网络”“序列模型”几个模块,每个模块再往下拆成具体知识点。

我最喜欢他的一句话是:“机器学习系统的调试,本质上是在做误差分析——先看验证集上哪个类别的错误最多,再集中精力解决那个类别的错误。”这个思路在我这个手写数字项目里同样适用:如果我发现数字7经常被识别成1,那我接下来要做的不是盲目调整个网络的超参数,而是先去看这批被误分类的7到底长什么样。可能是因为手写的7和1在字体上确实很像,那我就需要数据增强,加入更多的笔画变形样本;也可能是因为数据集中样本分布不均匀,那我就需要类别加权。

这种“先定位错误再针对性解决”的思路,和我考研刷题时的逻辑是非常一致的——哪类题型正确率低就先专攻哪类,而不是做一套卷子从头改到尾。这也是我觉得考研er做深度学习项目很“互补”的关键原因。

6. 模型训练完成之后:测试、可视化、反思总结

6.1 测试集的评估指标不是摆设

训练结束后,我在测试集上跑了一下模型的表现。最终结果是测试集准确率98.3%,对于MNIST这个数据集上简单的CNN来说,属于正常的水准。但我需要特别说明的是,这个准确率在MNIST上其实不算多厉害——因为MNIST的灰度图像本身就非常容易识别,稍微好一点的模型随便就能上99%。真正重要的不是你达到了多少,而是你确认真实没见过的数据也能有好的泛化表现。

测试过程中最容易出的问题是什么?我觉得是要区分两个概念:训练时的验证集表现和真正测试时的表现。很多人训练完看着loss很低就以为自己成功了,但实际上这个项目有没有效果,必须以“模型从未见过的数据”作为唯一裁判。MNIST的训练集和测试集是官方严格划分的,所以你在测试集上得到的准确率,才是模型真实水平的体现。

6.2 用tensorboard还是matplotlib:轻量可视化方案推荐

训练过程中loss变化趋势是判断模型状态的关键抓手。我的习惯是用matplotlib把训练loss和测试准确率画成曲线,每跑完一个epoch就更新一次。这样虽然不如TensorBoard那么专业,但胜在轻量,不需要额外安装配置,一页代码就能搞定。

import matplotlib.pyplot as plt plt.plot(range(1, num_epochs+1), history['train_loss'], label='Train Loss') plt.plot(range(1, num_epochs+1), history['test_acc'], label='Test Accuracy') plt.xlabel('Epoch') plt.ylabel('Value') plt.legend() plt.title('Training Progress') plt.show()

如果你用的是云平台上的Jupyter Notebook,画图甚至会直接内嵌显示,比本地更顺滑。

6.3 这一个项目带给我的增量:不仅是技术

复盘这整个项目,除了“会写了那么几十行PyTorch代码”这个表面收获外,有几点体会比较深。

  • 学会了“问题驱动的学习法”:不是先把所有深度学习理论啃完再动手,而是先设立一个项目目标,碰到什么不懂的原理就停下来查什么,学习效率比线性看书高很多。
  • 理解了“环境配置是工程项目的第一道门槛”:上机实践不是说开始就开始的,环境配置上的困难反而帮助我熟悉了Python生态和命令行操作。
  • 影响了“看文献的视角”:考研复试要读导师的文章,以前看论文只看结论,现在会下意识去关注他用了什么网络结构、什么优化器、什么正则化方法,理解多了,论文的阅读速度和审美能力也上去了。

7. 关于这个系列后续的一些想法

搞定了第一个“深度学习环境+CNN训练”闭环之后,我的下一步打算是继续往下走两条线。

第一条线是把L2正则化继续往深处挖:在同样的数据集上,对比不加任何正则化、加L2、加Dropout、加早停等不同方式的效果差异,量化出每种手段对防止过拟合的真实贡献。这条线的价值在于,它可以直接延伸到“如何调整多个loss间的比例”——理解了每个loss项对模型行为的贡献,才能在做多任务深度学的时候,更有根据地调整它们的权重。

第二条线是尝试一个更贴近实际应用的小项目,比如把MNIST的手写数字识别迁移到中文手写汉字识别或者车牌字符识别上。中文手写数据集比MNIST复杂得多,类别多、笔画复杂度高,处理起来会逼着我去学更复杂的数据增强手段和更深的网络结构。

回到最初的问题——考研er应不应该花时间做深度学习项目?我的答案是:做,但一定要克制范围、控制预期、保证闭环。一个能跑通的最小项目,胜过一本只翻了几页的教程书。知识如果没有在机器上真实跑一遍,永远都只是纸面上的概念;而一旦代码在你自己的电脑上从无到有地跑出了准确率,那种正反馈,会让后续所有的学习都变得顺畅。

最后再分享一个我在配置环境过程中发现的小技巧:所有依赖安装完成后,把你最终成功的安装命令、版本号写进一个requirements.txt或者单独Markdown笔记里。不要小看这个动作,当你半个月后重装系统、换新电脑,或者给室友分享这条路径的时候,这份记录会帮你省掉一整天重新踩坑的时间。这个习惯,我觉得比任何一个具体的网络结构都有价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询