尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CIFAR-10图像分类实战:用轻量CNN跑通PyTorch全流程

CIFAR-10图像分类实战:用轻量CNN跑通PyTorch全流程 做过第一个深度学习项目之后很容易陷入一种“能跑通就以为会了”的错觉。尤其当你只是照着教程敲了一遍代码看着loss下降、准确率升到90%潜意识里就会觉得自己已经掌握了深度学习。真到了第二个项目很多人会突然卡住——为什么换了个数据集就差这么多为什么网络深了反而变弱为什么加了数据增强训练损失反而降不下去我这次做的东西就是专门来治这个“似懂非懂”的用轻量CNN在CIFAR-10数据集上做图像分类。CIFAR-10是图像分类领域最经典的入门数据集之一60000张32×32的彩色小图、10个类别比MNIST有挑战性又比ImageNet亲民得多。整个项目不追求榜单上的SOTA目标只有一个用一套完全可控的轻量卷积神经网络把数据预处理、模型结构、训练配置和评估方法从头到尾跑明白。这个项目适合的人群很明确——刚跑通第一个MNIST数字识别或房价预测之类入门项目、想真正理解卷积神经网络工作原理的同学。我会把从环境准备、数据处理、网络设计到训练调参、问题排查的完整路径都拆开讲清楚包括那些教程里不写但实际必踩的坑。这篇文章既是我自己的项目总结也希望能帮你少走一段弯路。1. 项目整体设计为什么第二个项目我选了CIFAR-10配轻量CNN1.1 为什么CIFAR-10是比MNIST更合适的进阶数据集第一个项目用MNIST几乎是深度学习入门的默认选项因为它足够简单28×28的灰度图白底黑字类别区分度大随便一个两层的全连接网络就能跑到97%以上。但问题也在这MNIST的简单掩盖了大量真实问题比如图像增强怎么做、归一化对训练有多大影响、网络容量和过拟合怎么平衡。你很难在MNIST上体会到这些事因为数据本身太“干净”了。CIFAR-10恰好补上了这个缺口。它是真实的自然图像32×32的彩色图虽然分辨率依然很低但已经包含了背景、纹理、光照变化这些真实因素。同样是“猫”这个类别有的照片是猫的正面特写有的照片里猫只占画面的一小块这种类内差异让模型的泛化能力真正受到考验。轻量CNN在MNIST上跑到99%不稀奇在CIFAR-10上能稳定跑到75%以上就算是入门过关了。这个准确率差距不是模型不行而是数据难度本身摆在那。更重要的是CIFAR-10的尺寸非常适合做各种实验。32×32的图占内存小一个batch的GPU显存开销很低即使没有独立显卡靠CPU也能在可接受的时间内跑完一个完整训练流程。数据集大小也合适——训练集50000张测试集10000张——足够训练一个小规模网络又不会让每一轮训练等得让人失去耐心。从工程角度说这个数据规模是拿来练手的最佳区间。1.2 为什么用轻量CNN而不是上来就上大模型现在很多人一提到图像分类就直接上ResNet50、EfficientNet甚至各种预训练模型。我个人的建议是在第二个深度学习项目里千万不要这么做。原因有两个。第一个原因是过拟合的风险。预训练大模型的参数量动辄上千万甚至上亿而CIFAR-10只有5万张训练图你拿一个超大模型直接去拟合它大概率是训练集准确率接近100%、测试集准确率低得离谱。初学者看到这种结果很容易误以为是代码写错了实际上是模型容量和数据量严重不匹配。反而是一个参数量控制在百万级别的小网络在没有预训练权重的情况下也能老老实实地学到有意义特征。第二个原因是理解成本。大模型内部的残差连接、瓶颈结构、归一化策略一层叠一层出了问题你根本不知道是哪一层导致的。轻量CNN就不一样——两层卷积、两层池化、一层全连接每一层的作用都可以单独观察和验证。我在做这个项目时特意把每个中间层的输出尺寸都算了一遍确保脑子里对数据流、参数流有完整印象。这种“可解释性”对初学者来说是极其宝贵的。这里说的“轻量”我给自己定的标准是参数量不超过500万单次前向推理在普通CPU上不超过几十毫秒整个训练流程可以在一台没有独立显卡的电脑上跑完。这个标准并不严格但它保证了项目的核心精力放在理解原理上而不是耗在等待训练和调显存上。1.3 硬件约束下的策略选择做深度学习项目绕不开硬件问题。我这次主要用的是带RTX 3060的台式机同时也在另一台纯CPU的笔记本上做过对照实验想验证一下这套方案在低配环境下是否可行。实测下来这个轻量CNN的方案在两种环境都能顺利跑完只是时间成本差很多。在GPU上一个epoch训练50000张图大约需要10到15秒30个epoch总计七八分钟在CPU上一个epoch可能要2到3分钟30个epoch大概一小时出头。所以如果你手上只有CPU我建议把epoch数从30降到15左右并把batch size从128减到64这样总耗时能控制在半小时内准确率只会差两三个百分点。深度学习入门阶段跑通和看懂是第一优先级没必要为了一个百分点去硬等机器的算力。这里还有个小技巧如果机器性能确实很差可以把CIFAR-10的图像进一步缩小到24×24再送进网络甚至把图片转成灰度图牺牲一些准确率但能让整套流程的运行速度快上不少。这种“降级处理”在真实项目里也经常用到尤其是做算法原型验证的时候。算力不够就通过简化输入来换取实验迭代速度这笔账怎么算都划算。2. 轻量CNN的核心细节从数据预处理到训练配置2.1 数据预处理归一化、数据增强和测试集的“不变式”很多初学者拿到图像数据直接扔给模型开训这是最容易埋雷的地方。图像数据如果不做预处理模型效果会明显变差训练过程甚至可能根本不收敛。CIFAR-10的像素值范围是0到255torchvision的ToTensor操作会把它缩放到0到1之间但这还不够接下来必须做归一化Normalize让每个通道的数值分布在0附近。CIFAR-10有一组业界统计好的RGB三通道均值0.4914, 0.4822, 0.4465和标准差0.2470, 0.2435, 0.2616可以直接拿来用。归一化的意义在于让输入特征的量纲统一、数值范围相近避免某些通道的数值过大导致梯度更新方向被某个特征主导。你可以把归一化理解为“把不同尺度的东西放到同一把尺子上量”深度学习里的BatchNorm也是类似的思路只不过它的统计量是从当前batch里动态算的而数据预处理里的Normalize用的是整个数据集的先验统计量。数据增强是CIFAR-10项目里提升准确率最有效的手段。我用的组合是训练时先做RandomCrop(32, padding4)也就是把图像四周各扩4个像素后再随机裁剪回32×32然后做RandomHorizontalFlip即随机水平翻转最后做ToTensor和Normalize。RandomCrop相当于给模型提供了“同一张图略微平移也能识别”的训练样本RandomHorizontalFlip则利用了自然图像左右对称的特性。这两招加完之后同一个batch里的数据多样性明显增加模型的泛化能力会好不少。需要特别注意的是测试集不能做数据增强。测试集只做ToTensor和Normalize目的是保持每张图片都是“干净的原始输入”这样才能公平地评估模型真正学到的能力。如果测试集也做随机裁剪和翻转每次评估结果都不一样你根本没法判断是模型变好了还是随机性导致的波动。2.2 网络结构设计每一层怎么选、为什么这么选这个轻量CNN的结构我用了一个非常经典且容易复现的配置卷积层用两块“卷积批归一化ReLU最大池化”全连接部分用“Dropout全连接ReLU全连接”。整个网络参数量大概在180万左右放在今天的大模型语境下确实很轻但对CIFAR-10这个任务来说完全够用。第一层卷积的输入通道是3对应RGB三个颜色通道输出通道设成32卷积核大小3×3padding为1。3×3卷积核是目前的主流选择因为它参数少、感受野可以通过叠加来扩大两个3×3卷积堆在一起等价于一个5×5卷积的感受野但参数量更小。padding为1是为了保持输入输出尺寸一致32×32的图经过这层卷积后仍保持32×32。接着做2×2的最大池化步长默认等于池化核大小也就是2这会让空间尺寸从32×32变成16×16。第二层卷积输入通道32、输出通道64其他设置不变。经过这层后空间尺寸还是16×16再经过一次最大池化变成8×8。到这一步特征图的尺寸计算完全可用公式推出来输出尺寸等于(输入尺寸 - 卷积核大小 2×padding)除以步长再加1池化同理。我用两层卷积加两层池化最终把32×32的图压成了8×8×64的张量在送入全连接层之前需要把它展平成一维也就是8×8×644096维的向量。这个4096就是全连接层输入维度的来源很多人在写代码时容易把这步算错导致维度不匹配报错。全连接部分我使用了Dropout(0.5)这是应对过拟合的重要武器。Dropout在训练时随机让一半的神经元输出置零迫使网络不能过度依赖某几个神经元相当于在训练多个子网络的集成测试时Dropout自动失效所有神经元一起工作。全连接的中间层维度取512最后一层输出10对应CIFAR-10的10个类别。整个网络的“瓶颈”设计思路是越往后通道越多、空间尺寸越小信息从像素级逐渐抽象成语义级最后用全连接层做分类决策。2.3 训练配置关键损失函数、优化器、学习率计划、batch size模型结构定下来之后训练配置决定了它能不能收敛、能收敛到什么水平。我用的损失函数是CrossEntropyLoss交叉熵损失它内部包含了LogSoftmax和负对数似然所以在模型最后一层不需要手动加Softmax。交叉熵直接衡量预测概率分布和真实标签分布的差异对分类任务来说是最自然的选择。优化器我用了Adam初始学习率0.001。Adam自带自适应学习率机制对不同参数会分别调整步长几乎不需要手动调整就能稳定收敛非常适合初学者。如果你想让网络效果更好一点也可以换成SGD加动量的组合学习率设0.01或0.1动量设0.9但需要更细心的调参。一个常见经验是SGD的最终准确率往往比Adam略高但Adam的“稳”特别适合入门阶段等模型跑通了再换也不迟。学习率不能一个值从头用到尾。我设置了多步学习率衰减第15个epoch和第25个epoch分别把学习率降到原来的十分之一。这样做的逻辑是前期用较大的学习率快速找到“盆地”后期用小学习率在盆地里精细搜索避免在最优解附近来回震荡。如果你用的是PyTorch直接调用MultiStepLR就能实现。batch size设为128受限于CPU版本则可以降到64。batch size越大梯度估计越稳定但泛化能力不一定更好batch size越小梯度噪声越大有时候反而能逃出局部最优。128对CIFAR-10来说是一个比较均衡的数值。3. 实操过程在PyTorch里跑通轻量CNN全流程3.1 环境准备与依赖安装动手写代码之前先把环境搭好。我用的是Python 3.10 PyTorch 2.0 torchvision 0.15的组合这套版本组合在Windows和Linux上都比较稳。安装命令很简单直接去PyTorch官网选对应的CUDA版本复制命令就行一般是这样pip install torch torchvision torchaudio如果机器没有NVIDIA显卡安装CPU版本同样可行pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu装完之后记得验证一下torchvision和torch的版本是否匹配。这个坑我踩过torch和torchvision版本不匹配会导致import直接报错或者CIFAR-10数据集下载后无法解析。建议在终端里执行这个命令做一次快速检查python -c import torch, torchvision; print(torch.__version__, torchvision.__version__)看到版本号正常打印出来环境就算准备好了。另外建议把torchvision的CIFAR-10数据缓存路径单独指到磁盘空间充足的位置因为数据集虽然总共才160MB左右但如果装在系统盘很小的机器上偶尔也会出问题。3.2 完整代码数据加载、模型定义、训练循环下面这段代码就是我整个项目的核心可以直接复制保存成train_cifar10.py运行。为了便于理解我把它分成了几个模块先导入依赖和定义设备然后做数据预处理和加载再定义轻量CNN结构最后是训练和评估循环。import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms from torch.utils.data import DataLoader device torch.device(cuda if torch.cuda.is_available() else cpu) # 数据预处理 transform_train transforms.Compose([ transforms.RandomCrop(32, padding4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)), ]) transform_test transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)), ]) # 下载并加载数据 trainset torchvision.datasets.CIFAR10(root./data, trainTrue, downloadTrue, transformtransform_train) testset torchvision.datasets.CIFAR10(root./data, trainFalse, downloadTrue, transformtransform_test) trainloader DataLoader(trainset, batch_size128, shuffleTrue, num_workers2) testloader DataLoader(testset, batch_size128, shuffleFalse, num_workers2)# 轻量CNN模型 class LightCNN(nn.Module): def __init__(self, num_classes10): super().__init__() self.features nn.Sequential( nn.Conv2d(3, 32, kernel_size3, padding1), nn.BatchNorm2d(32), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), nn.Conv2d(32, 64, kernel_size3, padding1), nn.BatchNorm2d(64), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), ) self.classifier nn.Sequential( nn.Dropout(0.5), nn.Linear(64 * 8 * 8, 512), nn.ReLU(inplaceTrue), nn.Linear(512, num_classes), ) def forward(self, x): x self.features(x) x x.view(x.size(0), -1) x self.classifier(x) return x# 训练与评估 model LightCNN().to(device) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) scheduler optim.lr_scheduler.MultiStepLR(optimizer, milestones[15, 25], gamma0.1) for epoch in range(30): model.train() running_loss 0.0 correct 0 total 0 for inputs, labels in trainloader: inputs, labels inputs.to(device), labels.to(device) optimizer.zero_grad() outputs model(inputs) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() * inputs.size(0) _, predicted outputs.max(1) total labels.size(0) correct predicted.eq(labels).sum().item() scheduler.step() train_acc 100.0 * correct / total print(fEpoch {epoch 1:02d} | Loss {running_loss / total:.4f} | Train Acc {train_acc:.2f}%) if (epoch 1) % 5 0: model.eval() test_correct 0 test_total 0 with torch.no_grad(): for inputs, labels in testloader: inputs, labels inputs.to(device), labels.to(device) outputs model(inputs) _, predicted outputs.max(1) test_total labels.size(0) test_correct predicted.eq(labels).sum().item() test_acc 100.0 * test_correct / test_total print(f | Test Acc {test_acc:.2f}%)把这三段代码按顺序放进同一个文件运行即可。如果你的机器内存比较小可以把num_workers改为0避免Windows环境下多进程加载数据报错。如果显存不够把batch size改成64或32代码其他地方都不用动。3.3 训练过程观察与结果分析跑这个项目之前我建议你先建立一个合理预期。轻量CNN在CIFAR-10上配合数据增强30个epoch的合理水平是测试准确率75%到80%左右。这不是一个惊艳的数字但对一个入门项目来说是一个健康的学习结果因为CIFAR-10的真实难度摆在那里——即便是很多结构更复杂的经典网络在没有预训练的情况下也就是80%出头的水平。我实际跑出来的记录大概是这样的前5个epoch训练准确率从45%快速涨到68%测试准确率在62%左右第10个epoch时训练准确率到78%测试准确率缓慢爬到68%第20个epoch训练准确率接近88%测试准确率到73%左右最后几个epoch学习率衰减后测试准确率稳定在75%到78%之间。训练集和测试集准确率之间的差距始终存在这叫泛化差距是正常现象。如果这个差距过大比如训练准确率95%但测试只有55%那就要警惕过拟合了。训练过程中有个细节值得留意loss曲线的形态应该是前几个epoch下降很快然后变缓如果loss不降反升或者震荡得很厉害多半是学习率设置有问题或数据没有归一化。我在第一次跑的时候忘了加Normalize结果loss在2.3左右死活降不下去训练准确率一直在10%上下徘徊——10%恰好是随机猜一个类别的准确率这说明模型根本就没学到东西问题几乎可以肯定是出现在数据处理或梯度传播上而不是网络结构本身。4. 常见问题与排查技巧实录4.1 训练不收敛loss不降、准确率卡在10%这是初学者遇到最多的问题也是最让人抓狂的问题。准确率始终维持在10%左右意味着模型和随机猜没区别。我把自己的踩坑经历和排查顺序整理了一遍你只要按顺序检查基本能定位问题。第一步检查数据预处理。有没有对图像做Normalize像素值尺度是不是差得离谱我第一次跑的时候漏了那组均值和标准差训练loss就一直是2.3左右。第二步检查标签和数据是否对齐。torchvision的CIFAR-10自带标签一般不会错但如果你自己写了Dataset肯定要检查返回的label是否和图片对应。第三步检查学习率。Adam的0.001确实很稳但如果数据预处理正确、网络结构没问题loss还是纹丝不动可以试试把学习率调成0.0001或0.01做对照实验。第四步检查模型输出维度。全连接层最后的输出必须是10对应10个类别。一个非常高效的排查手段是先只取一个batch的数据把模型“死记硬背”能力测试一下。一个batch通常256张图如果模型连这256张图都拟合不了说明代码里有bug如果能拟合再放完整训练集。这种“过拟合单个batch”的测试在真实项目里被广泛使用是判断代码正确性的黄金标准。4.2 过拟合训练准确率很高、测试准确率上不去过拟合的表象是训练集准确率一路高涨测试集准确率却很低甚至停在某个区间完全不动。CIFAR-10虽然有5万张训练图但和模型参数量比起来并不算多所以过拟合几乎是入门阶段躲不开的话题。我建议的解决方案按优先级排序第一是增加数据增强强度除了RandomCrop和RandomFlip还可以加ColorJitter颜色抖动但注意幅度不要太大否则会破坏物体的本质颜色信息。第二是增加Dropout比例从0.5加到0.6或0.7或者在全连接层之前额外再加一层Dropout。第三是减小模型容量把第二层卷积的64个通道降到48或者把全连接层中间维度从512降到256。第四是提前停止也就是在测试准确率不再提升的epoch停止训练保存那个时刻的模型权重。我在实践里还发现一个特别容易忽略的问题如果你在训练循环里忘了调用model.eval()就开始测试那么BN层和Dropout都会按训练模式运行导致测试准确率忽高忽低、每次都不同。正确的做法是测试前一定要调用model.eval()并且在测试完、下一轮训练前再调用model.train()切回训练模式。这个小细节代码里看起来无关紧要但直接影响评估结果的可靠性。4.3 资源不足显存爆掉、CPU训练太慢、数据集下载失败显存不足这个报错大概是CUDA环境下最常见的错误了CUDA out of memory. 解决办法最直接是调小batch size128改64或者32如果还是爆就把第一层卷积的通道从32改成16模型小了显存占用立刻减下来。这里有一个原则在入门实验阶段任何超参数都可以为了跑通让路先把流程顺下来再说。CPU训练慢是另一个常见问题。torchvision默认的num_workers在Windows下有时候会报错可以改成0同时把torch.backends.cudnn.benchmark设为True能在输入尺寸固定的情况下让某些算子跑得更快。如果CPU还是等不了建议把epoch从30降到10到15效果损失在可接受范围内。数据集下载失败更是个大坑。CIFAR-10的下载源在国外国内网络有时候速度很慢甚至连接超时。遇到这种情况可以手动下载cifar-10-python.tar.gz然后把它解压到代码指定目录下的cifar-10-batches-py文件夹里再设置downloadFalse就能加载。我把这个目录结构写在代码里了直接按路径放进去就好。这个问题在很多教程里没人提前告诉你等到真出现了才发现卡在最无聊的环节上。4.4 问题速查与自检清单我把一些高频问题和对应方案整理成了表格方便你对照定位。这里面有些问题是我在实际项目里遇到的有些是和同行交流时收集到的都值得留个心眼。现象可能原因解决方法loss不降训练准确率约10%数据未归一化、标签错位、学习率过大或过小检查预处理用单个batch做拟合实验调整学习率训练准确率高测试准确率低过拟合增加数据增强、增加Dropout、减小模型容量、早停loss震荡剧烈学习率太大或batch size太小降低学习率增大batch size测试准确率每次运行都不一样测试时忘了model.eval()测试前调用model.eval()训练前调用model.train()CUDA out of memorybatch size太大或模型过大减小batch size减小通道数下载数据很慢或失败网络问题手动下载解压至指定目录Windows下num_workers报错多进程加载问题将num_workers设为0维度不匹配报错全连接层输入维度计算错误修改view前的展平维度为64×8×8除了表格里的内容我还想额外补充一个自检清单运行代码前先打印出一个batch的数据形状和标签形状确认是(128,3,32,32)和(128,)训练过程中每隔几个epoch打印一次loss和train acc测试时确保每个类别的准确率都单独统计一下而不仅看总准确率。CIFAR-10的类别是airplane、automobile、bird、cat、deer、dog、frog、horse、ship、truck每个类别有1000张测试图如果你发现某一类准确率特别低往往是模型对该类别的特征表现不够好这时候可以有针对性地分析数据和增强策略。5. 下一步扩展从CIFAR-10走向真实项目5.1 把轻量CNN升级到经典结构跑通并理解了这个轻量CNN之后下一步可以做两件自然的事一是替换网络结构二是替换数据集。网络结构方面最平滑的升级路径是换成ResNet18。ResNet的残差连接解决了深层网络退化的问题你只需要把代码里的LightCNN换成torchvision自带的resnet18并把最后的全连接层改成输出10个类别训练配置基本不用动。import torchvision.models as models model models.resnet18(weightsNone, num_classes10)改成ResNet18之后你会发现同样的数据和训练配置测试准确率很轻松就能上90%以上远远超过轻量CNN的75%左右。这个对比本身就是一个非常好的学习素材你能直观地感受到网络容量和特征提取能力对分类效果的影响。不过要提醒一句ResNet18的参数量大约是1100万比轻量CNN大了好几倍CPU训练的时间也会成倍增长最好还是在GPU上跑。数据集方面可以把CIFAR-10换成CIFAR-100它把类别从10个扩大到了100个每个类只有500张训练图分类难度陡增。你会发现轻量CNN在CIFAR-100上的准确率可能只有40%上下这是数据标注粒度变细后的正常现象也是理解“任务难度”和“模型容量匹配”关系的最好实验。5.2 迁移到自己的数据集要改哪些东西真实项目里几乎不会直接用CIFAR-10更多情况是你自己收集了一批图片想用深度学习做一个分类器。从CIFAR-10迁移到自有数据集核心要改三处数据加载、输入尺寸和类别数量。数据加载如果没有现成的torchvision支持最简单的方式是用torchvision.datasets.ImageFolder。它要求图片按类别存放目录结构是train/cat/1.jpg、train/dog/2.jpg这种它会把子文件夹名称自动映射成类别标签。输入尺寸方面如果你的图片不是32×32需要通过transforms.Resize((224, 224))或者你网络中约定好的尺寸先做缩放。类别数量则要改成你自己任务的实际类别数和最后一层全连接输出保持一致。还有一个容易被忽略的是类别不平衡问题。CIFAR-10每个类别样本数完全相同但你自己的数据几乎一定是不平衡的有些类几百张有些类只有几十张。这时候直接用CrossEntropyLoss效果会差可以考虑给损失函数加class_weight或者采用过采样、Focal Loss等方式。这个话题足够单独写一篇长文但在你真要把模型用到自有数据之前提前了解到这里就够了。5.3 给未来项目沉淀的工程习惯最后说说那些比模型本身更值得留下来的工程习惯。第一每次训练前固定随机种子保证实验结果可复现不然你会分不清准确率的波动是代码修改还是随机性导致的。固定的做法通常是这样import random import numpy as np def set_seed(seed42): random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed)第二每做一个实验把配置和结果记录下来无论是记在纸上、表格里还是TensorBoard都行。学习率、batch size、epoch、数据增强方式、最终准确率这五个字段一个都不能少。第三模型最终训练完之后单独写一个推理脚本把模型参数存成pt/pth文件加载后对单张图片做预测。不要只在训练循环里看到准确率就完事要亲手走一遍“加载模型—预处理单张图—前向推理—输出类别和置信度”的完整推理链路这个能力在实际部署中比训练本身更常用。第四个习惯和优化有关推理时如果要追求极致处理速度通常要改用torch.inference_mode()而不是旧的torch.no_grad()虽然两者都能关闭梯度记录但前者会额外跳过一些和推理无关的算子开销在批量推理场景下能感受到差距。我做这个项目的整体体会是深度学习入门阶段最难的不是把代码run起来而是建立起“我怎么知道这个模型真的在工作”的判断力。CIFAR-10配轻量CNN之所以是极好的训练场就是因为它把问题的规模和复杂度控制在了一个你能完全掌控的范围。在这个范围内你可以反复实验、对比、试错亲眼看到数据增强带来的准确率提升亲手体会到学习率衰减对loss曲线的影响。这些经验才是你进入更复杂项目之前最值钱的积累。
返回列表