资讯详情

基于PyTorch的垃圾识别与分类系统:从迁移学习到部署

📅 2026/10/26 13:56:17 | 华诺云谱 👁 阅读
基于PyTorch的垃圾识别与分类系统:从迁移学习到部署
垃圾分类这个题目每年课程设计和毕设季都会被翻出来做一遍我前后帮人看过不下十个版本从最早的 TensorFlow 1.x 手搓卷积到现在基于 PyTorch 的迁移学习方案坑基本是同一批人在踩。这套基于 PyTorch 的垃圾识别与分类系统干的事情其实很直接给一张垃圾照片模型告诉你它属于哪个类别再往前一步系统把这个结果包装成一个能上传图片、能返回类别和置信度的完整应用。它解决的核心问题是把“图像分类”这个课堂算法真正落到一个有业务含义的场景里——类别体系怎么定、数据从哪来、模型选多大、精度不够怎么办、最后怎么让别人在自己的电脑上跑起来。适合三类人看正在做课程设计想快速搭出可用原型的同学、准备毕设但卡在数据集和调参上的同学、以及做完模型不知道怎么包装成“系统”的同学。下面这份内容按我实际的推进顺序展开不讲虚的能用代码和参数说话的地方都给到具体值。1. 先想清楚这个系统到底由哪几块拼起来很多人一上来就 import torch然后卡在“我该先干什么”。这个项目的复杂度不在模型而在链路的完整性。拆开看是四层数据层数据集构建与增强、模型层骨干网络选择与训练策略、评估层指标与错误分析、应用层推理服务与交互界面。四层里任何一层偷懒答辩现场都会露馅——最常见的是前三层做得还行第四层临时拼一个 notebook 截图当界面老师一问“这个怎么部署”就答不上来。1.1 需求拆解哪些是必须做的哪些是加分项必须做的部分包括一个规模够用、划分干净的图像数据集一个能稳定收敛的训练脚本一套能说清楚模型好坏的评估结果一个输入图片就能出结果的交互入口。加分项才是模型集成、注意力可视化、移动端部署这些。我见过有人一上来就搞 Transformer 加多模态结果基础分类准确率还不如 ResNet18问题就出在顺序反了。判断“够用”的标准很朴素测试集整体准确率能到一个合理区间且没有哪一类的召回率低到离谱。一个四分类任务如果整体 90% 但某一类只有 50%那在实际使用里基本等于这一类的识别功能不存在。所以我在需求阶段就会把“每一类的召回率下限”写进去比如要求最差类别召回不低于 70%这条约束会直接影响后面的采样策略和损失函数选择。1.2 为什么用图像分类而不是目标检测这是被问得最多的问题。目标检测能做多物体、能框位置看起来更“高级”但对这个题目来说往往是负收益。原因有三第一检测需要框标注公开的检测级垃圾数据集远少于分类级自己标几千张框的时间成本不是课程设计能承受的第二检测模型训练更吃显存、更吃调参经验收敛慢出问题排查难第三实际使用场景是“用户拍一张主要物体的照片”单物体占画面主体分类模型完全够用。我的建议是如果画面里经常出现多个物体可以先做一次简单的目标检测或分割把主体裁出来再送进分类模型这是工程上更省力的组合拳。但训练阶段仍然以分类为主把检测当成预处理环节别把两个任务的损失混在一起训那是另一个量级的工作。1.3 技术栈选型为什么是 PyTorch 而不是别的选 PyTorch 的理由很实际动态图调试方便print 一下就能看张量形状torchvision 里预训练权重和标准数据增强开箱即用生态里模型导出、量化、部署的工具链完整。更重要的是遇到问题能搜到的解决方案多这对做课程设计的同学是硬性需求——你不需要成为框架专家你需要的是卡住的时候有人踩过同样的坑。具体到版本我一般固定 Python 3.9 或 3.10PyTorch 2.x 系列CUDA 版本跟着显卡驱动走。这里有个坑不要用 conda 默认源随便装容易出现 torch 和 torchvision 版本不匹配报一堆_C相关的导入错误。稳妥做法是先确认显卡驱动支持的 CUDA 版本再用官方提供的安装命令装对应组合装完立刻跑一句torch.cuda.is_available()和一次小张量的 GPU 运算验证别等到训练跑到一半才发现是 CPU 在跑。依赖清单我通常只保留必要的几个torch、torchvision、numpy、pillow、scikit-learn算指标、matplotlib画曲线、fastapi uvicorn做服务、python-multipart接收上传文件。依赖越少别人复现你的环境越容易这一点在答辩时很重要老师让你现场跑一遍你总不能让人家装半小时。2. 数据集这关过不好后面全是白费功夫我见过太多项目模型部分写得漂漂亮亮一问数据集就含糊“网上下的”。数据集的问题会以各种形式在训练后期爆发验证集准确率虚高划分有泄漏、某一类怎么都学不会样本太少或标签错、模型在真实照片上崩掉训练图和实拍图分布差太远。这三类问题没有一个是靠调学习率能救回来的。2.1 类别体系怎么定粗分类还是细分类粗分类指四分类这种大类体系细分类是分成几十个小类再映射回大类。两者的难度差一个数量级。粗分类类别少、类间差异大容易做到高准确率但演示效果平淡细分类更贴近实际应用但类别多、类内差异大、类间相似度高准确率会明显下降。我的折中做法是主干做细分类比如三十到四十个小类对外展示时把细类映射回大类这样既保证系统有细节又能在大类维度上给出好看的汇总指标。映射表用一份简单的字典维护就够了训练时用细类标签评估时同时输出细类和汇总两套指标。这个设计还有个好处答辩时被问“为什么分这么细”你可以顺势讲清楚细类混淆集中的位置这比背一段模型原理更能体现你真的做过。选类别时要注意样本可获得性。有些小类在公开数据集里只有几十张训出来的效果注定很差与其硬留着拉低整体指标不如合并到相近类别里或者在数据层做重采样。这一点我在项目初期就会做一张类别样本分布表横轴类别、纵轴样本量扫一眼就知道哪些类需要补数据。2.2 数据清洗去重和标签纠错比增强更重要公开数据集普遍存在的问题是重复图和近重复图。同一张图在训练集和验证集里各出现一次你的验证准确率就会凭空高出几个点而实际使用完全达不到。去重的做法不复杂先算每张图的哈希值比如感知哈希哈希相同或距离极小的归为一组只保留一张再按文件名和尺寸做一轮粗筛。这一步花不了半小时但能把指标的可信度拉回来。标签纠错更费时间但更值。具体做法是先训一个基线模型把置信度高但预测和标签不一致的样本捞出来人工看。这些样本里通常混着两类一类是模型确实错了说明这类样本有学习价值另一类是标签标错了这才是要修的。我一般会挑出置信度 0.9 以上但预测错误的样本人工过一遍几十张的量级就能发现明显的标注问题比如把“沾了油污的纸盒”标成了厨余类。注意清洗一定要在划分训练/验证集之前做。先划分再清洗等于用验证集的信息指导了数据修正指标就不可信了。2.3 数据增强别把增强做成了噪声注入增强的目的是让模型见到更多真实世界里会遇到的变形而不是把图变得面目全非。我的默认组合是随机裁剪缩放scale 取 0.7 到 1.0、随机水平翻转、轻度颜色抖动亮度、对比度、饱和度各 0.2 左右训练后期再叠加随机擦除。这套组合对垃圾这类纹理和形状都比较随意的目标很合适。有几个增强要谨慎用。垂直翻转对垃圾识别一般没什么意义反而可能让某些带方向性的物体变得不像大幅度的旋转超过 30 度会让物体姿态失真强颜色抖动会把“发黄的纸”和“白色的纸”搅在一起这两类在现实里是要区分的。验证集和测试集绝对不能加随机增强只做 resize 加中心裁剪加归一化这一点新手经常写错把增强写在了验证的 transform 里结果验证指标一直是乱的。归一化参数直接用 ImageNet 的均值和标准差就行因为用了预训练权重输入分布要和预训练时保持一致。如果你自己从头训那才需要统计自己数据集的均值方差。2.4 划分策略与自建数据补充划分比例我一般用 7:1.5:1.5 或者 8:1:1关键是分层抽样保证每个类别在三个集合里的比例接近。类别不均衡严重时少数类在验证集里可能只有几张指标波动会很大这种时候要么补数据要么接受这部分指标不可靠并在报告里说明。自建数据补充是拉开差距的地方。公开数据集多是摆拍或者网络图背景干净而实际使用是手机随手拍背景杂乱、光照复杂。我的做法是每个类别用手机拍 30 到 50 张故意包含桌面、地面、手持、逆光这些情况然后只放进验证集和测试集不参与训练。这样得到的指标能真实反映模型在实拍场景下的表现答辩时展示这一组对比数据说服力比单纯刷公开测试集高得多。3. 模型选型与训练把钱花在刀刃上到这一步很多人会陷入“模型越大越好”的误区。实际情况是课程设计级别的数据集规模通常在几万张量级ResNet50 往上的模型很容易过拟合而且训练慢、调参窗口小。选型的核心判断依据应该是数据规模、可用的算力、以及部署端的限制。三个条件里任何一个紧都往轻量模型走。3.1 骨干网络横向对比与参数估算下面这张表是我在实际项目中常用的参考输入统一按 224×224参数量和计算量是公开的常见数值推理耗时是相对值只能用来做横向比较不代表你机器上的绝对值。骨干网络参数量单张计算量相对推理耗时适用场景ResNet18约 11.7M约 1.8 GFLOPs1.0数据量中等追求稳定收敛首选基线ResNet50约 25.6M约 4.1 GFLOPs2.2数据量较大指标还有提升空间时再上MobileNetV2约 3.4M约 0.3 GFLOPs0.4要部署到 CPU 或移动端追求推理速度MobileNetV3-Small约 2.5M约 0.06 GFLOPs0.25极致轻量指标要求不高的演示场景EfficientNet-B0约 5.3M约 0.4 GFLOPs0.6精度和速度平衡需要仔细调增强我的常规路线是先用 ResNet18 跑通全流程、拿到基线指标再拿 MobileNetV2 跑一遍做对比。两个模型的指标差距如果很小最终交付就用 MobileNetV2因为部署体验会好很多差距明显的话再用 ResNet50 试一次看提升值不值得那几倍的训练时间。这个对比过程本身就是论文和答辩里很好的素材比只报一个模型的数字有说服力得多。显存估算也要提前算一下。以 ResNet18、batch size 64、224 输入、混合精度训练为例大致占用在 4 到 6 GB 这个量级不开混合精度会明显更高。如果你的显卡只有 8 GB那 batch size 就按 32 起步别硬顶 128爆显存之后再回头改代码很浪费时间。3.2 迁移学习的两种冻结策略怎么选迁移学习是这类项目的标准做法但“怎么迁”有讲究。第一种是全部参数一起微调学习率设小一点第二种是先冻结骨干只训分类头训几轮之后再解冻一起微调。前者收敛快、上限高但对小数据集容易过拟合后者更稳前期不容易把预训练学到的特征破坏掉。我的经验是数据量在每类几百张以上、总样本过万直接用全量微调加小学习率就够了数据量偏小总样本几千张时先用冻结策略训 3 到 5 个轮次让分类头稳定下来再解冻用更低的学习率微调。解冻那一步的学习率一般设成冻结阶段的十分之一到五分之一避免一下把权重推跑偏。冻结的实现要注意 BatchNorm 层。requires_gradFalse只影响梯度BatchNorm 在训练模式下依然会更新running mean和running var严格来说不算“真冻结”。如果要彻底冻结需要把 BN 层设成 eval 模式。这一点很多教程没讲但对小 batch size 的训练影响不小。3.3 损失函数、优化器与学习率的取值逻辑分类任务默认用交叉熵。类别不均衡时给交叉熵加类别权重是最省事的做法权重取该类样本数的倒数再归一化。如果个别类难分程度特别高可以换 Focal Loss通过降低易分样本的权重让模型关注难样本但要注意 Focal Loss 的两个超参需要调调不好反而掉点所以我一般先试加权交叉熵。优化器我用 AdamW 居多学习率 3e-4 配 weight decay 1e-4这是微调场景比较稳的组合。如果追求极致指标可以换 SGD 加动量 0.9学习率 1e-2 起步收敛后的泛化往往略好但对学习率调度更敏感。调度器用余弦退火最省心配合 3 到 5 轮的 warmup 让训练初期稳定。学习率和 batch size 的关系可以按线性缩放粗略估batch size 翻倍学习率也大致翻倍。但这个规则在大模型上不一定成立小模型上做个起点参考没问题。真正决定值的是前几十个 step 的 loss 曲线如果 loss 抖动剧烈甚至上升学习率砍一半如果 loss 下降极其缓慢学习率翻倍试试。3.4 训练循环的核心骨架下面这段是我常用的训练骨架混合精度、梯度裁剪、最优模型保存都包含在内可以直接拿去改。数据处理部分用 DataLoader 配多进程加载num_workers设成 CPU 核数的四分之三左右比较合适设太大会出现进程争抢反而变慢。import torch import torch.nn as nn from torch.amp import autocast, GradScaler from torch.optim.lr_scheduler import CosineAnnealingLR def train_one_epoch(model, loader, criterion, optimizer, scaler, device, clip1.0): model.train() total_loss, correct, total 0.0, 0, 0 for imgs, labels in loader: imgs, labels imgs.to(device, non_blockingTrue), labels.to(device, non_blockingTrue) optimizer.zero_grad(set_to_noneTrue) with autocast(device_typecuda, dtypetorch.float16): logits model(imgs) loss criterion(logits, labels) scaler.scale(loss).backward() scaler.unscale_(optimizer) torch.nn.utils.clip_grad_norm_(model.parameters(), clip) scaler.step(optimizer) scaler.update() total_loss loss.item() * imgs.size(0) correct (logits.argmax(1) labels).sum().item() total imgs.size(0) return total_loss / total, correct / total验证函数要记得切torch.no_grad()并且调model.eval()否则 BN 和 Dropout 还在训练模式指标会偏低而且每次跑都不一样。最优模型保存我按验证集准确率来存同时记录对应的轮次方便训练结束后回滚到最好的那一个权重而不是用最后一轮的。best_acc 0.0 for epoch in range(epochs): tr_loss, tr_acc train_one_epoch(model, train_loader, criterion, optimizer, scaler, device) va_loss, va_acc evaluate(model, val_loader, criterion, device) scheduler.step() if va_acc best_acc: best_acc va_acc torch.save({model: model.state_dict(), epoch: epoch, acc: va_acc}, best.pt) print(fepoch {epoch} | train {tr_loss:.4f}/{tr_acc:.4f} | val {va_loss:.4f}/{va_acc:.4f})3.5 训练过程中的监控与早停判断训练曲线是我判断问题的主要依据光看最终数字没用。我会重点看三个信号训练 loss 是否稳定下降、验证 loss 和训练 loss 的差距是否在扩大、验证准确率是否已经连续多轮不涨。第一个信号异常说明优化设置有问题第二个说明过拟合在发生第三个是早停的依据。早停的耐心值我一般设 5 到 8 轮配合余弦退火的话会适当放宽因为退火后期往往还有一次小幅提升。遇到过拟合迹象时优先动作是加增强、加 weight decay、减模型规模而不是立刻加数据——加数据成本最高应该放在最后。4. 评估这一步很多人做得太糙只报一个整体准确率的评估在答辩里是很吃亏的。因为分类任务的不均衡是常态整体准确率会被多数类主导少数类的糟糕表现被平均掉了。真正能说明问题的是类别级的指标加上错误分析。4.1 混淆矩阵与类别级指标怎么读混淆矩阵要按行归一化来看也就是看每一类的召回率而不是看绝对数量。行归一化之后对角线就是各类的召回率非对角线的格子告诉你这一类主要被误判成了什么。我通常会先把测试集的混淆矩阵打印出来找出最大的几个非对角格子这几个格子就是后续优化的方向。sklearn 的 classification_report 能一次给出每类的精确率、召回率和 F1配合支持度样本数一起看。支持度很低但指标很差的类说明样本不够得补数据支持度不低但召回很差的类多半是和某个类在视觉上确实像这时候要想的是特征层面的区分比如引入更强的增强或者换成能捕捉细节的输入分辨率。指标说明的问题常见处理方式整体准确率低且各类都低模型没学好或训练设置有误先在小样本上过拟合验证流程整体高但某类召回极低该类样本少或与某类高度相似补样本、加权采样、针对性增强精确率低召回率高模型过于激进把别的类也判进来了提高判定阈值或调整类别权重精确率高召回率低模型过于保守降低阈值检查是否训练不足4.2 错误样本分析模型到底错在哪这一步最费时间但收获最大。具体做法是把测试集里预测错误的样本按“真实类-预测类”分组每组抽十几张图拼成一张网格图看。看的时候问自己三个问题这图人能不能认对如果能模型缺什么信息如果不能是不是标签本身有问题我遇到过的典型情况某几类错误集中在“深色背景 小物体”的组合上说明模型的注意力被背景带跑了解法是加强随机裁剪、或者在训练里加入背景替换类增强还有一类错误集中在“同类不同材质”上比如纸质和塑料质感的同色物体这种靠提高输入分辨率往往有改善因为细节纹理在高分辨率下才看得出来。错误分析还有一个隐藏收益答辩时老师问“你的模型有什么不足”你能具体到某几类、某几种场景这比说“准确率还有提升空间”强太多。4.3 测试时增强与模型集成的取舍测试时增强对同一张图做多种变换后取平均预测通常能带来一点稳定提升代价是推理时间成倍增加。课程设计场景下如果推理是在服务器上跑加三到五种变换完全可以接受如果要部署到资源受限的设备就不建议用。模型集成是另一个提点手段把 ResNet18 和 MobileNetV2 的预测概率加权平均往往比单个模型好一两个点。权重可以按各自验证集准确率来分配也可以用简单的等权平均。要注意集成的收益有上限两个模型如果在同一批样本上错得一样集成就没什么用。判断方法是看两个模型的错误样本重合度重合度低才值得集成。5. 把模型包装成能演示的系统模型训完只是半成品。一个“系统”至少要能接收外部输入、返回结构化结果、有可交互的界面。这部分工作量不大但决定了答辩现场的观感也是很多人翻车的地方。5.1 推理服务的设计要点服务端我一般用 FastAPI原因是自带交互式接口文档答辩演示时打开文档页面直接上传图片测试比讲半天代码直观。核心接口就一个接收上传的图片文件返回预测类别、置信度、以及前几个候选类别。返回候选类别这个设计很实用因为实际使用中用户可能想知道第二可能是什么。推理服务里有几个必须处理的细节。第一是预处理要和训练时完全一致同样的 resize 尺寸、同样的插值方式、同样的归一化参数任何一处不一致都会导致线上指标明显低于测试指标这是最常见的坑。第二是模型只加载一次放在全局变量里不要每次请求都 load 一遍。第三是要显式设置model.eval()和torch.no_grad()。第四是要限制上传文件大小和类型避免有人传一个超大文件把服务卡死。import io, torch from PIL import Image from torchvision import transforms from fastapi import FastAPI, UploadFile, File import torch.nn.functional as F app FastAPI() device torch.device(cuda if torch.cuda.is_available() else cpu) model build_model(num_classes40).to(device) model.load_state_dict(torch.load(best.pt, map_locationdevice)[model]) model.eval() tf transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]), ]) app.post(/predict) async def predict(file: UploadFile File(...)): img Image.open(io.BytesIO(await file.read())).convert(RGB) x tf(img).unsqueeze(0).to(device) with torch.no_grad(): prob F.softmax(model(x), dim1)[0] top prob.topk(3) return {results: [{label: cid2name[i], score: round(float(s), 4)} for s, i in zip(top.values, top.indices)]}5.2 前端交互够用就好别过度设计前端不需要花哨一个上传框、一个预览区、一个结果列表就够了。用最朴素的 HTML 加表单提交或者用原生 fetch 调接口都行没必要上框架。做毕设的同学容易在界面上花太多时间最后发现老师只关心三点能不能传图、能不能出结果、出结果要多久。有一点值得做把置信度用进度条展示并且把前三个候选都列出来。这个小设计能直观体现模型的不确定性答辩时也方便解释“模型不是只会给一个答案”。另外建议加一个示例图片按钮现场网络不好或者找不到合适图片时一键加载内置样例这是保命设计。5.3 模型导出与推理加速如果演示环境没有 GPU就必须做速度优化。最省事的是动态量化把线性层转成 int8模型体积能压到四分之一左右CPU 推理速度有明显提升精度损失通常在可接受范围内。导出成 ONNX 再推理也是个选择但要注意算子兼容性遇到不支持的算子会导出失败。# 动态量化注意在 CPU 上执行 python -c import torch m torch.load(best.pt, map_locationcpu)[model].eval() q torch.quantization.quantize_dynamic(m, {torch.nn.Linear}, dtypetorch.qint8) torch.save(q.state_dict(), best_int8.pt) 导出之后一定要做一致性校验拿同一批测试图片分别用原模型和量化模型跑一遍比较两者的预测结果重合率和准确率差值。重合率低于 95% 就要谨慎可能某个层的量化损失偏大这时候可以只量化部分层。5.4 现场演示的稳定性预案答辩现场最容易出的事不是模型不准而是环境跑不起来。我的预案清单里有这几条所有依赖版本写进 requirements 里并且在一台干净机器上验证过安装流程模型权重的加载路径用相对路径加 try 兜底准备一个纯 CPU 也能跑通的降级配置提前录一段演示视频存在本地万一现场设备出问题可以直接播。还有一条经验不要在现场跑训练也不要在现场展示加载很慢的大模型。演示前把服务启动好浏览器预热一遍避免第一次请求因为模型加载或页面资源未缓存而卡住十几秒那十几秒的尴尬比准确率低两个点严重得多。6. 踩过的坑和排查清单下面这些是实际推进中反复出现的问题我按现象整理成表方便对照排查。每一项背后都是一次完整的排查过程有些坑不看这张表很难想到。6.1 训练阶段的问题速查现象最可能的原因排查动作处理方案loss 不降一直平着学习率过大或标签映射错位用 10 张图跑过拟合测试调小学习率核对标签与类别数训练准确率高但验证准确率很低数据泄漏或过拟合严重检查训练集和验证集是否有重复图去重后重新划分加强正则验证准确率一直卡在类别数的倒数附近类别数设置错或标签全为同一类打印标签的分布和唯一值修正 num_classes 与标签映射训练中途 loss 突然变成 nan学习率过高或梯度爆炸打印各层梯度范数加梯度裁剪降学习率检查输入范围显存溢出batch 太大或未用混合精度打印显存占用减 batch开混合精度及时释放中间张量训练速度异常慢数据加载成为瓶颈看 GPU 利用率增加 worker 数图片预解码为张量缓存关于“小样本过拟合测试”这是我最推荐的调试手段从训练集里挑 10 张图关闭增强和随机性让模型去记这 10 张如果几十个 step 内准确率到不了 100%说明训练流程本身有问题跟数据和模型规模都没关系。这一步能把问题定位范围缩小一大半。6.2 推理与部署阶段的问题线上指标比测试差一大截几乎是预处理不一致导致的。要逐个字段核对resize 的目标尺寸对不对、裁剪方式是中心裁剪还是直接 resize、归一化的均值和通道顺序是不是和训练一致、PIL 读出来的是 RGB 而 OpenCV 默认是 BGR。这几项里任何一项错了准确率都会明显掉。CPU 推理慢到没法演示通常是模型太大或者没用上量化。ResNet50 在普通笔记本 CPU 上单张推理要到几百毫秒加上前端上传和返回体感就很差。换成 MobileNetV2 再加动态量化单张能压到几十毫秒量级体验完全不同。服务启动报错找不到权重文件多数是相对路径的基准目录和执行目录不一致。稳妥做法是用os.path.dirname(os.path.abspath(__file__))拼绝对路径或者把权重路径做成配置项从环境变量读。6.3 答辩时容易被追问的几个点第一个问题是“你怎么保证评估结果可信”。回答要落到划分方式和去重上分层划分、划分前去重、实拍补充集只进验证和测试不参与训练。第二个问题是“类别不均衡怎么处理的”要能说清采样策略或损失加权的具体做法和效果对比。第三个是“为什么选这个模型”要能用参数量、推理耗时、指标对比三组数据支撑。第四个是“系统怎么部署”要说得清服务是什么、接口怎么调、有没有做速度优化。还有一个常被问但少有人准备的问题模型在什么情况下会错。这时候拿出错误分析的分组图讲清某一类物体在特定背景或光照下的失效模式是加分项。能承认边界、说清边界在哪比声称什么都能识别要可信得多。7. 我个人在这个项目上的一些体会做这类项目我最深的感受是时间分配反了。大多数人把 70% 的时间花在模型上实际上模型部分用现成的迁移学习方案两三天就能跑通真正吃掉时间的是数据清洗、错误分析和部署调试这三块。我后来的做法是把它调过来模型占三成时间数据和部署各占三成剩下一成留给文档和演示准备。还有一个具体技巧值得单独说在训练脚本里固定随机种子并且把每次实验的超参、对应的验证指标记在一张表里。这个习惯看起来笨但当你试到第十组参数发现不如第三组、却想不起来第三组用的什么设置时你就知道它的价值了。表里至少记这几列模型、输入尺寸、batch size、学习率、增强组合、最佳验证准确率、最佳轮次。这份记录本身就是最终报告里最有说服力的部分。最后提一个容易被忽略的点把这个系统的失败情况也写进文档。哪些类别容易混、什么样的照片会识别不出来、置信度低到什么程度应该让用户重拍。这些内容不写在文档里系统就只是一个玩具写清楚了它才像一个真实的工程产物。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑