ARTICLE DETAIL

资讯详情

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

骨骼癌目标检测数据集处理:从解压到YOLOv8训练全流程

骨骼癌目标检测数据集处理:从解压到YOLOv8训练全流程 简介面向医疗影像AI开发与肿瘤学研究的目标检测数据集聚焦骨骼癌病灶的自动识别与定位适用于YOLO系列模型训练、CT/MRI辅助诊断工具开发及医学影像教学。数据规模为训练集908张、验证集380张类别涵盖原发性与转移性骨肿瘤并包含溶骨性/成骨性病变样本标注经临床影像专家校验。压缩包共2000个文件以1288个txt标签文件与710个jpg影像为主另有yaml配置文件与docx说明文档可直接接入主流深度学习框架整体约41MB便于下载与迁移使用。已有86人学习适合需要标准化骨骼肿瘤检测基准数据的算法工程师、放射科研究人员及医学院师生开展模型训练、算法验证与教学实训。1. 骨骼癌目标检测数据集.zip不是拿到压缩包就万事大吉做医学影像目标检测的同行应该都遇到过这种场景费劲从各种渠道找到一个骨骼癌目标检测数据集.zip文件大小动辄几个 GB解压后以为直接就能开始训练结果第一步就卡住。这个标题里的“骨骼癌目标检测数据集.zip”本质上是一份用于目标检测任务的数据集压缩包里面是骨骼病灶的医学影像、边界框标注文件和类别定义。它的价值在于省掉采集、清洗和标注的重复工作但代价是格式转换、标注校验和训练适配全得自己来。适合想用 YOLOv8 在 CT 或 DR 影像上复现骨骼癌检测效果的工程师以及需要快速搭建医学影像检测基线的研究人员。如果你以为解压就是终点那后面的翻车已经在等你了。2. 拆开骨骼癌目标检测数据集之前先搞清三种标注格式和适用场景先别急着解压先弄明白你手上的 zip 里封装的是哪种标注。医学影像数据集不像自然图像数据集那样“下载即得”很多情况下标注格式是 VOC XML、COCO JSON、YOLO txt 三选一甚至同一个 zip 里同时出现两种标注。弄混格式直接训练轻则读不到框重则模型学了一堆错误坐标。2.1 VOC、COCO、YOLO 三种标注格式的字段差异VOC 格式用 XML 文件描述每张图的目标。每个 XML 根节点下是 filename、size 和多个 object 节点每个 object 里有 name 和 bndboxbndbox 给出 xmin、ymin、xmax、ymax 四个绝对像素坐标。这是最早也最直观的格式但也最容易出现坐标顺序颠倒的问题。COCO 格式用单个 JSON 文件描述整个数据集。images 数组存每张图的 id、file_name、width、heightannotations 数组存每个目标框的 image_id、category_id、bbox其中 bbox 是[x, y, width, height]注意不是两个对角点categories 数组定义类别 id 与名称的映射。COCO 的数据组织适合大规模训练但嵌套结构对新手很不友好。YOLO 格式是每张图一个同名 txt 文件每行一条记录class_id x_center y_center width height。这里的坐标全部是相对图片宽高的归一化值取值在 0 到 1 之间。对于骨骼癌这类小病灶归一化坐标很容易因为小数点精度不够而出现偏移所以转出时至少要保留 6 位小数。下面这张表可以快速对照三者的差异点格式存储方式框坐标定义类别定义常见后缀VOC每图一个 XMLxmin, ymin, xmax, ymaxobject/name文本.xmlCOCO全集一个 JSONbbox 为 x, y, w, hcategoriesid 映射.jsonYOLO每图一个 TXT归一化 x_center, y_center, w, h类别 id 从 0 开始.txt如果你的骨骼癌数据集 zip 解压后同时存在 JPEGImages、Annotations 和 labels 三个目录那大概率是 VOC 和 YOLO 双格式打包。这种重复标注看着贴心实则是隐患同一张图片的 XML 和 txt 可能来自不同标注者框的位置和类别名称未必一致。后面做训练前必须选一种作为真值来源不能混着用。2.2 骨骼癌数据集常见的目录结构与命名玄学我见过很多医学影像数据集的目录结构骨骼癌相关数据集最常见的布局是顶层分 Images 和 Labels 两个大目录Images 下按 case 编号放子目录Labels 下按检测方法放 XML 或 TXT。还有一种布局是模仿 Pascal VOC直接叫 JPEGImages、Annotations、ImageSets/Main。命名上最让人头疼的是文件名带后缀差异。比如case_001_1_1.jpg对应的标注文件却是case_001_1_1.xml这还算良心的有些数据集用case001-1-1.dcm标注文件却叫case001-1-1_annot.xml中间多处一个_annot。找对应关系时如果不做一次全量 mismatch 检查训练时八成会遇到 KeyError 或空标签。另外有些数据集会附带 mask 目录存的是病灶分割掩膜。如果只想做目标检测mask 可以暂时不处理但如果你想用分割掩膜反推最小外接矩形注意矩形可能比真实病灶大一圈尤其是骨骼边缘的病灶直接转出的框会带入大量背景。2.3 用 Python 脚本快速盘点 zip 里的图片、标注和类别解压前先用脚本看一眼 zip 内部结构比一个个文件夹点开高效得多。下面这段脚本会列出总文件数、扩展名分布和顶层目录统计帮你快速定位标注类型。import zipfile import os from collections import Counter def inspect_dataset_zip(zip_path): with zipfile.ZipFile(zip_path) as z: names z.namelist() print(总文件数:, len(names)) ext_counter Counter(os.path.splitext(n)[1].lower() for n in names) print(扩展名分布:, ext_counter.most_common()) # 统计顶层目录下的文件数量 dir_counter Counter(n.split(/)[0] for n in names if / in n) for dir_name, cnt in dir_counter.most_common(): print(f目录 {dir_name}: {cnt} 个文件) if __name__ __main__: inspect_dataset_zip(骨骼癌目标检测数据集.zip)这段脚本的关键点是os.path.splitext把所有扩展名统一小写后做统计能立刻看出有没有.dcm、.png、.xml、.json这些分类。有了扩展名分布后你就能判断这个 zip 是否符合预期。如果发现顶层目录分布很散比如一个目录对应一个 CT 序列那说明数据集可能按病例切分而不是按训练/验证切分。这种情况后面做数据划分时要额外小心不要让同一个病例的图像同时出现在训练集和验证集里否则验证结果会虚高。如果想进一步知道标注里有哪些类别可以用下面的脚本在解压后统计 VOC XML 的类别出现次数import xml.etree.ElementTree as ET from pathlib import Path from collections import Counter def count_voc_classes(ann_dir): classes Counter() for xml_file in Path(ann_dir).glob(*.xml): root ET.parse(xml_file).getroot() for obj in root.findall(object): name obj.find(name).text.strip() classes[name] 1 for name, cnt in classes.most_common(): print(f{name}: {cnt}) count_voc_classes(Annotations)这个脚本会告诉你类别名是不是统一。骨骼癌数据集里常见的坑是同一个病灶写成 “osteosarcoma” 和 “Osteosarcoma” 两种大小写不一致会导致类别数翻倍。我一般会在统计后强制做一次小写归一化或者在转换成 YOLO 格式时直接按映射表处理。3. 解压与校验别让 zip 解压和标注丢失拖垮训练拿到“骨骼癌目标检测数据集.zip”后大多数人第一件事就是双击解压然后直接开训。这样做的后果是你可能在几天后才发现图片有一半打不开、标注文件和图片对不上、类别 id 全乱了。解压和校验这一步做扎实后面训练会省心很多。3.1 Windows / Linux 下的解压命令与中文乱码处理Windows 下右键“全部解压缩”就能完成但要注意如果 zip 是 Linux 上压缩的内部文件名编码可能是 UTF-8Windows 资源管理器解压后经常出现“茕茕孑立”式乱码。遇到这种情况我建议用 Python 的 zipfile 手动解压并指定解码方式。Linux 下解压命令就一行但要区分编码场景unzip 骨骼癌目标检测数据集.zip -d dataset如果文件名是 GBK 编码且系统 locale 是 UTF-8上面这条命令会打出乱码。很多国内医院合作数据集在 Windows 上压缩文件名编码用 GBK此时应加-O gbk参数unzip -O gbk 骨骼癌目标检测数据集.zip -d dataset-O参数指定 zip 内部文件名的字符集-d指定解压目录。unzip -O gbk在部分发行版上可能需要安装unzip的 non-UTF8 支持版本没有的话就用 Python 解压代码里把encode(gbk, errorsignore)处理一遍。用 Python 解压时需要注意压缩包内文件名可能带有非法字符或绝对路径尤其是某些 Windows 工具打包出来的 zip 会包含以盘符开头的路径。安全做法是只取文件名部分不保留目录层级import zipfile with zipfile.ZipFile(骨骼癌目标检测数据集.zip) as z: for info in z.infolist(): raw_name info.filename.encode(cp437).decode(gbk, errorsignore) clean_name raw_name.replace(\\, /).split(/)[-1] target fdataset/{clean_name} with z.open(info) as src, open(target, wb) as dst: dst.write(src.read())这里的逻辑是先用cp437还原 zipfile 对非 ASCII 文件名的默认解码再按gbk重新解码。很多国产医学数据集的压缩包就是这样读出来的。errorsignore是为了防止个别文件名里混入无法解码的字节导致整个解压中断。3.2 校验图片完整性、标注与图片一一对应解压完成后先别急着建模。写一个校验脚本让图片和标注做一次全量匹配。影像数据最容易出现的问题是 DICOM 转 JPG 时丢帧或者原始文件部分损坏。from PIL import Image from pathlib import Path from collections import defaultdict def validate_pairs(img_dir, ann_dir, ann_ext.xml): imgs set(p.stem for p in Path(img_dir).rglob(*.*) if p.suffix.lower() in (.jpg, .jpeg, .png, .dcm)) anns set(p.stem for p in Path(ann_dir).rglob(f*{ann_ext})) orphan_imgs imgs - anns orphan_anns anns - imgs print(有图无标注:, len(orphan_imgs), list(orphan_imgs)[:5]) print(有标注无图:, len(orphan_anns), list(orphan_anns)[:5]) # 校验图片文件能否正常打开 broken [] for img_path in Path(img_dir).rglob(*.jpg): try: with Image.open(img_path) as im: im.verify() except Exception as exc: broken.append(str(img_path)) print(损坏图片:, len(broken), broken[:5]) validate_pairs(Images, Annotations, ann_ext.xml)这段脚本先把图片文件名的主干提取成一个集合标注主干提取成另一个集合然后求差集。stem不包含后缀所以case_001_1_1.jpg和case_001_1_1.xml能正确对应。如果文件名本身带_annot、_mask等后缀就需要在求差集前先做一次归一化替换。Image.verify()是 PIL 里轻量级完整性检查不会加载完整像素数据适合大批量图片快速排查。如果图片是 .dcm 格式PIL 打不开你需要用 pydicom 单独校验但一般医学数据集的检测标注都是基于导出后的 JPG/PNG。3.3 处理 zip 伪加密和报错的文件头解压时如果遇到“需要密码”但压缩包里并没有真密码的情况很大概率是 zip 伪加密。这种 zip 将通用标志位第 0 位标记为加密但数据区并没有加密常见于某些老工具打包时误操作。zipfile 遇到伪加密会直接抛出RuntimeError: File is encrypted但文件内容本身可以明文读取。处理伪加密有两个思路。第一个思路是跳过加密判断直接读取原始数据适合文件数量少的临时修复第二个思路是把 ZIP 的加密标志位改写掉生成一个新 zip更适合大批量数据。下面这段脚本实现第二种思路只处理局部文件头和中央目录头里对应的标志位def repair_fake_encrypted(src, dst): with open(src, rb) as f: data bytearray(f.read()) # 先处理局部文件头 PK\x03\x04 i 0 while i len(data) - 4: if data[i:i4] bPK\x03\x04: flag int.from_bytes(data[i6:i8], little) if flag 0x0001: data[i6:i8] (flag 0xFFFE).to_bytes(2, little) # 跳到下一个文件头 compress_size int.from_bytes(data[i18:i22], little) name_len int.from_bytes(data[i26:i28], little) extra_len int.from_bytes(data[i28:i30], little) i 30 name_len extra_len compress_size else: i 1 # 再处理中央目录头 PK\x01\x02 i 0 while i len(data) - 4: if data[i:i4] bPK\x01\x02: flag int.from_bytes(data[i8:i10], little) if flag 0x0001: data[i8:i10] (flag 0xFFFE).to_bytes(2, little) i 1 else: i 1 with open(dst, wb) as f: f.write(data)核心逻辑是把通用标志位字段的第 0 位清零但保留其他标志位不变。局部文件头里的标志位决定 zipfile 读取时是否要解密码中央目录头里的标志位决定解压工具是否显示加密状态。两个都要改否则用 7-Zip 打开仍然显示有密码。注意这个修复只对伪加密有效。如果文件是真加密数据区已经被加密过单纯改标志位只会在解压时报出乱码或 CRC 错误。判断方式很简单修复后用 zipfile 能正常读取内容且 CRC 校验通过就是成功如果读出来是乱码说明数据区确实加密了那只能找原始提供方要密码没有后悔药。4. 把骨骼癌数据转换成 YOLOv8 格式脚本与四个边界坑校验通过后下一步是统一格式。我默认你的目标是 YOLOv8 训练因为现在医学影像检测领域用 YOLOv8 做基线的数量确实不少相关教程和参数也最全。YOLOv8 的data.yaml要求标注文件是 YOLO txt每一行一个框所以必须把 VOC 或 COCO 转成 txt。下面两套脚本可以直接复用但坑在后面四个地方。4.1 从 VOC XML 转 YOLO txt归一化坐标计算VOC 转 YOLO 的公式很固定中心点 x (xmin xmax) / 2 / width框宽 (xmax - xmin) / width所有坐标都除以图片宽高。要注意的是XML 里的size节点必须和图片实际像素一致否则算出来的归一化坐标会整体偏移。import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, class_names): root ET.parse(xml_path).getroot() size root.find(size) img_w float(size.find(width).text) img_h float(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text.strip() if name not in class_names: continue # 跳过未定义的类别 cls_id class_names.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 box_w (xmax - xmin) / img_w box_h (ymax - ymin) / img_h # 取 6 位小数避免误差 lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}) return linesclass_names是一个列表顺序就是 YOLO 类别 id 的顺序。比如[bone_tumor, normal]那么 XML 里的bone_tumor对应 id 0normal对应 id 1。这个顺序在后面对应data.yaml里的names字段必须完全一致否则训练时类别错乱。这里我把xmin xmax除以 2 得到中心点而不是用xmin (xmax-xmin)/2因为数学上等价但前者少一次减法在极大像素坐标下能减少浮点误差。对于骨骼癌这种 CT 图像常见 512x512 或 1024x1024 的尺寸差别不太大但遇到边界框坐标是非整数时中心点计算方式会影响第 6 位小数。4.2 从 COCO JSON 转 YOLO txt处理嵌套 annotationCOCO JSON 转 YOLO 时最容易搞混的是 bbox 字段。COCO 的 bbox 是[x, y, width, height]其中x, y是左上角坐标不是中心点。转换时要自己先算出中心点。import json from pathlib import Path def coco_to_yolo(ann_json, out_dir, class_names): data json.load(open(ann_json, encodingutf-8)) # COCO 的 category id 往往不连续建立到 0..N-1 的映射 cat_id_to_idx {cat[id]: idx for idx, cat in enumerate(class_names)} img_id_to_info {img[id]: img for img in data[images]} # 按 image_id 分组 anns_by_img {} for ann in data[annotations]: anns_by_img.setdefault(ann[image_id], []).append(ann) for img_id, img in img_id_to_info.items(): img_w img[width] img_h img[height] stem Path(img[file_name]).stem lines [] for ann in anns_by_img.get(img_id, []): if ann[category_id] not in cat_id_to_idx: continue coco_cat_id ann[category_id] cls_idx cat_id_to_idx[coco_cat_id] x, y, bw, bh ann[bbox] x_center (x bw / 2.0) / img_w y_center (y bh / 2.0) / img_h box_w bw / img_w box_h bh / img_h lines.append(f{cls_idx} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}) out_file Path(out_dir) / f{stem}.txt out_file.write_text(\n.join(lines), encodingutf-8)需要注意class_names这里我写成了[{id: 1, name: bone_tumor}, ...]这种结构方便直接用cat[id]建立映射。如果你手头只有纯字符串列表要先把 COCO 的 categories 数组转成字典。COCO 的file_name可能带相对路径比如cases/001.jpg。Path(file_name).stem会取出001如果同目录下有两张图都叫001.jpg但在不同子目录输出 txt 会互相覆盖。遇到这种情况要在out_dir下保留原相对目录结构而不是全部平铺。4.3 四个边界坑空标注、类别不连续、多边形框、图像尺寸不一致转换脚本看起来简单但真正跑数据时四个边界坑几乎都会遇到。第一个是空标注图片。有些骨骼癌数据集里阴性样本没有目标框XML 或 JSON 里没有 object/annotation。转出的 txt 是空文件。YOLOv8 训练时空 txt 文件可以用来训练背景但要注意数据划分时不能把它和正样本混在一起统计 mAP否则验证集会因为大量无目标图片导致 mAP 偏低。我的做法是单独保留空标注文件的清单分割数据时按 1:1 混合进 trainval 里只放少量空图做背景测试。第二个是类别不连续。COCO 常见类别 id 是 1、2、5、10中间有空位。如果你直接拿 category_id 当 YOLO 类别 id训练时会看到 num_classes 突然变成 11但实际只有 4 个类别损失函数和类别映射都会错。转换时重新映射到 0..N-1 是必须的操作上面脚本已经处理了。第三个是多边形框。有些医学数据集标注的是分割多边形只有在segmentation字段没有 bbox或者 bbox 是从多边形里算出来的但与你预期不符。如果 JSON 里确实没有 bbox就需要用多边形所有顶点求最小外接矩形x_min 所有点的 x 最小值x_max 所有点的 x 最大值再换算出 bbox 和中心点。这里要当心多边形顶点顺序是内外轮廓嵌套的直接取 min/max 会把空洞区域也算进去不过对于病灶掩膜来说影响通常可接受。第四个是图像尺寸不一致。XML 里的 size 和图片实际尺寸不一致或者 COCO JSON 里的 width/height 是错的。这类问题在多模态数据集里尤其常见比如 ICVL 高光谱数据集转出来的图片尺寸可能和原图差一个维度。转换时我建议直接用 PIL 读取实际尺寸覆盖原文件里的 size 字段而不是信任 XML/JSON 的值。代码如下from PIL import Image def get_real_size(img_path): with Image.open(img_path) as im: return im.size # (width, height)把返回值传给转换函数替换原来从 XML/JSON 读取的 width/height。这一步能避免很多玄学偏移尤其是训练时发现框和病灶错位半个身位的情况。5. 骨骼癌目标检测常见问题排查数据划分、小目标与 zip 损坏转换完格式你以为能训练了但真正的坑在后面。围绕这个数据集我总结三个高频问题每条都按现象、原因、解决来写方便你对照排查。5.1 数据划分时样本重叠导致的结果虚高现象训练时 loss 正常下降验证集 mAP 达到 0.98 甚至 1.0但拿到新的 CT 影像上一测漏检率极高。原因划分训练集和验证集时直接按图片文件随机切分。同一个病例的 CT 切片本来就高度相似可能训练集里出现 case_001 的第 20 张切片验证集里出现 case_001 的第 21 张切片。模型在训练时已经见过几乎一样的图像验证 mAP 自然虚高。这是医学影像数据集最典型的翻车点不按病例分群结果就是自欺欺人。解决按病例号划分数据先提取文件名中的 case 标识比如用正则从case_001_1_1.jpg里抠出case_001保证同一个病例的所有图片只进入 train 或 val。划分脚本如下import random from pathlib import Path def split_by_case(img_dir, train_ratio0.8): case_map {} for p in Path(img_dir).rglob(*.jpg): case_id p.stem.split(_)[0] # 按命名规则提取病例号 case_map.setdefault(case_id, []).append(p.stem) cases list(case_map.keys()) random.shuffle(cases) split_idx int(len(cases) * train_ratio) train_cases set(cases[:split_idx]) val_cases set(cases[split_idx:]) train_files [stem for case in train_cases for stem in case_map[case]] val_files [stem for case in val_cases for stem in case_map[case]] return train_files, val_filessplit(_)[0]是假设文件名格式为case_xxx_yyy_zzz的通用写法。如果你的数据集命名是tumor_01_003.dcm转出来的tumor_01_003.jpg那就取前两个字段。关键点是同一个 case 的所有信息不能被拆散。5.2 医学影像小目标检测标注框尺寸分布与锚点设置现象模型训练几十轮后大的病灶能检测到但小的骨骼转移灶几乎全部漏检验证集 PR 曲线上 recall 在小目标区间掉到 0.2 以下。原因骨骼癌病灶在早期往往只有几十个像素而 YOLOv8 默认的锚点虽然能适应小目标但数据增强时如果没做针对性设置小目标被随机裁剪掉的概率极大。另一个原因是数据集中小目标样本在总样本里占比很低模型严重偏向大目标。解决先统计一下所有标注框的尺寸分布看看 width 和 height 的中位数。如果大量框在 32x32 像素以下属于典型的小目标数据集至少要做三件事。第一训练时启用mosaic0.5甚至关闭 mosaic因为 mosaic 会把四张小图拼在一起小目标再缩一倍就没了。第二把图像 resize 到 640x640 时不要用默认的 letterbox改用保持原分辨率但限制最大边长的策略比如imgsz512配合rectTrue让短边不强制拉伸减少小目标信息损失。第三loss 里的box权重可以适当调高到 0.1 左右同时把cls和dfl保持默认让模型更注重框的位置回归。我一般会在训练前先输出一张框宽高分布直方图如果发现大量框宽高比值极端不均衡比如病灶形状呈长条形还需要考虑旋转增强或调整输入图像的长宽比。5.3 zip 内文件损坏或缺失时的应对策略现象训练时突然报FileNotFoundError或者某张图对应的 txt 文件不存在检查发现 zip 解压出的文件数量比压缩包内少解压过程没有报错但静默丢文件。原因很多医学数据集压缩包是从云盘下载或通过 HTTP 分段下载中途断点续传不完整zip 的中央目录被截断解压工具会漏掉末尾部分文件。另一种情况是原始数据本身就不完整打包者没有校验文件数。解决解压后立即用unzip -t做一次完整校验Linux 下命令为unzip -t 骨骼癌目标检测数据集.zip该命令会逐项读取每个压缩条目并计算 CRC输出到No errors detected才算完整。如果发现有文件 CRC 错误说明压缩包已损坏直接解压不能解决问题。此时先尝试用zip -F修复中央目录但这个命令只对本地文件头完整的 zip 有效。对于截断的 zip我一般会重新请求原始文件或者用文件名清单向数据提供方确认缺失项。更稳妥的做法是下载完先记录 zip 的 SHA256 值和提供方公布的值比对。不要等训练到一半才发现少文件那时候重新下数据代价更大。6. 用训练好的骨骼癌检测模型做一次全流程验证数据集处理完成并训练出best.pt后别急着部署先做一次全流程验证。这一步能帮你判断这个骨骼癌目标检测数据集到底值不值得继续投入。from ultralytics import YOLO model YOLO(best.pt) results model.predict( val_images/case_017_1_1.jpg, conf0.25, iou0.45, saveTrue, save_txtTrue, ) for r in results: print(r.boxes.cls) print(r.boxes.conf) print(r.boxes.xyxy)这段推理脚本会输出预测类别、置信度和像素坐标框。你要做的是把这几个框和原始标注文件手动比照看看坐标偏移是否在一个可接受范围内。医学影像上骨骼癌病灶往往边界模糊医生标注本身就有主观差异所以框偏移几个像素是正常的但偏移超过二三十个像素就需要回头查转换脚本。如果只是看 mAP可以跑模型自带的验证函数model.val(datadataset.yaml, splitval, conf0.25, iou0.5)重点关注 val 集上每个类别的 recall尤其是小目标类别的 recall。如果 recall 低于 0.5这个数据集即便 mAP 再高实际项目也很难用。此时可以考虑增加小目标样本、调整损失权重或者改用更大分辨率的输入。如果 recall 正常那就拿着测试集多跑几遍确认结果稳定。我现在拿到任何一个数据集压缩包第一件事永远是跑校验脚本而不是训练。这个习惯帮我避开了很多翻车现场——文件缺失、标注错位、伪加密全都在半小时内暴露出来。希望这个处理流程也能帮你把“骨骼癌目标检测数据集.zip”变成一份真正可信的训练资源。希望帮到你。本文还有配套的精品资源点击获取
返回列表