尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
深度学习实战:基于CNN的宠物体型识别全流程解析
实话讲每年一到毕设季“基于深度学习的某某识别”这类题目几乎保底出现而“宠物体型识别”更是其中一个热度很高、看起来简单、但想做得漂亮并不容易的方向。这篇博文我就以“基于Python与CNN的宠物体型识别”为例完整复盘一遍从选题、数据、模型、训练、评估到答辩的全流程。无论你是正在为毕设发愁的在校生还是想拿图像分类练手的深度学习入门者这篇内容都可以直接当一份“施工图纸”用。核心关键词就三个深度学习、CNN、宠物体型识别我会把这三件事拆开揉碎讲透。做这个项目最大的魅力在于它不是一个纯学术的玩具题而是有真实应用价值的小场景。宠物体型识别本质上是一个细粒度图像分类任务它和普通的猫狗分类不一样目标都是猫但要区分这只猫是偏瘦、正常还是超重这比区分猫和狗要难得多。正因如此题目本身的“技术含量”足够撑起一篇合格论文同时工作量可控、数据集可获取、演示效果好。我相信这也是很多老师愿意给出类似题目的原因。1. 项目立项与整体方案设计1.1 题目定位与核心需求拆解拿到“宠物体型识别”这个题目第一步不是急着写代码而是把任务定义清楚。所谓“体型识别”最终要解决的是一个图像分类问题输入一张宠物照片模型输出它属于哪个体型类别。但这里有两个关键点需要和导师确认清楚。第一宠物是单指猫还是猫狗都包含我建议如果导师不强制要求就聚焦在单一物种上比如只做猫的体型识别或只做狗的体型识别。原因很简单猫和狗在体型、毛发、拍摄角度上差异太大如果混在一起模型很可能会去学“物种特征”而不是“体型特征”导致最终在某一类上表现极差。第二体型分成几类最常见的做法是三分法偏瘦、正常、偏胖。如果你想增加工作量也可以做四分偏瘦、正常、偏胖、肥胖。但三分类在数据标注的容错率上更友好因为“正常”和“偏胖”的边界本身就有主观性类别越细标注噪声越大模型收敛越困难。任务定义清楚之后整个项目的技术路径就非常清晰了用Python语言基于深度学习框架我推荐PyTorch构建卷积神经网络模型完成一个三分类图像识别任务并在测试集上验证效果最终封装成一个可运行的简易演示程序。1.2 技术选型为什么是CNN为什么选PyTorch很多人刚接触深度学习时都会有个疑问识别宠物体型非要用CNN吗用传统机器学习方法比如提取颜色直方图、纹理特征再喂给SVM行不行理论上行但实际效果会差很多。宠物体型是一个全局形态特征体现在身体的宽高比例、腹部线条、肋骨触感等细节上。传统特征工程方法很难用手工设计的描述子把这些信息表达出来而CNN通过多层卷积核自动学习局部纹理到全局形态的层次化特征天生适合这种任务。这也是深度学习方案在毕业设计中成为主流的原因。框架选型上我在几个主流方案里比较过。TensorFlow的生态成熟但API版本迭代折腾人PyTorch的代码更接近Python原生风格动态图机制让Debug变得直观在学术界的使用率逐年升高非常适合作为毕设技术栈。唯一要注意的是版本兼容性建议固定使用某个稳定版本不要频繁升级。1.3 硬件环境与软件环境准备这个项目对硬件的要求真的不算高。训练阶段如果你的机器没有NVIDIA显卡完全可以用云算力或者直接使用Google Colab的免费GPU如果只有CPU也可以跑只是时间要多花几倍。本地环境建议按以下清单准备操作系统Windows 10/11 或 Ubuntu 20.04都能正常工作Python版本3.8 或 3.9不要用太新的版本避免第三方库兼容问题深度学习框架PyTorch 1.10 至 2.x 均可图像处理库OpenCV 或 Pillow用于图像读写与预处理科学计算库NumPy、pandas用于数据处理与分析可视化库Matplotlib、scikit-learn用于绘制曲线与计算指标我见过太多人把时间浪费在配环境上这里分享一个经验先在本地用一个小数据集比如每个类别几十张图跑通完整流程再切到GPU环境做全量训练。流程通了后面换机器只是装库的问题。2. 数据集构建与预处理决定了项目的上限2.1 数据从哪里来怎么又快又合法地积累样本做图像分类项目最让人头疼的就是数据。很多同学在第一周就开始到处找“猫咪胖瘦图片数据集”但公开可用的现成数据集非常少体型标注更是稀缺。这种情况下我建议用组合拳来解决。首选是爬虫采集这不是什么灰色手段就是常规的图片搜索抓取。可以按“胖猫”“正常体型的猫”“瘦猫”等关键词在开放的图片网站上爬取每类先收集200到300张。其次是整理自己手头的宠物照片如果身边有养宠物的同学、朋友可以发动他们贡献一些不同体型的照片。还有一个容易被忽略但很好用的来源是宠物医院、宠物店的公开宣传图这些图片通常清晰度高、姿态正。不管数据从哪来有几条红线必须守住不要使用商业付费图库的图片不要搬运他人明确声明版权保护的图片涉及宠物主人正面照的要打码处理。毕设虽然是学习用途但该有的版权意识不能少。2.2 标注策略与类别判定标准数据收集完成之后真正的体力活是标注。这是整个项目中最容易被低估的一环也是拉开档次的环节。你需要根据正面和侧面参考图对每一张图进行体型评级。这里有一个实操经验类别判定不要凭感觉要列出可量化的参考维度。我的建议是建立一份标注说明文档写清楚什么算偏瘦、什么算正常、什么算偏胖。比如参考宠物医院的体况评分标准能明显摸到肋骨、腰部内收明显判定为偏瘦肋骨可以摸到但有一层薄脂肪、俯视有沙漏腰判定为正常肋骨难以触及、腹部有脂肪堆积、俯视呈椭圆甚至水桶状判定为偏胖。按照这个标准让两个人以上对同一批图片独立标注遇到分歧就讨论或剔除能有效降低标注噪声。标注完还要做一次质量审查。我有一次就是因为偷懒跳过了审查结果模型训练时发现有一批“正常”类里混进了大量美颜滤镜严重的图导致收敛极慢。审查的主要任务是剔除严重模糊、主体占比过小、多只宠物同框、被文字或水印大面积遮挡的图片。2.3 数据增强用最少的样本换来最好的泛化标注完成之后一般每个类别也就能剩下100到200张干净图片总量大概在四五百张。这个数据量对于CNN来说是偏小的直接训练几乎必然过拟合。这时就要靠数据增强来“人为扩大数据集”。数据增强的本质是在不改变图片语义标签的前提下对图片做一系列变换让模型见识到更多样的形态。常用的操作包括水平翻转猫朝左和朝右本质上没区别但模型看到的输入却翻倍随机旋转限制在正负15度以内太大角度会让体型信息失真随机裁剪并缩放模拟不同拍摄距离下宠物在画面中的占比变化颜色抖动调整亮度、对比度、饱和度让模型对光线变化更鲁棒轻微透视变换模拟从不同角度拍摄产生的形变这里要特别提醒一点旋转角度和透视强度不要开得太大否则会出现“鱼眼猫”“歪头猫”这种现实中不存在的畸形样本反而干扰模型学习真实的体型特征。我用PyTorch做增强时通常是训练集用全套增强验证集和测试集只做缩放归一化这样评估结果才能反映真实水平。2.4 数据集的目录组织与DataLoader实现数据准备好了代码层面的第一步是把数据集按标准目录结构整理好。推荐采用ImageFolder的格式这是PyTorch里最省事的组织方式。dataset/ ├── train/ │ ├── thin/ │ ├── normal/ │ └── overweight/ ├── val/ │ ├── thin/ │ ├── normal/ │ └── overweight/ └── test/ ├── thin/ ├── normal/ └── overweight/train、val、test的划分比例建议为7:2:1。很多人只分train和test这个习惯并不好。验证集用于训练过程中的模型选择与早停判断测试集只用于最终效果评估两者职责必须分开。读取数据的代码可以这样写from torchvision import transforms, datasets from torch.utils.data import DataLoader # 训练集增强与预处理 train_transforms transforms.Compose([ transforms.Resize((224, 224)), transforms.RandomHorizontalFlip(p0.5), transforms.RandomRotation(degrees10), transforms.ColorJitter(brightness0.2, contrast0.2, saturation0.2), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) # 验证/测试集只做缩放与归一化 val_transforms transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) train_dataset datasets.ImageFolder(./dataset/train, transformtrain_transforms) val_dataset datasets.ImageFolder(./dataset/val, transformval_transforms) test_dataset datasets.ImageFolder(./dataset/test, transformval_transforms) train_loader DataLoader(train_dataset, batch_size32, shuffleTrue, num_workers4) val_loader DataLoader(val_dataset, batch_size32, shuffleFalse, num_workers4) test_loader DataLoader(test_dataset, batch_size32, shuffleFalse, num_workers4)注意这里的Resize尺寸统一设为224乘224这是ImageNet预训练模型的标准输入尺寸后面迁移学习时会用到。归一化用的均值与标准差也是ImageNet统计出来的标准值直接用即可。3. CNN模型构建与训练实战3.1 是手写CNN还是用预训练模型这是个战略问题刚入门的时候很多教程会教你手搓一个三层卷积网络然后跑一下MNIST手写数字识别。但到了毕设这个量级如果还是从零训练一个十几层的CNN数据集只有几百张训练出来的模型效果大概率是惨不忍睹的。这里有一个核心概念必须理解迁移学习。简单说就是先用一个巨大的通用数据集比如ImageNet包含上千万张图、一千个类别训练好一个CNN让它已经学会了提取通用视觉特征的能力然后我们把它搬运到宠物体型识别这个具体任务上只需要在它基础上做少量调整。这就好比让一个经验丰富的兽医学徒来看宠物体型他已经知道眼睛、耳朵、毛发、四肢是什么样只需要再教他“什么样的身体比例算胖”学习成本当然远低于从零开始教一个婴儿认识一切。预训练模型的选择我首推ResNet18或ResNet34理由是效果和资源消耗的平衡点很好。ResNet引入了残差结构解决了深层网络梯度消失的问题结构不复杂在几百张图片的小数据集上也能稳定收敛。如果你的显存紧张MobileNetV3是个更轻量的选择如果追求更高精度且显存充足ResNet50也可以但训练时间会成倍增加。3.2 迁移学习模型改造与关键参数配置使用预训练模型时需要把模型最后一层全连接替换成符合自己分类任务的形式。以ResNet18为例原始的最后一层输出是1000类我们要改成3类。import torchvision.models as models import torch.nn as nn # 加载预训练模型 model models.resnet18(pretrainedTrue) # 修改全连接层适配三分类任务 num_features model.fc.in_features model.fc nn.Linear(num_features, 3) # 在实际项目中建议再加入一个Dropout层来抑制过拟合 # 这里为了简洁直接替换fc完整写法可以自定义分类头这里有两个关键决策点。第一是冻结所有层只训练分类头还是放开全部层进行微调我的建议是如果数据集非常小每类少于100张冻结前面大部分层只训练最后一两个残差块和分类头防止过拟合如果数据量相对充足可以全部放开但学习率要调低。实操中最省心的方案是分两阶段先用较大学习率只训练分类头再降低学习率放开全部层微调。第二几个超参的初始值怎么定。损失函数用CrossEntropyLoss这是多分类的标配。优化器我用Adam初始学习率设在0.001如果你听到某些人推荐SGD加动量那通常是在大数据集上的经验我们这种规模Adam更稳收敛快、不容易震荡。batch size在显存允许的情况下选32或64跑不动就降到16。训练轮数先设30轮配合早停机制。3.3 完整的训练循环与模型保存逻辑训练循环的代码逻辑看起来很统一但如果要从头到尾跑通一个深度学习项目还是有一些细节需要认真处理。我把核心代码写出来并加上必要的说明。import torch import torch.nn as nn from torch.optim import lr_scheduler import copy device torch.device(cuda if torch.cuda.is_available() else cpu) model model.to(device) criterion nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lr0.001) scheduler lr_scheduler.ReduceLROnPlateau(optimizer, modemin, patience2, factor0.5) num_epochs 30 best_acc 0.0 best_model_wts copy.deepcopy(model.state_dict()) for epoch in range(num_epochs): # 训练阶段 model.train() running_loss 0.0 correct 0 total 0 for inputs, labels in train_loader: 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) _, preds torch.max(outputs, 1) total labels.size(0) correct (preds labels).sum().item() train_loss running_loss / total train_acc correct / total # 验证阶段 model.eval() val_loss 0.0 val_correct 0 val_total 0 with torch.no_grad(): for inputs, labels in val_loader: inputs, labels inputs.to(device), labels.to(device) outputs model(inputs) loss criterion(outputs, labels) val_loss loss.item() * inputs.size(0) _, preds torch.max(outputs, 1) val_total labels.size(0) val_correct (preds labels).sum().item() val_loss val_loss / val_total val_acc val_correct / val_total scheduler.step(val_loss) print(fEpoch {epoch1}/{num_epochs}, fTrain Loss: {train_loss:.4f}, Train Acc: {train_acc:.4f}, fVal Loss: {val_loss:.4f}, Val Acc: {val_acc:.4f}) # 保存验证集上最优模型 if val_acc best_acc: best_acc val_acc best_model_wts copy.deepcopy(model.state_dict()) torch.save(model.state_dict(), best_model.pth) # 加载最优模型 model.load_state_dict(best_model_wts)这段代码里有几个细节值得讲清楚。为什么用验证集而不是训练集来决定保存哪个模型因为训练集上的准确率一定会越来越高但那可能是过拟合导致的虚假繁荣验证集上的表现才反映模型的泛化能力。为什么要用ReduceLROnPlateau自动降学习率因为当验证损失进入平台期时手动去调整学习率既麻烦又容易错过时机这个调度器会在连续几个epoch没有改善时自动将学习率减半非常实用。3.4 训练过程的曲线观测与收敛判断训练跑起来之后不是坐在屏幕前干等就行。我习惯画两条曲线训练损失与验证损失随epoch的变化曲线以及训练准确率与验证准确率随epoch的变化曲线。怎么看这两条曲线正常情况下训练损失持续下降验证损失也持续下降最终都稳定下来这时模型收敛良好。如果训练损失降到很低但验证损失开始反弹就说明过拟合正在发生早停机制此时就该介入。如果训练损失下降很慢可能说明学习率太小或者模型容量不足需要调整策略。还有一个经验数据集规模很小时第一次训练的前几个epoch里验证准确率可能在33%左右徘徊这等于随机猜别慌。等到损失函数开始明显下降准确率会迅速拉升这个“起飞”的过程在迁移学习里通常出现在第3到第8个epoch之间。如果10个epoch之后还在33%附近才需要停下来检查数据加载、标签映射、预处理这些环节是不是出了问题。4. 模型评估、错误分析与演示系统搭建4.1 用指标说话准确率之外还要看什么训练结束以后清理一下桌面泡杯茶接下来就是验收环节。很多人只习惯看一个总体准确率比如“我们的模型达到了85%的准确率”。如果想把毕设做得规整一点光有这一个数字远远不够。我建议至少计算以下几项指标准确率、精确率、召回率、F1分数以及混淆矩阵。以“偏胖”这个类别为例精确率回答的是“模型说它是偏胖它真的是偏胖的概率有多大”召回率回答的是“所有真实偏胖的宠物模型找回来的比例有多大”。有些场景下两类指标此消彼长F1就是它们的调和平均综合反映该类别的表现。计算和可视化可以用下面这段代码from sklearn.metrics import confusion_matrix, classification_report import numpy as np import matplotlib.pyplot as plt # 收集测试集预测结果 all_preds [] all_labels [] model.eval() with torch.no_grad(): for inputs, labels in test_loader: inputs inputs.to(device) outputs model(inputs) _, preds torch.max(outputs, 1) all_preds.extend(preds.cpu().numpy()) all_labels.extend(labels.numpy()) # 打印分类报告 print(classification_report(all_labels, all_preds, target_names[thin, normal, overweight])) # 绘制混淆矩阵 cm confusion_matrix(all_labels, all_preds) plt.figure(figsize(8, 6)) plt.imshow(cm, interpolationnearest, cmapBlues) plt.colorbar() plt.xticks(np.arange(3), [thin, normal, overweight]) plt.yticks(np.arange(3), [thin, normal, overweight]) plt.xlabel(Predicted Label) plt.ylabel(True Label) for i in range(3): for j in range(3): plt.text(j, i, cm[i, j], hacenter, vacenter, colorwhite if cm[i, j] cm.max()/2 else black) plt.show()关于指标的合理解释我要提前打个预防针如果三个类别的测试准确率在80%到90%之间已经算是相当不错的成果了毕竟体型判断本身存在人为标注误差有些照片即便是真人来看也未必能达成一致。在论文里如实分析这些误差来源反而比吹嘘99%准确率更有说服力。4.2 错误样本分析模型为什么认错我之前做这个项目时对错误样本做了一个归类分析发现主要集中在三种情况。第一种是“视角极端”的照片比如完全俯拍、只拍到宠物背部身体轮廓信息严重缺失。第二种是“姿态干扰”宠物蜷成一团睡觉时视觉上会显得比实际小很多模型很容易把偏胖的猫判成正常。第三种是“毛发与颜色干扰”白色长毛猫即使偏瘦蓬松的毛发也会让体型看起来偏胖深色短毛猫则恰恰相反。分析错误样本的过程本身就是论文里很出彩的章节。你可以在论文中展示几张典型的错分图片并解释模型为什么会做错以及这种错误提示了哪些改进空间。这比只丢一张准确率表格要显得专业得多。4.3 做一个能演示的界面Gradio的一站式方案很多毕设都会要求做一个系统演示但不用把界面做得太重。从前有两条路写一个Tkinter桌面窗口或者用Flask搭一个Web页面。现在还有第三条路就是Gradio它简直是深度学习演示的神器几行代码就能生成一个带上传、预测、结果展示的网页。import gradio as gr import torch from torchvision import transforms from PIL import Image def predict(image): transform transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) img_tensor transform(image).unsqueeze(0).to(device) with torch.no_grad(): outputs model(img_tensor) probs torch.softmax(outputs, dim1) prob_dict { 偏瘦: round(probs[0][0].item(), 4), 正常: round(probs[0][1].item(), 4), 偏胖: round(probs[0][2].item(), 4) } return prob_dict demo gr.Interface( fnpredict, inputsgr.Image(typepil), outputsgr.Label(num_top_classes3), title宠物体型识别演示系统, description上传一张宠物全身照模型会给出偏瘦、正常、偏胖的概率。 ) demo.launch()这个演示系统在答辩现场很加分。你当场找一张导师手机里的宠物照片传上去结果出来比嘴里说多少技术名词都直观。而且Gradio界面本身是比较现代的交互形式相比传统的按钮窗口观感上要高出几个档次。5. 训练过程中的疑难杂症与排坑实录5.1 过拟合最常遇到的拦路虎五百张图训练一个深度模型过拟合几乎是必然遭遇的。表现是训练准确率冲到97%以上验证准确率却卡在70%左右徘徊。我自己的排坑顺序是这样的。先检查数据增强是否生效看训练时数据路径里是不是忘了加transform。如果增强没问题再考虑正则化手段在分类头前加Dropout层随机丢弃比例取0.3到0.5在损失函数上增加权重衰减也就是L2正则化Adam的weight_decay参数设为1e-4或5e-4此外把训练轮数降下来配合早停不让模型在训练集上反复碾压到过度拟合。如果这些手段都用了过拟合还是严重那问题多半出在数据规模本身太小。这时候与其硬调模型不如回到数据层面想办法比如扩展采集范围用小众搜索词再爬一批图或者对已收集图片做更高阶的增强比如随机擦除。5.2 类别不均衡三分类也会被忽视“偏瘦”的图片天然比“正常”和“偏胖”难收集因为日常养宠的人很少会刻意拍一张自家猫的“瘦照”。训练完成后一看混淆矩阵“偏瘦”类的召回率特别低这就是类别不均衡的典型表现。应对手段有三个层级。最简单的是把三个类别的样本数量尽量对齐少的类别可以多做几份增强副本但注意要用不同的增强参数组合不要简单复制粘贴。第二个方案是调整损失函数的类别权重让模型在计算损失时对样本少的类别给更高权重PyTorch里可以在CrossEntropyLoss的weight参数里传入一个权重张量。第三个方案如果某个类别实在太少可以考虑合并或重新定义任务边界比如把“偏瘦”和“正常”合并成“不胖”做成二分类。这是最后手段但总比卡死在一个做不出来的分类任务上强。5.3 显存不足、训练速度慢的应对方案本地训练时最常见的一句话是“CUDA out of memory”。别慌它通常不是无解的。先把batch size从32降到16或8这是最直接的减负方案。如果还想再压一压可以把输入尺寸从224降到192对最后一层卷积的影响往往不大。还有一个技巧是在PyTorch里开启混合精度训练用torch.cuda.amp显存占用几乎减半速度还能提升。如果连显卡都没有也有两条路可以走。一是用云端GPU很多平台提供几块钱一小时的学生优惠二是用CPU硬跑只要模型选MobileNetV3这种轻量网络把训练轮数降到20轮耐心等也是能跑完的。5.4 训练Loss不下降或直接报NaN的排查思路有几种情况会导致训练从一开始就卡住。最常见的是学习率设置不合理0.01的Adam学习率在迁移学习里往往偏高我习惯从0.001或0.0001起步。第二个常见坑是数据归一化没做像素值直接以0到255的原始范围喂进网络数值尺度过大容易导致梯度爆炸。第三个情况是标签与类别索引对不上比如按字母顺序读入类别文件夹和你的预期顺序不一致这时候查一下train_dataset.classes就能定位。Loss变成NaN通常是数值溢出优先怀疑学习率太大或数据里有异常值。5.5 完整的问题速查表现象最常见原因首选排查动作训练准确率高、验证准确率低过拟合增加Dropout、数据增强、早停某个类别准确率明显偏低类别不均衡调整类别权重或补充样本验证Loss持续不降学习率不合适调低学习率检查归一化CUDA显存不足batch size过大降低batch size开启混合精度Loss输出NaN学习率过大或数据异常减小学习率检查输入数据准确率始终接近随机水平标签顺序错误打印class_to_idx检查映射关系训练很慢但Loss正常网络太深或资源不足换轻量网络用混合精度6. 毕业论文结构与答辩展示的经验之谈6.1 论文结构怎么搭才不容易被挑毛病毕设论文的评阅老师看重的不是代码多复杂而是逻辑链条是否完整。你的论文结构可以完全跟着项目流程走引言与背景、相关技术介绍、需求分析与系统设计、数据集构建、模型训练与实验分析、系统实现与测试、总结与展望。这是一个典型的“从问题到方案再到验证”的闭环。特别要注意的是实验对比部分。不要只写自己的模型达到多少准确率要设对比实验。至少要有三组不做迁移学习的自建CNN、冻结特征层的迁移学习、全层微调的迁移学习。这样就能用数据说明“我为什么选用某个方案”而不是拍脑袋决定的。对比表格里除了准确率还可以加上训练时间、模型参数量这些维度让论文的厚度和说服力都上一个台阶。6.2 答辩PPT和现场演示的几个细节答辩时老师最反感的事情之一是你洋洋洒洒讲10分钟理论基础却说不清自己做了什么。我的建议是PPT控制在15页以内核心顺序调整为研究背景与意义一到两页数据准备过程两页模型方案与设计思路三到四页实验结果与对比三页演示系统两页总结与后续工作一页。现场演示环节务必提前把Gradio应用默认打开到正确端口并跑通一遍。这是老生常谈但几乎每年都有人犯现场传一张图片界面一直转圈圈然后只能尴尬地切回PPT。还有一个小技巧准备2到3张覆盖不同体型的本地测试图同时把模型容易分错的那一张也准备好当老师问到“这个系统有没有缺陷”时主动调出这张图做分析反而能展示你对问题的理解深度。6.3 可以进一步扩展的方向答辩结束后如果想把这个项目继续做下去或者是把这套代码复用到别的任务上有几个自然的扩展方向。一个是多类别联合识别比如同时判断宠物种类和体型模型输出从单一分类变成多任务学习。一个是引入目标检测模型先行定位先用检测框裁出宠物主体再分类对复杂背景的照片会更鲁棒。还有一个方向是把模型部署到移动端用轻量化的量化方法把模型压缩到几十兆做成一款App端的宠物健康助手。这些都是可以在论文“展望”部分写的内容也能成为后续研究的引子。最后说一点我的个人心得。做这类深度学习毕设最大的坑从来不是技术本身而是时间管理。我从选题到完成大概花了六周前两周全耗在数据采集标注上中间两周搭模型调参最后两周写论文和做演示系统。很多同学把数据采集拖到最后结果模型没时间调参论文写得敷衍。提前规划好每一阶段的任务每天固定跑一轮训练记录训练日志你的毕设过程会顺畅得多。这个项目做成之后你收获的不只是一份代码和一篇论文而是一整套“拿到图像分类问题怎么拆解、怎么推进、怎么交付”的方法论。这套思路比分数和评语更值钱。
RELATED

相关推荐

GLM本地部署实战指南:从硬件选型到API封装

GLM本地部署实战指南:从硬件选型到API封装

先把结论放在前面:本地部署大模型没有想象中那么玄乎,但也绝对不是你双击安装包就能完事的东西。我做本地大模型部署已经有小半年时间,从最开始只会在网页上跟GLM系列产品聊天,到后来真正把开源权重拉到自己的机器上跑起来&#x…

📅 2026/10/23 3:31:36
GLM-4-9B-Chat本地部署全攻略:量化、推理引擎与API调用

GLM-4-9B-Chat本地部署全攻略:量化、推理引擎与API调用

GLM-4-9B-Chat这颗开源模型发布以后,我在自己机器上前前后后部署过不止一次,从最早的llama.cpp量化版,到后来的vLLM在线服务,再到压到8GB显存笔记本上的超低资源方案,折腾了一圈下来,踩过的坑基本都摸清了。…

📅 2026/10/23 3:31:36
Windows蓝屏STOP代码解析:从误判陷阱到根因定位

Windows蓝屏STOP代码解析:从误判陷阱到根因定位

简介:本资源是一份面向Windows系统运维人员、IT支持工程师及电脑爱好者的基础排错工具文档,聚焦蓝屏死机(BSOD)错误代码的系统性整理与实用解读。针对用户因不明错误反复重装系统、排查效率低下的痛点,文档详尽收录0x0…

📅 2026/10/23 3:31:36
MORE NEWS

更多资讯

📰

ABP中HttpClient的POST及GET请求方式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

【日拱一卒,三省吾身】2024.12.14随想

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

网盘直链下载助手使用指南:9 大网盘取直链,3 步直连 IDM 与 Motrix

网盘直链下载助手使用指南:9 大网盘取直链,3 步直连 IDM 与 Motrix 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘…

📰

PoB PoE2珠宝系统实战思路:从词缀选择到技能树布局的完整指南

PoB PoE2珠宝系统实战思路:从词缀选择到技能树布局的完整指南 【免费下载链接】PathOfBuilding-PoE2 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding-PoE2 技能树点满了,属性还是差一截?天赋点全花光、装备全拾完…

📰

【日拱一卒,三省吾身】2024.12.10 随想

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

深入理解Linux Netlink:内核与用户态通信的协议与实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬