多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

糖尿病肾病眼底图像数据集:VOC/YOLO双格式详解与YOLOv8训练踩坑指南

糖尿病肾病眼底图像数据集:VOC/YOLO双格式详解与YOLOv8训练踩坑指南 简介糖尿病肾病检测数据集面向医学影像中的糖尿病视网膜病变分级识别任务提供完整的Pascal VOC与YOLO双格式标注数据。资源围绕5个临床分级类别展开包含mild-DR、moderate-DR、normal、proliferation-DR、severe-DR适用于医疗AI算法工程师、科研人员及高校相关专业学生进行模型训练、算法对比与毕业设计。压缩包共2000个文件以XML标注文件为主辅以TXT格式文件与使用说明整体大小约44.31MB解压后无需复杂转换即可接入VOC或YOLO训练流程也可使用LabelImg等标注工具对XML标注进行二次校验目前已有138人学习下载。资源在数据整理与格式适配方面较为便捷五类病变分级覆盖从正常到增殖期的典型样本有助于快速搭建糖尿病肾病检测基线、验证模型泛化能力或进一步开展细粒度分类探索。1. 糖尿病肾病检测数据集VOC和YOLO双标注一次给全先看清这批图像的门道如果你在找一份能直接扔进YOLO训练的医学检测数据集这批4122张糖尿病肾病相关眼底图像值得花十分钟了解。它同时提供了Pascal VOC的xml和YOLO的txt标注覆盖normal、mild-DR、moderate-DR、severe-DR、proliferation-DR五个类别没有做训练集/验证集切分也没有mask分割文件适合目标检测入门、迁移学习、毕业设计或者算法对比。很多新手拿到手就解压开训结果类别索引错、xml和txt对不上白跑一轮。下面我把解压、校验、格式转换、训练前检查到YOLOv8跑通的完整细节和踩坑记录都拆开讲照着做能少走弯路。2. 数据集的真实构成VOC和YOLO两种格式并存先看清再动手很多人拿到压缩包第一反应是直接双击解压然后一股脑扔给训练脚本。我建议你先花五分钟把里面的文件结构盘清楚因为这类医学数据集常有“jpg、xml、txt数量一致但内容对不上”的隐患特别是VOC和YOLO双格式同时提供时两边的类别顺序和坐标范围很容易不一致。2.1 压缩包解开后你应该看到什么按照资源说明压缩包解开后包含的是jpg图片、Pascal VOC格式的xml标注文件和YOLO格式的txt标注文件。数量上三种文件都是4122个一一对应。还有一个“使用前必读.txt”里面一般写的是类别名称、格式说明和引用信息我习惯先读它。文件名是firc_shenbing_数字编号比如firc_shenbing_1063.jpg对应firc_shenbing_1063.xml和firc_shenbing_1063.txt这个命名规律能帮你快速定位问题样本。先看文件类型清单文件类型数量内容说明用途.jpg4122眼底图像模型输入.xml4122Pascal VOC标注基础标注格式.txt4122YOLO格式标注训练时直接读取注意资源说明里特别提到“不包含分割路径的txt文件”意思是压缩包里没有train.txt、val.txt这类文件列表也没有像images/、labels/这样强制分好的目录结构。你需要自己划分训练集和验证集并决定要不要保留原始目录组织。目录结构大概率是下面这样. ├── 使用前必读.txt ├── firc_shenbing_1063.jpg ├── firc_shenbing_1063.txt ├── firc_shenbing_1063.xml ├── firc_shenbing_1065.jpg ├── firc_shenbing_1065.txt ├── firc_shenbing_1065.xml ...如果你解压后发现发布者已经按images、annotations、labels分好了文件夹原理一样不影响下面的检查操作。先做一次最基础的数量校验。在Linux或macOS的终端里进入数据集目录执行ls *.jpg | wc -l ls *.xml | wc -l ls *.txt | wc -l三条命令分别统计jpg、xml、txt文件的个数。如果和4122对不上说明压缩包不完整或者有重复文件后续训练前一定要处理掉。注意wc -l统计的是行数如果文件名带换行符会统计错但这种医学图像数据集基本不会出现。如果担心可以用find . -name *.jpg | wc -l代替。如果你的文件分散在多个子目录里把ls换成find即可find . -name *.jpg | wc -l find . -name *.xml | wc -l find . -name *.txt | wc -l这一步看起来初级但能过滤掉一半的“缺文件”问题。我遇到过有人用网盘下载时部分小文件被静默跳过最后train阶段报错找不到对应标注往往就是这里没查。2.2 VOC标注和YOLO标注的坐标对应关系先打开一个xml文件看一眼。VOC标注每个目标由object节点描述包含类别名和bndbox框坐标annotation size width960/width height540/height depth3/depth /size object namemild-DR/name bndbox xmin128/xmin ymin96/ymin xmax384/xmax ymax288/ymax /bndbox /object /annotation这里xmin、ymin是框左上角坐标xmax、ymax是右下角坐标单位是像素基于原始图片尺寸。而对应的YOLO格式txt文件里一行代表一个目标对象格式是0 0.266667 0.355556 0.266667 0.355556这五个数字依次是类别索引、归一化中心点x坐标、归一化中心点y坐标、归一化框宽、归一化框高。类别索引不是字符串是数字顺序由你在训练配置里定义的classes列表决定这一点是新手最容易踩的坑。从VOC到YOLO的坐标换算关系是x_center (xmin xmax) / 2 / image_width y_center (ymin ymax) / 2 / image_height box_width (xmax - xmin) / image_width box_height (ymax - ymin) / image_height注意除以的是图片的实际宽高不是标注里某个框的宽高。很多人在这里把width/height取成了xml里第一个object的框宽结果所有归一化坐标全部溢出。用上面给出的xml实例代入图片宽960高540框左上角(128,96)右下角(384,288)。那么x_center(128384)/2/9600.2667y_center(96288)/2/5400.3556w(384-128)/9600.2667h(288-96)/5400.3556。正好对应txt里的数字。需要特别注意的是txt中数字的顺序只与CLASSES列表顺序有关与xml文件中object的出现顺序无关。如果同一个图片里有三个框txt里就是三行每行独立。读取VOC标注时你可以改变object的遍历顺序但写入txt时数字索引必须严格按照CLASSES列表来。2.3 用脚本摸清类别分布和空标注情况在开始训练前我强烈建议统计一下每个类别的目标数量。医学影像数据集普遍存在类别不均衡正常样本往往远多于病变样本。写一个Python脚本扫一遍xmlimport glob import xml.etree.ElementTree as ET from collections import Counter xml_files glob.glob(your_dataset_path/*.xml) class_counter Counter() empty_images [] for xml_file in xml_files: tree ET.parse(xml_file) root tree.getroot() objects root.findall(object) if len(objects) 0: empty_images.append(xml_file) for obj in objects: name obj.find(name).text.strip() class_counter[name] 1 print(类别统计:, dict(class_counter)) print(空标注图片数:, len(empty_images)) print(部分空标注文件:, empty_images[:5])脚本思路是遍历所有xml找到每一个object节点的name文本用Counter计数同时如果某个xml文件里没有任何object则记为空标注图片后续训练时应直接排除或人工复标。注意obj.find(name).text.strip()里的strip()很有必要因为有些标注工具会在类别名两侧留下空格不清理会出现“normal”和“ normal ”两个类名YOLO训练时直接多出一个类别。如果这个资源按摘要给出了类别顺序为[mild-DR,moderate-DR,normal,proliferation-DR,severe-DR]你统计出来也应该是这五个名字且数量总和等于所有xml里object的总数。脚本运行后输出的类别统计可以直观告诉你哪一类样本少如果severe-DR或proliferation-DR的数量远低于normal后面训练时必须处理样本不均衡否则模型会对多数类过拟合。如果你想进一步核对txt里的类别索引是否和这个顺序一致可以这样交叉验证import glob for txt_file in glob.glob(your_dataset_path/*.txt): with open(txt_file) as f: for line in f: parts line.strip().split() if len(parts) ! 5: print(字段数异常:, txt_file, line)这只是检查字段数量更严格的索引检查要结合转换脚本完成后面第四章会详细讲。3. 解压和校验7z包的打开方式与数据完整性检查压缩包是.7z格式这和常见的zip、rar不太一样。7z的压缩率高但需要有对应的解压工具很多Linux服务器默认不带7z命令直接解压会报“command not found”。这一章把解压、关联校验和标签数值范围检查一次说清。3.1 Linux和Windows下正确解压7z文件在Ubuntu/Debian服务器上先装p7zipsudo apt install p7zip-full然后解压到当前目录保留包的目录结构7z x 糖尿病肾病检测数据集VOCYOLO格式4122张5类别.7zx表示保留完整路径如果你不想破坏当前目录结构可以指定输出目录7z x 糖尿病肾病检测数据集VOCYOLO格式4122张5类别.7z -o./DRD_dataset注意参数-o后面紧跟目录路径中间没有空格写成-o /path会报错。如果你需要覆盖已存在的文件加-y参数跳过询问7z x dataset.7z -y -o./DRD_dataset解压完成后可以用ls DRD_dataset | wc -l看文件数量是否和预期一致。如果压缩包设置了密码在命令行里用-p传入但密码含特殊字符时极易出错后面避坑章节细说。Windows环境下推荐直接用7-Zip软件。右键压缩包在“7-Zip”子菜单里选择“提取到当前文件夹”即可。如果右键菜单里没有7-Zip也可以先打开7-Zip主界面再双击压缩包进入最后点“提取”。我一般不用Windows自带的“全部解压缩”去解7z因为这个功能只支持zip格式强行解7z会提示格式不支持。这里有个非常常见的问题明明密码输入正确但7z一直提示密码错误。其实绝大多数情况不是密码错而是命令行下密码里的特殊字符被shell转义了。比如密码包含$、、!等字符在bash里直接输入会被解释成变量或历史命令。解决方法是把密码用单引号包起来7z x dataset.7z -p实际密码或者在Windows图形界面里手动复制密码粘贴避免键盘布局或输入法干扰。还有一小部分情况是压缩包本身做了Unicode文件名编码解压时提示文件名乱码但密码仍报错这时候先用LANGC 7z l dataset.7z列出内容看看是否能正常读取列表能读取就说明密码没问题是操作系统编码问题换7-Zip图形界面或加-mcp932这类参数再试。3.2 用Python核对图片和标注是否一一对应不要相信眼睛直接用脚本统计最稳妥。下面的脚本会找出有多余或缺失的标注文件from pathlib import Path data_dir Path(dataset_path) jpg_stems {p.stem for p in data_dir.glob(*.jpg)} xml_stems {p.stem for p in data_dir.glob(*.xml)} txt_stems {p.stem for p in data_dir.glob(*.txt)} print(图片数:, len(jpg_stems)) print(xml数:, len(xml_stems)) print(txt数:, len(txt_stems)) print(缺xml的图片:, jpg_stems - xml_stems) print(缺txt的图片:, jpg_stems - txt_stems) print(多余xml:, xml_stems - jpg_stems) print(多余txt:, txt_stems - jpg_stems)Path.stem返回不带后缀的文件名比如firc_shenbing_1063.jpg的stem是firc_shenbing_1063。通过集合差运算能快速找到不匹配项。如果缺xml说明该图片没有标注不能参与VOC相关训练如果缺txt说明该图片没有YOLO标签直接训练时会报“missing label”错误。这里要说明一点如果发布者把jpg、xml、txt分别放在三个子目录里改一下glob路径比如data_dir.glob(images/*.jpg)、data_dir.glob(labels/*.txt)逻辑不变。注意三个子目录的stem集合要基于同一层级拼接避免同名不同文件造成假阳性。除了文件名对应图片本身也要检查是否损坏。尤其是网盘下载的压缩包偶发某个jpg文件头被截断。用Pillow库快速扫一遍from PIL import Image import glob broken [] for img_file in glob.glob(dataset_path/*.jpg): try: img Image.open(img_file) img.verify() # 不加载像素只验证文件头 except Exception as e: broken.append((img_file, str(e))) print(损坏图片数:, len(broken)) for item in broken[:10]: print(item)img.verify()只检查文件结构是否正确速度很快不会把整个图像读入内存。如果扫出来损坏图片单独记录文件名训练前从数据清单里剔除或用备份文件替换。这个检查对YOLO训练特别重要因为一旦dataloader读到坏图可能整个epoch直接崩掉。3.3 检查YOLO标签数值是否落在0到1区间YOLO的归一化坐标本应在[0,1]范围内但很多转换脚本没做边界保护偶尔会出现cx、cy或wh略大于1的情况。这种标签训练时不会直接报错但会导致loss异常大推理时预测框全部偏向图像边缘。写一个检查脚本import glob bad [] for txt_file in glob.glob(dataset_path/*.txt): with open(txt_file) as f: for line_no, line in enumerate(f, 1): parts line.strip().split() if len(parts) ! 5: bad.append((txt_file, line_no, 字段数不是5, line.strip())) continue try: cls_id, cx, cy, w, h map(float, parts) except ValueError: bad.append((txt_file, line_no, 数字解析失败, line.strip())) continue if not (0 cx 1 and 0 cy 1 and 0 w 1 and 0 h 1): bad.append((txt_file, line_no, f越界 c{cx:.3f},{cy:.3f} w{w:.3f} h{h:.3f}, line.strip())) print(异常行数:, len(bad)) for item in bad[:10]: print(item)这个脚本把每个txt文件的每一行拆成五个字段逐一检查类别索引是否为有效数字、中心坐标和宽高是否在合法区间。如果找到了越界标签需要回溯对应的xml和原始图片重新计算或用第四章的转换脚本重新生成。正常情况下这份数据集应该一行异常都没有。如果你看到大量越界建议先怀疑解压是否完整再怀疑发布者的转换脚本是否靠谱。4. 把VOC转成YOLO格式转换脚本、坐标换算和两个绕不开的坑虽然这份资源已经同时给了xml和txt但你在实际使用中几乎一定会遇到需要自己转换的场景比如给这批数据补充新标注、把其他来源的VOC数据合并进来、或者想更换类别顺序。自己掌握转换逻辑比每次都求助于在线转换网站可靠得多。4.1 一个可以直接跑的VOC转YOLO脚本下面是一个我常用的批量转换脚本直接用Python标准库不依赖额外包import os import glob import xml.etree.ElementTree as ET # 类别顺序必须与后续训练data.yaml中的names顺序完全一致 CLASSES [mild-DR, moderate-DR, normal, proliferation-DR, severe-DR] def convert_voc_to_yolo(xml_path, output_dir): tree ET.parse(xml_path) root tree.getroot() img_w float(root.find(size/width).text) img_h float(root.find(size/height).text) lines [] for obj in root.findall(object): name obj.find(name).text.strip() if name not in CLASSES: print(f跳过未知类别 {name} in {os.path.basename(xml_path)}) continue cls_id CLASSES.index(name) bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) if lines: os.makedirs(output_dir, exist_okTrue) txt_path os.path.join(output_dir, os.path.basename(xml_path).replace(.xml, .txt)) with open(txt_path, w) as f: f.write(\n.join(lines)) if __name__ __main__: xml_dir path/to/xmls out_dir path/to/txts for xml_file in glob.glob(os.path.join(xml_dir, *.xml)): convert_voc_to_yolo(xml_file, out_dir)几个关键点你需要知道。CLASSES列表的顺序直接决定输出txt中每个框的类别索引。如果这个列表和训练时的data.yaml里的names顺序不一致模型会学混淆。我见过有人VOC转换时用字典排序训练时用手写顺序结果normal和mild-DR整体置换测试时完全没法看。root.find(size/width)这里用了带斜杠的路径ElementTree支持这种相对查找。有些标注工具会在不同层级放置图片尺寸信息比如在annotation下有个segmented节点宽度信息就放在size节点里。转换前先打印一个xml的root结构确认路径不出错。f{cls_id} {x_center:.6f} ...用格式化字符串控制小数位数六位小数已经足够YOLO训练使用不必保留全部浮点位数文件体积也更小。如果你要把这个脚本改成命令行工具可以在末尾加argparse来接收xml目录和输出目录这样不修改代码就能复用到其他VOC数据集。4.2 归一化坐标的边界保护和负值处理医学影像里经常出现所谓“贴边框”——病灶区域一直延伸到图片边缘人工标注时会把xmax标成图片宽度。这时候(xmax - xmin)除以图片宽度正好等于1.0YOLO的w1.0是合法值但如果某些图像增强库对1.0宽度做了缩放容易在Mosaic或RandomAffine时产生NaN。我一般会在转换时加一个下限保护w (xmax - xmin) / img_w h (ymax - ymin) / img_h # 防止浮点误差造成的负值或零值 w max(min(w, 1.0), 1e-6) h max(min(h, 1.0), 1e-6) x_center max(min(x_center, 1.0), 0.0) y_center max(min(y_center, 1.0), 0.0)1e-6是个很小的数避免因标注错误导致宽度为0。如果你发现某个框的xmin大于xmax说明原始xml有坐标顺序问题这类样本需要记录下来另行处理不要默默clip掉。转换前最好先校验VOC框的合法性省得生成一堆无意义的txtfor obj in root.findall(object): bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) if xmin xmax or ymin ymax: print(f非法框: {os.path.basename(xml_path)}, {obj.find(name).text}) continue if xmin 0 or ymin 0 or xmax img_w or ymax img_h: print(f越界框: {os.path.basename(xml_path)}, {obj.find(name).text})这段代码把异常框打印出来而不是带病转换。很多老数据集里有个别框坐标溢出图片边界不处理的话训练时可能不会崩溃但推理结果会莫名对不上。4.3 坑类别索引从0开始以及Windows环境的路径转义我见过最典型的翻车就是把类别索引写成从1开始。VOC里第一个类别的名字对应YOLO索引0很多人受Excel表格从1开始的习惯影响把mild-DR写成了1结果所有框都被误判成moderate-DR。这个问题不会导致训练崩溃但会让precision和recall完全错乱且很难发现因为loss还在下降。排查方法是随机抽几个txt文件读取第一个数字再回到对应的xml里看第一个object的name对照CLASSES列表确认索引一一对应。下面的代码可以帮你做这个抽查import glob import random CLASSES [mild-DR, moderate-DR, normal, proliferation-DR, severe-DR] sample_txts random.sample(glob.glob(path/to/txts/*.txt), 5) for txt_path in sample_txts: xml_path txt_path.replace(.txt, .xml) with open(txt_path) as f: first_line f.readline().strip() cls_id int(first_line.split()[0]) print(txt_path, -, CLASSES[cls_id], 对应xml中的第一个object)另一个坑在Windows下批量处理时路径分隔符是反斜杠。如果代码里直接手写路径拼接比如out_path labels/ txt_file.split(\\)[-1]一旦漏掉转义就会把路径写错。我习惯统一用os.path.basename或Path(txt_file).name来取文件名不要在字符串里手工处理目录分隔符。批量转换完成后务必再跑一次数量校验ls path/to/xmls/*.xml | wc -l ls path/to/txts/*.txt | wc -l两个数字应该一致。不一致时优先查是否有xml里没有object的情况因为我的脚本在lines为空时不会创建txt文件这是预期行为但要心里有数。5. 训练前排查清单五个最容易翻车的细节这一章不聊网络结构只聊把数据集喂给YOLO之前最值得花时间排除的五个坑。每一个都是我或者周围同事实际踩过的写出来帮大家省时间。5.1 现象一训练日志里类别数不对mAP总在低位徘徊原因xml里有类别名和txt里的索引对不上或者某些txt里写了不在CLASSES范围内的类别索引。这个数据集本身类别固定5个但如果你合并过其他数据或者用labelimg重新保存过xml可能会出现类别名大小写不一致比如“Normal”和“normal”被当成两个类别。解决训练前用第四章的抽查脚本从txt反查xml确认每个数字索引都对应正确的类别名。同时跑一遍全量标签扫描grep -RhoE ^[0-9] labels/ | sort -n | uniq -c这条命令统计labels目录下所有txt第一个字段类别索引的出现次数。如果输出里出现了5以上的数字说明有越界类别索引需要立即定位并修正。注意grep的-o会匹配出每个符合条件的数字-h禁止输出文件名-R递归目录。5.2 现象二图片能正常打开但训练时突然报错“Expected 3 input channels, got 4”原因一部分医学图像是RGBA四通道或者带有透明度通道。YOLOv8默认输入是三通道RGB四通道图片在数据加载阶段会直接崩溃。这类图片用系统自带看图工具能显示肉眼很难发现。解决写一段预处理脚本把所有图片统一转成RGB三通道并覆盖保存from PIL import Image import glob for img_path in glob.glob(dataset_path/*.jpg): img Image.open(img_path).convert(RGB) img.save(img_path, quality95)convert(RGB)会把RGBA、灰度图、调色板图都统一成RGB三通道。注意如果原图是灰度图转换后虽然变成三通道但三个通道内容相同训练速度会稍慢但不影响推理。如果还想顺便修复EXIF旋转方向可以用Pillow的ImageOps.exif_transpose。5.3 现象三所有验证结果都偏向normal病变框全部漏检原因这是典型的类别不均衡。医学筛查类数据集中正常样本占比很高这个数据集虽然每张图都有标注但可能出现1000个normal目标对应200个proliferation-DR目标。模型训练时对占多数类的样本过拟合导致少数类几乎不预测。解决先跑2.3节的统计脚本打印每个类别的目标个数。如果少数类数量少于多数类的一半建议做三类处理一是按类别比例重采样图片让每类的目标数量接近二是使用YOLOv8的class_weights参数给少样本类别更大损失权重三是简单粗暴把少数类的图片复制几份加入训练集但不建议复制超过3次否则模型会对重复样本过拟合。对于这份数据我建议先看看normal和其他DR分级的比例再决定用哪种方案。5.4 现象四自己划分训练集和验证集后训练集loss和验证集loss趋势一样但实测效果差原因数据划分时出现了泄漏。最常见的做法是用random.shuffle打乱所有文件名再按比例切分但你可能在划分前解压了两次数据集路径里包含了两份完全相同的图片副本或者同一个病人的不同眼底图被随机分到了训练集和验证集。由于医学数据集没有官方划分文件编号里的firc_shenbing_可能蕴含患者级信息跨患者验证才更合理。解决先按文件名去重再按编号分组划分。简单做法是只保留一份副本然后固定随机种子import os import random random.seed(42) files os.listdir(dataset_path) random.shuffle(files) split int(len(files) * 0.8) train_files files[:split] val_files files[split:]固定随机种子能保证每次运行划分结果一致避免调参时因数据划分不同导致无法复现实验。如果你怀疑存在患者级泄漏可以先把文件名前缀相同的图片全部归入同一个集合再划分这样验证集更接近真实场景。5.5 现象五解压后txt文件行尾是^M字符训练时标签解析报错原因在Windows下编辑过txt后行尾符可能从LF变成CRLF某些YOLO数据加载器在Linux下解析时会把\r一并读入导致坐标值变成0.266667\rfloat()转换失败。解决用sed清理整个labels目录的行尾符sed -i s/\r$// dataset_path/*.txtsed -i直接修改原文件s/\r$//表示把每行结尾的回车符删除。改完后再跑一次3.3节的检查脚本确认没有解析异常。这个坑在Windows下用labelimg保存的txt里特别常见初看文件完全正常但一进训练就报错。6. 用这个数据集跑通YOLOv8目录组织、配置文件和验收技巧当你把前面的检查都做完下面这些步骤能让你在半小时内跑出第一版模型。先把数据集组织成YOLO要求的目录结构。我习惯在项目根目录下建一个datasets/DRD文件夹然后按train/val划分图片和标签datasets/DRD/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/用下面的Python脚本完成划分并复制文件import shutil from pathlib import Path src Path(dataset_path) dst Path(datasets/DRD) split 0.8 jpg_files sorted(src.glob(*.jpg)) stop int(len(jpg_files) * split) for i, jpg in enumerate(jpg_files): sub train if i stop else val shutil.copy(jpg, dst / images / sub / jpg.name) shutil.copy(jpg.with_suffix(.txt), dst / labels / sub / jpg.with_suffix(.txt).name)然后写data.yamlpath: datasets/DRD train: images/train val: images/val names: 0: mild-DR 1: moderate-DR 2: normal 3: proliferation-DR 4: severe-DR训练命令我一般用yolo train datadatasets/DRD/data.yaml modelyolov8n.pt epochs100 imgsz640 batch16 device0yolov8n.pt是小模型适合先验证数据管线通不通。epochs先跑100看趋势batch大小按显存调整12GB显存用16通常没问题。训练完成后验证阶段我会这么做跑一次带混淆矩阵的完整验证yolo val modelruns/detect/train/weights/best.pt datadatasets/DRD/data.yaml plotsTrue然后重点看confusion_matrix.png不是只看mAP。医学检测场景里漏掉一个病变比多框一个正常区域严重得多所以我会把置信度阈值调低到0.15左右观察recall曲线的变化。再拿一批完全没参与训练的外部图片逐个跑推理记录误检和漏检专门看normal和proliferation-DR这类边缘类别。我很早以前踩过一个坑只依赖mAP选模型结果某个模型mAP挺高但对severe-DR的recall只有0.5因为正样本太少被整体带偏。从那以后我每次训练完都强制自己走一遍“混淆矩阵 外部图片推理样本”的验证流程并对每一类单独看precision/recall不再用单一指标说事。这套流程对这份糖尿病肾病数据集同样适用希望帮到你。本文还有配套的精品资源点击获取
返回列表