ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

YOLO11cls血细胞图像分类实战:1000张小数据集一键训练全记录

YOLO11cls血细胞图像分类实战:1000张小数据集一键训练全记录 简介面向癌症血细胞检测与医疗图像分类任务的YOLO11cls训练数据集包含1000张真实采集自医疗场景的血细胞图片覆盖basophil、erythroblast、monocyte、myeloblast、seg_neutrophil五个类别可用于区分正常与异常细胞形态。数据按类别文件夹进行区分整理标注质量较高无需额外转换即可作为YOLOCLS等分类算法的训练输入也适合作为通用医疗影像分类场景的数据补充。考虑到原始图片体量较大资源以PDF形式交付共1个文件、4.86MBPDF内除数据集基本情况介绍外还附有类别缩略图与百度网盘获取方式便于读者先确认数据组织再完成下载。目前已有51人浏览学习。此外资源附赠YOLO11cls一键训练脚本及博主训练结果日志可快速复现完整训练流程参考训练曲线、超参配置与类别划分思路特别适合医疗图像分类项目开发者和YOLO分类算法学习者直接上手。用YOLO11cls给血细胞做目标分类1000张小数据集从目录整理到一键训练全记录最近在弄血细胞图像分类这个方向正好把一套完整流程跑通了用YOLO11cls对血细胞显微图像做目标分类数据集一共1000张图分好类别放进文件夹再写一个一键训练脚本直接出模型。这篇就把整个项目的数据整理思路、YOLO11cls选型逻辑、脚本设计细节和训练中踩过的坑一次性说清楚。做血细胞分类这件事本质上就是教模型认识显微镜下不同类型的血细胞比如中性粒细胞、淋巴细胞、单核细胞还有和癌症检测相关的异常细胞。模型学会之后输入一张细胞图像它能告诉你这属于哪个类别。我这次的目标是把这套东西做得足够顺手让后面换数据集、加类别、重新训练都只需要改几行配置不需要每次从零开始写代码。这篇文章适合什么人看你手头正好有一些图像数据想做分类但不太想从头理解ResNet那些底层的训练循环或者你想拿YOLO11cls练手但懒得翻官方文档又或者你就是对血细胞分类这个场景感兴趣想看看实际项目里数据怎么组织、训练怎么调参。看完这篇文章至少你能直接复现一套可用的流程。1. 项目整体设计与数据集规划1.1 类目设计与样本分布做图像分类的第一步永远是回答一个问题到底要分几类每类有多少张图这个决定直接关系到模型能不能训练出来。我这个项目对标的是血细胞形态学检验的常见需求。医学上血细胞分类通常涉及五类白细胞也就是中性粒细胞、淋巴细胞、单核细胞、嗜酸性粒细胞、嗜碱性粒细胞再加上红细胞、血小板以及和血液系统恶性肿瘤相关的异常细胞。在1000张图的体量下类别数量我控制在8个以内比较稳妥。每类图大约保持在100到150张这样模型才有足够的数据去学每一类的形态特征。这里有个很现实的经验图像分类模型在小样本下最容易出现的问题就是过拟合——模型把训练集里那几张图的背景、染色深浅都背下来了换一批图立刻露馅。所以类别宁少勿多如果某个类别只有三四十张图我建议先合并到相近类别或者干脆先把这一类从训练计划里拿掉等后续补充了数据再纳入。1000张图看着不少分到8个类别里面每类也就一百多张属于典型的小样本场景整个训练策略都得围绕这个现实来设计。我目前的类目设计是这样的Neutrophil中性粒细胞、Lymphocyte淋巴细胞、Monocyte单核细胞、Eosinophil嗜酸性粒细胞、Basophil嗜碱性粒细胞、RBC红细胞、Platelet血小板、Abnormal异常细胞。前五个是白细胞五分类后面是红细胞、血小板和异常细胞。如果你自己搞数据集类别名称一定要用英文后面YOLO11cls读取的时候对中文路径和类名的兼容性不好命名这步省事后面就麻烦。1.2 目录结构与数据划分方式YOLO11cls对数据集的目录组织有明确的约定训练集和验证集分开每个类别一个子文件夹文件夹的名字就是类别名图片直接放在类目文件夹底下。没有标注文件不需要画框也不需要打点。这也是我推荐新手用YOLO11cls做分类的原因——纯图像分类连标注工具都不用装。目录结构大概是这样的datasets/ cell_dataset/ train/ Neutrophil/ 001.jpg 002.jpg Lymphocyte/ 001.jpg ... val/ Neutrophil/ 101.jpg ...这里最关键的一步是数据划分。我建议不要在整理原始图片的时候就手动分train和val而是把所有类别的原始图先放在一个统一目录里比如all_images/Neutrophil/然后用脚本自动划分。手动拖文件最大的问题是不均匀——手一抖验证集里某些类可能就两张图训练的时候泛化指标就会被某一个类别拖垮。划分比例我用的train/val 85/15同时按类别分层抽样保证每个类别在train和val里面所占的比例和整体一致。这一点在类别样本量不均衡的时候尤其重要。如果某类总共有150张train里面分到120张val里30张这个比例可以接受。但如果某类只有60张train/val按85/15切完可能只有9张在val里评估结果波动就会很大。遇到这种情况可以把划分比例调到9/1或者用5折交叉验证来做更稳的评估。2. YOLO11cls选型分析与运行机制2.1 为什么选YOLO11cls而不是传统CNN分类网络之前好几个项目我用的是ResNet、EfficientNet这类经典分类网络从数据加载器到训练循环都是自己写的代码量不小改个数据增强策略还要翻半天自己当时写的逻辑。这次我为啥换成YOLO11cls最主要的原因是Ultralytics这套框架把整条链路串起来了——训练、验证、推理、导出都用一套API不需要我再去维护一堆自定义脚本。YOLO11是Ultralytics在2024年9月底推出的新版本相比YOLOv8主要改进在模型结构的效率上比如引入了C3k2模块替代之前的C2f同时把分类、检测、分割、姿态估计四种任务统一在同一个框架里。YOLO11cls就是其中的分类模式和YOLOv8-cls一样没有检测框的输出只有类别概率。具体到我们这个1000张血细胞图像的场景YOLO11n-cls和YOLO11s-cls这两个轻量级预训练模型就足够用了。nano版本参数量最少GPU显存占用低跑一轮epoch非常快small版本精度会高一些但也更吃资源。我的建议是先在nano上把整个流程跑通确认数据没问题、loss能降再换small版本做最后的训练。直接用大模型调参一个小失误就要等很久才能发现效率太低。2.2 目录结构自动读取与标签映射原理YOLO11cls读取数据的方式非常直接。训练的时候框架会扫描你指定的train和val目录自动识别里面的子文件夹名称作为类别标签然后按字母顺序生成一个类别到数字ID的映射。也就是说你根本不需要提供额外的标注文件类目文件夹的命名就直接是模型输出的类别名称。这个机制底层是调用torchvision的ImageFolder来加载数据的。ImageFolder要求数据严格按照“根目录/类别名/图片”的组织方式存放然后通过class_to_idx生成映射关系。一旦你在第一步手动把某个类别的图片放错了文件夹模型就会学到一个错误的对应关系而且训练过程不会报任何错误——这类错误最难排查因为训练曲线看起来一切正常就是推理结果跟现实对不上。所以我对目录命名的要求是一律小写英文开头不要带空格和特殊字符不要用中文。之前帮朋友排查过一次问题他的类别命名为Normal Cell和Cancer Cell训练过程中没有任何报错但推理时输出的类别名带了空格后续处理结果的时候一直对不上浪费了不少时间。这类小问题看起来不起眼实际处理起来很折磨人。3. 一键训练脚本设计与实操3.1 脚本整体流程标题里说的“一键训练脚本”其实就是把整个训练流程封装起来从环境检查到最终输出模型只跑一条命令就能完成。我的设计思路是用户只需要提供一个参数——数据集的根目录其余的像类别数、图像尺寸、批次大小、训练轮数这些都用合理的默认值同时允许通过命令行参数覆盖。先看核心部分训练入口的代码import argparse import shutil from pathlib import Path from ultralytics import YOLO def check_environment(): 检查训练所需的基础环境 import torch if not torch.cuda.is_available(): print([提示] 未检测到CUDA将使用CPU训练速度会明显变慢) else: print(f[信息] 检测到GPU: {torch.cuda.get_device_name(0)}) def build_dataset_yaml(data_root: str, save_path: str): 自动生成YOLO分类任务的yaml配置不需要手写 data_root Path(data_root) train_dir data_root / train val_dir data_root / val if not train_dir.exists() or not val_dir.exists(): raise FileNotFoundError( f数据集目录结构错误必须在{data_root}下包含train和val文件夹 ) classes sorted([p.name for p in train_dir.iterdir() if p.is_dir()]) if not classes: raise RuntimeError(train目录下没有找到任何类别子文件夹) yaml_content fpath: {data_root}\ntrain: {train_dir}\nval: {val_dir}\nnames: {classes}\n yaml_path Path(save_path) yaml_path.write_text(yaml_content, encodingutf-8) print(f[信息] 检测到{len(classes)}个类别: {classes}) print(f[信息] 数据集配置已写入 {yaml_path}) return str(yaml_path), classes def train(data_root: str, epochs: int, imgsz: int, batch: int, model_name: str): 执行训练主流程 check_environment() yaml_path, classes build_dataset_yaml(data_root, cell_dataset.yaml) model YOLO(model_name) model.train( datayaml_path, epochsepochs, imgszimgsz, batchbatch, patience20, optimizerauto, lr00.01, augmentTrue, seed42, projectruns/classify, nameexp, )这个脚本的运行方式是python train_cell.py --data ./datasets/cell_dataset --epochs 120 --imgsz 224 --batch 32 --model yolov11n-cls.pt你只需要保证datasets/cell_dataset目录下面有train和val两个子目录脚本会自动扫描类别、生成配置、启动训练。为什么用脚本自动生成yaml而不是手动维护一个最大的好处是换数据集的时候不用去改配置文件脚本读取到的类别列表永远和数据文件夹里的实际内容一致避免数据更新了、yaml忘了改的尴尬局面。3.2 关键参数解析与调优策略参数设置是训练效果好坏的分水岭。我把我实际使用的参数配置和调整逻辑详细说一下。epochs和patience小数据集情况下120个epoch是比较合理的起点配合patience20的早停策略。早停的意思是如果连续20个epoch验证集精度都没有提升训练自动终止并保存最优模型。这个机制特别适合小数据集——训练后期模型已经收敛继续跑只会过拟合早停帮你自动掐断。如果你是第一次跑不要一上来就设300个epoch先在50个epoch下跑通流程看loss下降趋势再逐步增加。imgszYOLO11cls默认是224x224。血细胞图像本身尺寸不大而且单个细胞通常集中在图像中心区域224足够保留形态特征。不建议一开始就调成320或更高因为图像尺寸越大训练耗时和显存占用成倍增加对小数据集来说收益却不明显。有一个经验如果你训练完发现模型对细粒度差异比如嗜酸性粒细胞和嗜碱性粒细胞总是分不清再把imgsz提到256或320试试。batch根据自己的显卡显存灵活调整。12GB显存跑nano模型batch32基本没问题如果你用的显卡比较老或者显存只有6GB降到16也不会影响最终精度太多。batch太小低于8会让梯度估计噪音变大训练不稳定batch太大超过64对小数据集就是浪费模型很快拟合训练集但泛化能力跟不上。lr0初始学习率0.01是我在一堆实验中验证过的稳妥起点。Ultralytics默认的优化器策略是auto它会根据模型类型自动选择AdamW或SGD。在血细胞这类小数据集上我实测AdamW的收敛速度比SGD快而且对学习率没那么敏感。训练过程中如果发现loss震荡得很厉害可以把lr0降到0.005再跑一次。3.3 训练结果验证与最佳实践训练完之后所有结果都会生成在runs/classify/exp/目录下。这个目录里最有价值的三个东西是混淆矩阵confusion_matrix.png、训练曲线results.png和最优权重best.pt。先看results.png里的两条核心曲线训练loss和验证精度。如果训练loss持续下降但验证精度在一段时间后开始波动或者下降这是过拟合的典型信号说明模型把训练集的特征背得太死了。我在EfficientNet和YOLO11cls上都遇到过这个问题通常的解法是加数据增强、增加dropout比例、或者减少训练轮数让早停机制在更早的时候触发。混淆矩阵是我每次训练完第一个看的东西。它展示的是模型在每个真实类别上预测成了什么类别对角线上的数字越大越好。我这次训练完观察到的主要混淆集中在Eosinophil和Basophil两类的判别上——这两种细胞的颗粒染色形态确实很像人眼看都容易搞混模型拿到的训练图又少出现混淆是意料之中的事。这种情况我会先回数据集看看这两个类别的图片质量如果发现某个类别的部分图片本身质量就差或者类别标错了优先清理数据而不是急着调模型结构。推理验证也是完整流程的一部分。简单的验证脚本from ultralytics import YOLO model YOLO(runs/classify/exp/weights/best.pt) results model.predict(datasets/cell_dataset/test/Neutrophil/001.jpg) probs results[0].probs.data.tolist() names results[0].names predicted names[probs.index(max(probs))] print(f预测类别: {predicted}, 置信度: {max(probs):.4f})建议单独留一个test文件夹放测试图片这些图不参与训练也不参与验证只用来做最终效果评估。这个习惯能防止你在无意中通过反复调参去“记住”验证集实际部署时效果打折扣。4. 常见问题与排查技巧实录训练血细胞分类的过程中我碰到的坑不少列一个排查速查表都是实际踩过的问题表现可能原因解决办法训练一开始loss不降反升学习率太大或数据集类别不均衡调低lr0到0.005检查每个类别样本数量差距过大需补充样本训练集精度接近100%但验证集只有70%过拟合加数据增强、设更高的dropout、检查是否有重复图片同时出现在train和valValueError: All classes in your dataset are the same数据划分脚本出问题检查train和val目录下每个类别的图片是否都有分布CUDA out of memory批次或图像尺寸太大降低batch到16或8imgsz降到192训练很快结束但精度很低数据集里有大量错误标注随机抽查几十张图确认每个类别里面的图片是否真的属于该类推理时输出的类别名全是乱码路径或类名包含中文字符统一改成英文类名路径中不要有中文有几个容易忽略但特别关键的细节值得单独说。重复图片问题。我之前整理数据集的时候用过一个数据增强工具生成了一批扩充图后来发现原图和增强图被分到了train和val两个不同的集合里。模型训练的时候等于提前“见过”验证集的变体了验证精度虚高在真实场景中效果大打折扣。如果你也用数据增强扩充过样本务必先按图片内容计算哈希值把所有重复或高度相似的图放在同一集合里。类别不均衡的应对。1000张图分8类很容易出现某些类别特别少的情况。处理方式优先级优先找更多样本找不到就用类别权重。Ultralytics框架里可以通过在yaml里给不同类别设置不同的loss权重来缓解或者用数据增强把少样本类的图翻转、旋转、加噪声来生成新的变体。加倍复制图片是最不推荐的做法模型会严重过拟合被复制的那几张图。验证集图片的标准。血细胞图片在采集时会有染色差异、光照差异、噪点差异th训练集和验证集尽量来自不同的采集批次。如果所有图都是从同一个来源下载的模型学到的可能只是那个来源的固定成像风格换一个来源的数据就失效了。有条件的话可以在网上找不同类型显微镜拍摄的血细胞图片混入训练集这比单纯堆数量有效得多。训练速度优化。CPU上训练的话nano模型一轮epoch跑1000张图大概需要一两分钟100个epoch就是两三个小时还能接受。如果有GPU把torch的混合精度训练打开能再快不少。YOLO11默认就会自动启用混合精度跑之前确认一下你的GPU支持就行。显存不够的时候可以先试试把batch降到8而不是急着换小模型。用户的实际经验是batch从32降到8精度下降通常在1%以内但训练稳定性明显提升对小数据集甚至是更优的选择。脚本复用建议。一键训练脚本的价值在于复用到其他数据集上。我在设计脚本的时候特意把数据集路径作为参数传入而不是硬编码在代码里这样换一个数据集只需要改命令行参数即可。如果你后续想把这个脚本迁移到检测任务只需要把YOLO(yolov11n.pt)换成检测模型再把数据集的目录结构换成images和labels的格式其他部分基本可以复用。5. 项目扩展方向与个人经验总结血细胞分类这个项目做下来我最大的体会是对于这种小规模数据集数据质量和管理方式对最终结果的影响往往大于模型结构本身。我一开始在YOLO11s-cls和YOLO11n-cls之间反复纠结后来发现两者在这个数据量上精度就差了一个多百分点反而是把数据清理了一遍之后整体精度提升了将近5个百分点。对于个人项目来说花时间把类别标注弄准确、图片筛选干净、划分合理收益远大于换一个更大更深的模型。后续这个项目还可以往几个方向扩展。如果拿到了更多数据或者更大的标注集可以尝试把YOLO11s换成分类检测联合训练比如先用检测模型定位血细胞再对每个细胞做分类这样就能处理一张图里有多个细胞的场景。也可以尝试把模型导出成ONNX格式部署到边缘设备上配合显微镜做一个实时的辅助识别工具。不过我要提醒一句这类模型目前更适合作为技术验证和教学研究的参考血细胞诊断是一个极其严谨的医学领域任何实际应用都需要经过严格的临床验证和监管审批不是训练一个模型就能上手的。最后再分享一个小经验训练日志不要删。我每次训练都会把runs/classify目录完整保留过了一两周回来看当时某个实验结果往往能发现之前忽略掉的信息。有一次我在调batch size的时候无意中对比了两个日志的混淆矩阵才发现某个类别在更大batch下错误率明显升高顺藤摸瓜找到了数据划分上的一个bug。这些日志比记忆可靠得多养成保留的习惯后面会少走很多弯路。本文还有配套的精品资源点击获取
返回列表