ARTICLE DETAIL

资讯详情

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

淋巴细胞目标检测数据集详解:从HE切片到YOLOv8训练

淋巴细胞目标检测数据集详解:从HE切片到YOLOv8训练 简介淋巴细胞目标检测数据集是一份面向医学影像与YOLO目标检测任务的行业级数据集适用于病理辅助诊断、免疫微环境评估、淋巴细胞计数等AI模型开发场景。压缩包共2000个文件以1152个txt标注文件、846张jpg病理图像为核心另附1个yaml配置和1个docx说明文档整体约67.68MB目录结构清晰可直接用于模型训练与推理。数据集总计1152张医学图像按训练580、验证290、测试282划分类别为Lymphocyte淋巴细胞全部采用YOLO格式边界框标注由医学专家校验覆盖密集细胞簇等复杂病理分布场景能很好适配YOLOv5/v7/v8及更高版本算法。数据源自医学病理图像数据库涵盖淋巴细胞典型分布场景标注文件支持扩展至细胞计数、密度分析等下游任务。已有60人浏览学习适合医疗AI研究人员、病理诊断系统开发者及免疫治疗分析者可用于淋巴细胞自动识别、癌症病理分析、药物疗效评估中的免疫细胞定量研究。1. 淋巴细胞目标检测数据集1,152 张 HE 切片为什么值得一跑病理科每天要出几百张免疫组化切片淋巴细胞计数是淋巴瘤分级和免疫状态评估的硬指标人工在 40 倍镜下逐视野点数一天下来眼睛都是花的。如果你需要训练一个目标检测模型去自动识别病理切片里的淋巴细胞这个资源就是为这件事准备的训练 580、验证 290、测试 282合计 1,152 张医学图像统一 YOLO 标注格式类别聚焦 Lymphocyte可直接喂给 YOLOv5/v7/v8 甚至更新的检测框架不用再花一周去整理格式、划分数据集。它解决的不只是“有没有数据集”的问题而是把数据划分、标注格式、医学专家校验这些原本要返工的活提前做完。适合正在做病理辅助诊断、免疫治疗研究或者刚入门想拿医疗数据练手的开发者。2. 数据集拆解从 CD3CD20 文件名读懂标注与切片来源2.1 压缩包里的文件构成Roboflow 导出结构的典型样子这批数据从文件名看明显是从 Roboflow 平台导出的。.rf.后缀就是 Roboflow 导出时给每张图像加的唯一标识后面跟一串 hash。文件名主体的CD3CD20_Lymphocyte_193_069632_081920_HE_png每一段都有含义后面我会逐个拆。先看压缩包解开后最可能出现的目录结构lymphocyte_dataset/ ├── train/ │ ├── images/ │ │ ├── CD3CD20_Lymphocyte_193_069632_081920_HE_png.rf.xxx.jpg │ │ └── ... │ └── labels/ │ ├── CD3CD20_Lymphocyte_193_069632_081920_HE_png.rf.xxx.txt │ └── ... ├── valid/ │ ├── images/ │ └── labels/ ├── test/ │ ├── images/ │ └── labels/ ├── data.yaml └── README.txt这里train/images和train/labels必须一一对应同名 jpg 和 txt 配对。如果你解压后看不到data.yaml自己在根目录建一个就行这个文件后面训练的时候要喂给 YOLO。压缩包里的划分比例是 580:290:282约等于 5:2.5:2.5这在目标检测数据集里属于合理水平测试集占了近四分之一说明划分者希望模型在独立数据上的表现能被真实评估而不是只盯着验证集调参。由于文件名明确带.rf.我判断这是 Roboflow 导出时勾选了“YOLO format”后生成的目录结构标准做法是每张图配套一个同名的.txt标注文件。2.2 文件名里的信息从 CD3CD20 到坐标编号文件名CD3CD20_Lymphocyte_193_069632_081920_HE_png能读出几个关键信息。CD3CD20是免疫组化双标染色的标志物组合CD3 标记 T 细胞CD20 标记 B 细胞这在淋巴瘤病理诊断里非常常见。Lymphocyte是类别名说明这批数据标注的对象就是淋巴细胞而不是单独区分 CD3 阳性还是 CD20 阳性。193大概率是病例或切片编号069632_081920更像原始全切片WSI上某个 patch 的像素坐标。最后HE_png表示这是 HE 染色切片导出的 PNG 图像。我处理过不少病理切片导出的数据集这种命名方式几乎成了惯例从 WSI 上裁剪 patch 时把病例编号和 patch 原点坐标写进文件名方便后续追溯。这意味着什么如果你要做数据划分绝对不能按文件名随机分而应该按193这类切片编号去分。否则同一个切片上的相邻 patch 会同时出现在训练集和测试集里验证时指标虚高部署到真实切片上立刻翻车。这个问题我后面在避坑章会展开。2.3 YOLO 标注格式的读取把归一化坐标转成像素框YOLO 格式的标注文件是纯文本每行代表一个目标五个数字依次是类别ID 中心点x 中心点y 框宽 框高所有坐标都做了归一化值域在 0 到 1 之间。要可视化检查标注质量你需要把这些归一化坐标乘回图像的宽高。下面这个脚本可以快速把标注转成像素坐标并打印出来from PIL import Image img_path CD3CD20_Lymphocyte_193_069632_081920_HE_png.rf.xxx.jpg label_path img_path.replace(.jpg, .txt) with Image.open(img_path) as im: w, h im.size # 图像实际宽高单位像素 with open(label_path, r) as f: lines [line.strip() for line in f if line.strip()] for line in lines: cls, cx, cy, bw, bh line.split() cx, cy, bw, bh map(float, (cx, cy, bw, bh)) x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) print(fclass{cls} bbox({x1}, {y1}, {x2}, {y2}), size{x2 - x1}x{y2 - y1})逻辑上没什么技巧核心是w和h必须从图像读出来不能猜不能用 640 或 512 硬算。病理切片的原始分辨率经常是 1024 或 2048猜错尺寸会导致画出来的框全部偏移。跑完后建议随机挑 20 张图把x1, y1, x2, y2用cv2.rectangle画上去人工看一眼淋巴细胞的框应该是紧贴细胞边界、没有大面积包含周围组织如果框整体偏小或偏大说明标注或转格式过程有问题趁早发现比训练完再排查省力得多。2.4 类别与场景分布单类别数据集的任务边界整个数据集只有一个类别Lymphocyte这既是优势也是边界。优势在于训练简单不需要做类别不平衡处理直接训练收敛快。边界在于它做不了后续的亚型分析——你不能从这套数据知道某个淋巴细胞是 CD3 阳性还是 CD20 阳性。如果项目需求是“辅助诊断淋巴瘤并区分 T/B 细胞来源”这套数据只能作为第一阶段的检测模型第二阶段需要额外标注 CD3/CD20 的类别信息。摘要描述里也明确了它的应用场景是“识别病理切片中的淋巴细胞辅助医生评估免疫微环境”所以拿到数据后先想清楚需求再动手单类别模型和细粒度分类模型的训练管线差别不小。3. 把数据集跑进 YOLOv8环境配置、data.yaml 与训练参数3.1 解压与目录规划unzip 之后先做这两件事这一步看似基础但我在处理 Roboflow 导出的数据时踩过坑。压缩包解压到 Linux 服务器上unzip是最直接的方式mkdir -p ~/projects/lymphocyte_detection cd ~/projects/lymphocyte_detection unzip lymphocyte_dataset.zip -d ./lymphocyte_dataset如果解压报错“Invalid or unsupported zip format”大概率是 Windows 下压缩的 zip 带了特殊标记可以用 7z 兜底7z x lymphocyte_dataset.zip -oly mphocyte_dataset解压后第一件事是确认目录完整性检查train/labels下的 txt 数量和train/images下的 jpg 数量是否一致差一个都会在训练时报找不到标注文件。我一般用一条命令快速核对cd ~/projects/lymphocyte_detection find ./lymphocyte_dataset/train/images -name *.jpg | wc -l find ./lymphocyte_dataset/train/labels -name *.txt | wc -l两个数字对不上先回到解压环境排查别急着开训练。第二件事是确认 txt 内容格式随机挑一个用cat查看cat ./lymphocyte_dataset/train/labels/xxx.txt正常输出是一行五个数字例如0 0.3125 0.6789 0.0234 0.0312。如果你看到的是Lymphocyte 0.31 0.67 0.02 0.03这种带类别名的格式说明导出的不是纯 YOLO 格式需要先做一次类别名到 ID 的映射转换YOLO 训练时读的是数字 ID不是字符串。这两种格式我在不同数据集里都碰到过0.1 秒的确认能省下一下午的排错时间。3.2 写 data.yaml路径、类别与训练/验证/测试指向YOLOv8 系列训练时需要一个data.yaml文件告诉训练器三件事数据路径、类别数量、类别名称。先看标准写法path: ./lymphocyte_dataset train: train/images val: valid/images test: test/images nc: 1 names: 0: Lymphocyte这里有几个细节容易错。path字段是基准路径如果设置成相对路径YOLO 会以当前工作目录为基准拼接train/images如果设置成绝对路径就写死机器上的位置。我一般推荐写成相对路径方便把整个项目目录打包带走。nc: 1表示单类别names的长度必须等于nc类别名可以自由起但必须和标注文件里的 ID 一一对应。test字段不是必须的训练阶段只用train和valtest是后续评估专用。如果你拿到手的压缩包只给了 train 和 validtest 目录不存在就把test那行删掉不影响训练。3.3 启动训练YOLOv8s 起步显存不够就换 nano环境用 ultralytics 官方包一条命令装完pip install ultralytics然后启动训练cd ~/projects/lymphocyte_detection yolo detect train \ modelyolov8s.pt \ datadata.yaml \ epochs100 \ imgsz640 \ batch16 \ device0 \ seed42逐个解释参数。modelyolov8s.pt选择预训练权重作 backbones 版本在速度和精度之间最均衡。如果你的显卡显存只有 8G把模型换成yolov8n.pt精度掉一点但训练和推理都快很多。imgsz640是输入分辨率淋巴细胞的直径在 HE 切片上通常只有 10-20 像素640 的分辨率对单细胞检测偏小我建议显存够就拉高到 960这个后面避坑章细说。batch16按显存容量调整太大直接 OOM太小训练慢。device0指定第一块 GPU没 GPU 就删掉这行用 CPU 跑但 1,152 张图 CPU 训练会非常痛苦不推荐。seed42固定随机种子确保两次训练结果可复现这个对论文和实验对比很重要。启动后终端会打印每轮的 loss 和 mAP 指标同时生成runs/detect/train目录里面存了权重、日志和训练曲线。首次训练建议先跑 20 个 epoch 验证流程通不通再跑满 100 个避免第三天发现数据路径配错导致白跑。3.4 训练过程监控日志、曲线与断点续训训练不是启动完就撒手不管。前 10 个 epoch 重点看两处loss是否在下降val的 mAP 是否从 0 开始抬升。如果 loss 在 1.5 附近震荡超过 10 个 epoch大概率是学习率或数据问题。ultralytics 默认会自动做 cosine 学习率衰减前 3 个 epoch 是 warmup所以前期 loss 有波动是正常的但 20 个 epoch 后仍无明显下降趋势就要干预了。断点续训用以下命令yolo detect train \ modelruns/detect/train/weights/last.pt \ datadata.yaml \ epochs100 \ imgsz640 \ batch16 \ device0注意model参数换成last.pt训练进度会从断点继续但 epochs 记得改成总轮数而不是剩余轮数否则会自动停下来。训练结束后best.pt是验证集指标最优的权重last.pt是最后一个轮次的权重我一般只保留best.pt。4. 验证结果与模型落地从 mAP 到 ONNX 导出的完整链路4.1 验证集指标解读mAP50、mAP50-95 与医学场景的取舍训练完第一件事是跑验证集看看模型在没见过的数据上的真实水平yolo detect val \ modelruns/detect/train/weights/best.pt \ datadata.yaml终端会打印mAP50、mAP50-95、precision、recall四项指标。病理检测场景里我更看重recall因为漏掉一个淋巴细胞意味着诊断信息的丢失而误检的框医生还能在复核时发现。recall 低时优先降低置信度阈值或提高输入分辨率。mAP50-95 是一个更严格的综合指标对框的位置精度敏感淋巴细胞这种小目标mAP50-95 通常只有 mAP50 的 6-8 成如果差距太大说明框定位有系统偏差检查标注框和报告坐标是否一致。4.2 用 predict 跑一张 HE 图可视化与阈值调整验证集跑完挑一张测试图像的检测结果直观感受下yolo predict \ modelruns/detect/train/weights/best.pt \ sourcetest/images/xxx.jpg \ conf0.25 \ saveTrueconf0.25最低置信度阈值高于这个值的框才会输出。病理切片上标注噪声相对大建议先 0.25 偏低跑看漏检有多少再逐步提升到 0.5 观察误检比例。用 Python 推理可以拿到更细的中间结果from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.pt) results model.predict( sourcetest/images/xxx.jpg, conf0.25, iou0.45, saveTrue, ) boxes results[0].boxes for box in boxes: x1, y1, x2, y2 box.xyxy[0].tolist() score box.conf[0].item() print(fbbox({int(x1)}, {int(y1)}, {int(x2)}, {int(y2)}) conf{score:.3f})iou0.45是 NMS 的 IoU 阈值细胞密集场景下框很容易互相重叠两个淋巴细胞挨在一起这个值设太高会把相邻框误合并成一个设太低则同一个细胞出多个框。我一般从 0.45 开始调密集团块数据调到 0.3 效果更好。4.3 导出 ONNX 与部署前的后处理模型要落地到病理辅助诊断系统PyTorch 权重通常不够。ultralytics 一行导出 ONNXyolo export modelruns/detect/train/weights/best.pt formatonnx opset12导出的best.onnx可以直接用 ONNX Runtime 推理不需要再依赖 PyTorch 环境。部署时注意输入分辨率必须和训练时一致训练用imgsz640推理时就 resize 到 640如果部署管线里用别的分辨率结果会明显变差。病理图像通常是大尺寸(几千乘几千)常见做法是先把整图切成 patch逐 patch 推理再把坐标映射回原图坐标系这一步推荐用slice-inference这类小工具能省掉自己写 overlap 逻辑的时间。如果只做研究不部署这章看到这里就够了直接跳到下一章避坑。5. 避坑与排查病理切片检测的五个真实教训5.1 训练不收敛loss 不降或直接 NAN现象train loss 在前 10 个 epoch 里从 2.1 掉到 1.9 后横住不动val loss 反而上升严重时 loss 变成 NAN。 原因学习率过高导致梯度震荡输入分辨率太低淋巴细胞特征被下采样糊掉。 解决先把学习率降到lr00.001开warmup_epochs5同时把imgsz从 640 提到 960让单个细胞的像素面积更大。改完再跑 20 个 epochloss 明显稳步下降再继续。医学小目标数据集上我遇到的不收敛案例 80% 是分辨率问题不是网络结构问题。5.2 验证集高分、测试集翻车数据泄露这一关现象val mAP50 到了 0.85test 一跑只有 0.4差了一倍。 原因数据划分时按图像随机分配同一个切片(文件名里的 193、167 那些编号)的相邻 patch 同时进了训练集和测试集模型相当于“看过”测试图的一部分区域。 解决重新做数据划分按文件名中的病例编号分组同一个编号的所有 patch 必须全部进同一集合。用 python 脚本按编号切分例如编号 193 的 patch 全进训练集、编号 222 的全进测试集。我自己的血泪经验是病理切片数据集任何时候都先按病例分组划分再谈训练。5.3 密集细胞簇漏检严重小目标与 NMS 的博弈现象单张图里有 50 个淋巴细胞聚成一团模型只检出 15 个且漏掉的大多是紧挨着的相邻细胞。 原因默认 anchor 尺寸偏大对直径 20-40 像素的小目标不敏感NMS 阈值太高导致相邻细胞的框被合并。 解决把imgsz提高到 960 甚至 1280iou0.3降低 NMS 合并倾向。还可以用 ultralytics 的自动 anchor 优化脚本重新统计数据集的框尺寸分布。最直接的做法是看results的框尺寸直方图如果绝大多数框宽高在 20 像素以下就考虑用更高倍率切图或者小目标检测专用模型。5.4 显存溢出batch、imgsz 与梯度累加现象RuntimeError: CUDA out of memory。 原因imgsz960和batch16叠加后显存超了。 解决先降batch8再不行开梯度累加。ultralytics 没有内置的 accumulate 参数但可以在 pyTorch 里手动模拟每 2 个 batch 更新一次梯度。其实最省事的策略是换成yolov8n.pt显存占用能砍一半精度掉 2-3 个点对于淋巴细胞检测这种单类任务影响不大。显存不足时优先换小模型不要急着降分辨率。5.5 换一台机器推理时误检暴增染色差异与数据增强陷阱现象训练集验证 mAP 0.8把模型放到另一家医院的切片上推理框出来一片假目标。 原因数据增强里的hsv_h、hsv_s随机变换把 HE 切片的颜色分布拉得过宽模型学到的是颜色不变性而非形态特征新切片的染色条件和训练集差异巨大产生了分布外偏移。 解决训练时调低增强参数hsv_h0.01、hsv_s0.2甚至关掉更稳的方案是推理前对新数据做染色归一化把色调映射到训练集的分布上。病理染色差异是这类数据集最大的坑没有之一模型精度再高换个染色批次照样翻车所以增强参数宁保守不要激进。6. 进阶用检测结果做淋巴细胞计数与免疫评分6.1 从 bbox 到细胞计数检测的最终目的是计数。模型跑完一张图框的数量近似等于淋巴细胞数量但直接数框容易把低置信度误检也数进去。我会在计数时额外加一个稍高的置信度门槛from ultralytics import YOLO model YOLO(best.pt) results model.predict( sourcewhole_slide_patch/001.jpg, conf0.4, iou0.3, verboseFalse, ) boxes results[0].boxes count len(boxes) print(flymphocyte count: {count}) # 计算细胞密度 area_cm2 0.0125 # 单视野面积单位平方厘米 density_per_cm2 count / area_cm2 print(fdensity: {density_per_cm2:.1f} cells/cm2)这里的conf0.4比推理阈值高是为了过滤低质量检测。area_cm2需要根据切片实际面积换算不同显微镜参数差异很大直接写死数值复现不了得用你自己显微镜的视场直径算。6.2 从单类扩展到 CD3/CD20 亚型分析当前数据是单类Lymphocyte但文件名里的CD3CD20提示这批切片来自双标染色。如果你的后续研究需要区分 T 细胞和 B 细胞可以在这个数据集的基础上做二次标注把Lymphocyte细分为CD3和CD20两类然后继续用 YOLO 训练。这种做法比从零收集数据省事因为位置信息已经标好了只需要在现有 bbox 上追加类别属性。标注工具用 labelImg 或 Roboflow 都行别手动改 txt容易把坐标改坏。6.3 固定随机种子让实验不再是玄学同一个数据集反复训练两次结果差距很大这种情况十有八九是随机种子没固定。YOLO 训练命令里显式传seed42NumPy 和 PyTorch 的随机种子也要在脚本开头固定import random import numpy as np import torch random.seed(42) np.random.seed(42) torch.manual_seed(42) torch.cuda.manual_seed_all(42)从那以后我每次换新数据集都会强制走一遍“先固定种子 → 再训练 → 再人工核对 20 张可视化结果”这个流程一步都不省。实验对比时能明确知道指标差异来自模型改进而不是随机噪声。希望帮到你。本文还有配套的精品资源点击获取
返回列表