news 2026/10/9 21:44:50

战车卫星图目标检测数据集全流程:标注转换、切图与训练避坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
战车卫星图目标检测数据集全流程:标注转换、切图与训练避坑

简介:面向目标检测研究与开发者的战车卫星图数据集,专为处理军事侦察、安防监控与自动驾驶等场景中的装甲车辆识别任务而构建。资源内含1000张1024×1024像素的高清彩色卫星图,目标涵盖坦克、步兵战车等多种装甲车型,可支撑YOLO、Faster R-CNN、Mask R-CNN等主流目标检测框架的训练与验证。压缩包除图像外,还附有批量重命名脚本、信息说明文档及对应标注文件,标注以边界框形式给出目标位置,为模型提供清晰监督信号;卫星图像特有的光照变化、遮挡和远距离目标等挑战,可用于评测算法在复杂环境下的鲁棒性。整包约343.63MB,目前已有2902人学习下载,适合具备计算机视觉基础的研究者、算法工程师及军事相关领域开发者,用于模型训练、超参数调优与检测性能对比分析,亦可直接作为遥感目标检测课题的基准数据集使用。

1. 战车卫星图目标检测:这份数据集到底能干什么

第一次拿战车卫星图数据集跑目标检测,验证集精度看着不错,换到一张完整的大图上却基本漏检,当时心里只有一个词:翻车。问题不在网络结构,而在卫星视角本身——装甲车、战车这类目标在遥感图里常常只有几十个像素,道路、建筑、树影全是干扰。这套人工智能目标检测数据集(战车卫星图2)要解决的正是这个场景:把高空俯拍影像中的战车与装甲车标注出来,喂给主流目标检测框架做训练,帮你在小目标检测方向少走弯路。适合两类人,一是刚接触遥感目标检测、想做点实际训练的新手,二是从自然图像模型迁移到卫星数据后精度骤降、正在排查原因的从业者。拿到手先别急着训练,把数据分布看清,后面的脚本能省你好几天。

2. 数据集结构与标注格式:拿到手先做这三件事

这类战车卫星图数据下载下来通常是一个压缩包,解压后目录结构大同小异。我的习惯是不急着打开训练脚本,先花十分钟把三件事做掉:核实文件目录、搞清标注格式、跑一次数据质量体检。这三件事决定后面所有操作是顺利还是反复返工。很多新手一上来就把数据集路径填进训练配置,结果不是标签读不出来,就是训练到一半发现坐标全错,回头再查,时间全搭进去了。

2.1 目录组织与文件清单:先确认这套数据是哪一代

典型的目录结构一般是这样的:

  • JPEGImages/:原始卫星影像,JPG或PNG,一张图对应一个文件;
  • Annotations/:VOC格式的XML标注,文件名和JPEGImages里的图片名一一对应;
  • ImageSets/Main/:train.txt、val.txt、test.txt,每行一个不带扩展名的图片ID;
  • 部分版本会额外提供labels/(已转好的YOLO txt)或者annotations.json(COCO格式)。

有些打包版本为了适配不同框架会放两份标注,内容一致但格式不同。我一般先打开ImageSets/Main里的txt确认作者给的划分方式,如果这个目录是空的,说明划分要靠自己完成。这里有个容易踩的点:labels/里的txt不一定是和当前JPEGImages/完全对应的,有的发布者会漏掉一部分图片的标签,只靠肉眼根本看不出来,必须用脚本统计一下文件数量和ID匹配情况。

路径内容用途
JPEGImages/原始影像(JPG/PNG)模型输入
Annotations/VOC XML标注目标框坐标、类别名
ImageSets/Main/train/val/test ID列表数据集划分依据
labels/ 或 annotations.jsonYOLO或COCO备用标注跨框架迁移

真正需要仔细检查的是XML里object节点的name字段——同一类目标叫法是否统一。我见过label里tank、armor、armored_vehicle混着来的版本,可能只是不同批次标注的人叫法不同,但在转格式和计算类别数时会直接让脚本崩掉。检查方法是抽十来个XML看一下,或者用下一章的统计脚本把全部标签列出来。另外,如果目录里存在labels/,建议还是自己用XML重新转一份,而不是直接用打包的txt,你不确定它和原图尺寸是否匹配、坐标是否被压缩过。

2.2 标注格式映射:VOC、COCO与YOLO三种读法

先花两分钟把三种主流标注格式对齐,后面就不会被坐标搞晕。VOC的XML把目标框记录成xmin、ymin、xmax、ymax四个像素值,含义简单直接,左上角点和右下角点。COCO的annotations.json里,每条标注用[x, y, width, height]表示,也是像素坐标,但注意它和VOC的顺序不一样,x和y是框左上角,后面是宽高。YOLO格式则完全不同,它把坐标归一化到0到1之间,存储中心点横坐标、中心点纵坐标、框宽、框高,全部除以原图尺寸,所以不管原始分辨率是多大,txt里的值都在0到1之间。

这个换算关系是卫星图数据集中最容易被忽略的地方:

  • 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

这里image_width和image_height必须是该图原始尺寸,不是某次resize后的尺寸。很多训练框架内部读图片时会把原图直接缩放,同时会把label按原尺寸归一化,如果你在外部先缩放,就会出现框和内容对不上,训练半天模型学了个寂寞。

再看旋转框的问题。部分卫星图数据集为了提高标注精度,用的是四点多边形或者带旋转角度的矩形框,这类标注在XML里可能写成rotated_bndbox或八个点的polygon。如果遇到这种结构,不要硬塞给按水平框设计的YOLO训练管线。常见做法是选用支持旋转框检测的模型,或者用旋转框的外接矩形生成水平框,同时接受一定程度的背景误差。转之前先看清楚,别等训练报错才回头。

2.3 数据质量快速体检:别让标注问题拖累训练

体检不需要精确到每张图,但要有一个整体感觉。我一般检查四项:一是空标注图,没有目标的背景图占比多少。如果占比低,说明作者已经做了初步筛选;如果有一半图没有目标,就要考虑保留部分作为负样本。二是图像尺寸是否一致,如果原始影像尺寸横跨几百像素到几千像素,训练时统一resize会对小目标极不友好,后面大概率需要切图。三是目标框尺寸是否离谱,有的目标明显只有20像素,却标着50像素的框,导致训练时模型学到的是“把框扩大一点也行”,mAP很难提升。四是类别是否出现异常,比如某个类只出现在几张重复背景里,模型容易过拟合到特定纹理。

体检脚本不另写,用第3章的统计脚本直接跑一遍,就能覆盖大部分检查项。跑完之后,建议抽50张图把标注框画出来,用OpenCV把矩形画到原图上,肉眼扫一遍。这个操作能看到框和车厢边缘是否贴合、有没有框住两辆车、有没有漏标。虽然只花十几分钟,但能避免后面三天莫名其妙的调参。从经验看,数据质量有问题时,调什么网络结构都很难救回来。

3. 用脚本摸清数据分布:目标太小是卫星图的头号问题

在把数据送进模型之前,先回答三个问题:目标在图像里占多大面积、每张图平均有多少目标、各类别数量是否均衡。卫星图目标检测和自然图像目标检测的本质差别就在这——同样的检测模型在COCO上表现不错,换到卫星图上精度掉一半,多半是数据分布变了,模型没见过这么小的目标。

3.1 目标尺寸与纵横比分布统计

先写一个脚本把全部XML里的目标框尺寸统计出来,这段代码很短,但对后续所有决策都有用。

# stat_annotations.py:统计全部XML标注的目标尺寸与数量 import os import glob import xml.etree.ElementTree as ET from collections import defaultdict import statistics xml_dir = "Annotations" # 改成你的标注目录 widths, heights = [], [] per_image_counts = [] class_counter = defaultdict(int) for xml_path in glob.glob(os.path.join(xml_dir, "*.xml")): tree = ET.parse(xml_path) root = tree.getroot() # 读原始图尺寸 size = root.find("size") img_w = int(size.find("width").text) img_h = int(size.find("height").text) count = 0 for obj in root.findall("object"): name = obj.find("name").text class_counter[name] += 1 bnd = obj.find("bndbox") xmin = float(bnd.find("xmin").text) ymin = float(bnd.find("ymin").text) xmax = float(bnd.find("xmax").text) ymax = float(bnd.find("ymax").text) widths.append(xmax - xmin) heights.append(ymax - ymin) count += 1 per_image_counts.append(count) print("图片数:", len(per_image_counts)) print("目标总数:", len(widths)) print("每图目标数 中位数:", statistics.median(per_image_counts)) # 目标宽度中位数和十分位 sorted_w = sorted(widths) print("目标宽度 中位数:", statistics.median(widths), "p10:", sorted_w[len(sorted_w)//10]) print("目标高度 中位数:", statistics.median(heights)) print("类别统计:", dict(class_counter))

逻辑说明:逐个解析XML,把size节点里的图宽图高取出来,再遍历object节点读取目标框,把每个目标宽高记录到列表里。用中位数而不是平均值,是因为个别超大的标注会拉高平均值,掩盖小目标问题。class_counter用defaultdict统计每个类目标数,方便看类别间的数量差距。

参数说明:xml_dir改成自己的Annotations路径即可。所有坐标都用float()做转换,避免有的XML标了带小数坐标而报错。p10是排序后第10%位置的值,它比中位数更能反映“大量目标到底有多小”。

拿到结果后怎么判断:如果目标宽度中位数低于40像素,说明这批数据普遍是小目标。常规backbone下采样5次后,一个40像素的目标在特征图上只剩一个点,信息几乎丢光,后面训练要么提高输入分辨率,要么换支持小目标的检测头。如果宽高比大部分集中在1附近,说明目标是接近方形的战车;如果出现大量2.0以上的长条框,说明数据集里可能有坦克或长车厢车辆,anchor设计要考虑长宽比。

3.2 切图策略:大图切成可训练的小图

几千像素的卫星原图直接进模型,显存装不下,硬缩放到640会让30像素的目标缩到几乎不可见。常见做法是滑窗切图:把大图切成固定尺寸的小块,同时把标注框同步裁剪。切图的核心是保证目标完整落在某个窗口里,并且裁剪后的坐标正确。

# crop_sliding.py:按滑窗切图并同步裁剪、过滤标注 import os import cv2 import glob import xml.etree.ElementTree as ET WIN_SIZE = 1024 # 切图窗口尺寸 OVERLAP = 256 # 窗口重叠像素 STEP = WIN_SIZE - OVERLAP # 滑动步长 MIN_KEEP = 0.7 # 目标最小保留面积比例 SRC_IMG = "JPEGImages" SRC_XML = "Annotations" OUT_IMG = "cropped_images" OUT_LABEL = "cropped_labels" def load_boxes(xml_path): tree = ET.parse(xml_path) root = tree.getroot() boxes = [] for obj in root.findall("object"): bnd = obj.find("bndbox") xmin = float(bnd.find("xmin").text) ymin = float(bnd.find("ymin").text) xmax = float(bnd.find("xmax").text) ymax = float(bnd.find("ymax").text) boxes.append([xmin, ymin, xmax, ymax]) return boxes def crop_and_save(img, boxes, ox, oy, save_id): patch = img[oy:oy+WIN_SIZE, ox:ox+WIN_SIZE] new_boxes = [] for xmin, ymin, xmax, ymax in boxes: # 计算目标在当前窗口内的可见区域 nxmin = max(xmin, ox) nymin = max(ymin, oy) nxmax = min(xmax, ox + WIN_SIZE) nymax = min(ymax, oy + WIN_SIZE) if nxmax <= nxmin or nymax <= nymin: continue inter_area = (nxmax - nxmin) * (nymax - nymin) full_area = (xmax - xmin) * (ymax - ymin) # 只保留完整度足够高的目标框 if inter_area / full_area < MIN_KEEP: continue new_boxes.append((nxmin - ox, nymin - oy, nxmax - ox, nymax - oy)) if new_boxes: cv2.imwrite(f"{save_id}.jpg", patch) with open(f"{save_id}.txt", "w") as f: for b in new_boxes: f.write(" ".join(str(int(v)) for v in b) + "\n") os.makedirs(OUT_IMG, exist_ok=True) os.makedirs(OUT_LABEL, exist_ok=True) for img_path in glob.glob(os.path.join(SRC_IMG, "*.jpg")): base = os.path.splitext(os.path.basename(img_path))[0] xml_path = os.path.join(SRC_XML, base + ".xml") if not os.path.exists(xml_path): continue img = cv2.imread(img_path) h, w = img.shape[:2] boxes = load_boxes(xml_path) for oy in range(0, h - WIN_SIZE + 1, STEP): for ox in range(0, w - WIN_SIZE + 1, STEP): crop_and_save(img, boxes, ox, oy, f"{OUT_IMG}/{base}_{ox}_{oy}")

逻辑说明:先用load_boxes把XML里的水平框读出来,然后按滑窗逐步移动窗口。每到一个窗口位置,计算每个目标框落在窗口内的可见面积,如果可见面积占原框面积的比例小于MIN_KEEP,就丢掉这个框,避免模型学到半截目标。裁剪后的坐标要减去窗口的左上角坐标(ox, oy),因为在新图片里坐标系原点变成了窗口左上角。

参数说明:WIN_SIZE主要取决于显卡显存,1024是中等显存的稳妥值,显存充足可以设1280,目标更小时甚至可以用1536。OVERLAP设256,能保证小尺寸目标至少完整落在一个窗口里,同时不会产生太多重复样本。MIN_KEEP设0.7是个经验值,设太高会把大量目标滤掉,设太低则给训练增加低质量框。切完图建议抽50个窗口看一眼,确认目标没有被切得只剩一个角。

还有一点容易被忽略:如果你的目标本身大于窗口尺寸,那无论如何都不可能完整保留,这时要么把该目标从样本中剔除,要么改用更大窗口。卫星图里极少数目标可能出现这种情况,不用强行处理,统计一下占比,低于1%直接丢弃不影响效果。

3.3 类别不平衡与背景样本的处理

数据分布统计往往还会暴露类别失衡。战车卫星图数据里,坦克和装甲车两类数量差距可能达到五倍甚至更高。两个实用方向:

一是类别权重,在损失函数里给少数类更高的权重,降低多数类主导梯度。很多框架在训练配置里直接支持class_weights参数,不需要自己实现损失函数。

二是样本增强,对少数类做复制粘贴增强或过采样。与自然图像不同的是,卫星影像里目标大多是俯视视角,可以自由旋转粘贴,只要背景不穿帮就行。不推荐简单重复复制同一张图,模型容易记住样本本身,而不是学到泛化特征。

背景样本的处理:如果统计时发现大量图没有目标,这部分背景图不要丢。把它们切成固定尺寸的背景块,作为负样本放进训练集,模型能学到“道路、建筑、树影不是装甲车”,对全图推理时的虚警压制非常明显。负样本也可以来自有目标图片中那些没有目标的切块,这类样本来源多,且天然贴近真实场景分布。我一般在分类统计里单独建一个background目录,训练时把背景块路径写进训练列表,让模型在前景和背景之间学会平衡。

4. 转成YOLO格式并跑通一次训练:完整链路

数据分布看清楚了,切图也做了,这一步把标注从VOC转成YOLO格式,然后划分数据集,跑通一次完整训练。YOLO格式之所以常用,是因为脚本读取效率高、一行一个目标,而且和框架自带的增强、损失函数无缝对接。就算资源包本身带了labels/,我也建议用XML重新转一遍,保证版本一致。

4.1 VOC转YOLO:目录与归一化坐标

转换的核心是坐标归一化。前面2.2讲过换算公式,这里直接落到脚本:

# voc2yolo.py:VOC XML 转 YOLO txt import os import glob import xml.etree.ElementTree as ET # 按实际数据集标签调整,顺序决定类别ID CLASSES = ["tank", "armored_vehicle"] def convert(xml_path, label_dir): tree = ET.parse(xml_path) root = tree.getroot() img_w = int(root.find("size/width").text) img_h = int(root.find("size/height").text) lines = [] for obj in root.findall("object"): name = obj.find("name").text if name not in CLASSES: print(f"未知类别: {name} in {xml_path}") continue cls_id = CLASSES.index(name) bnd = obj.find("bndbox") xmin = float(bnd.find("xmin").text) ymin = float(bnd.find("ymin").text) xmax = float(bnd.find("xmax").text) ymax = float(bnd.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 lines.append(f"{cls_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}") base = os.path.splitext(os.path.basename(xml_path))[0] out_path = os.path.join(label_dir, base + ".txt") with open(out_path, "w") as f: f.write("\n".join(lines)) os.makedirs("labels", exist_ok=True) for xml_path in glob.glob("Annotations/*.xml"): convert(xml_path, "labels")

逻辑说明:先把XML里size节点的宽高读出来当作归一化分母,然后遍历所有object,把类别名映射为类别ID,再读bndbox四个坐标,转换成YOLO五元组。坐标保留6位小数,既能满足精度,也不会让文件变大。

参数说明:CLASSES的顺序决定类别ID,第0类是tank,第1类是armored_vehicle,后续训练yaml里names的顺序必须一致,否则会出现标签错位。转换时遇到未知类别,我选择打印并跳过而不是直接崩溃,因为卫星图数据里“多写一个空格”“大小写不一致”太常见了,先让转换跑完,再回头统一处理这些异常。

转换完检查一下输出文件数量,和XML数量对比。如果少了文件,多半是XML解析出错,比如标注里出现负数坐标。这时候回到第2章说的体检步骤,把那些异常的XML单独挑出来修掉。

4.2 划分训练集与验证集:按整图划分而不是按切块划分

很多人在这一步偷懒,直接对所有切块图随机按比例划分。这么做验证集精度会虚高得离谱——同一张原始大图切出来的块,可能一半在训练集一半在验证集,模型等于见过“同一片地”了。正确做法是先以原始图片ID为粒度划集合,再对切块分批。

# split_dataset.py:按原图ID划分训练/验证/测试集 import os import random IMG_DIR = "JPEGImages" # 原图目录 TRAIN_RATIO = 0.8 VAL_RATIO = 0.1 ids = [] for f in os.listdir(IMG_DIR): if f.lower().endswith((".jpg", ".jpeg", ".png")): ids.append(os.path.splitext(f)[0]) random.Random(42).shuffle(ids) n_train = int(len(ids) * TRAIN_RATIO) n_val = int(len(ids) * VAL_RATIO) train_ids = ids[:n_train] val_ids = ids[n_train:n_train + n_val] test_ids = ids[n_train + n_val:] with open("train.txt", "w") as f: f.write("\n".join(train_ids)) with open("val.txt", "w") as f: f.write("\n".join(val_ids)) with open("test.txt", "w") as f: f.write("\n".join(test_ids))

逻辑说明:先收集原图ID,shuffle后按比例切成三段,每个txt每行一个ID。参数说明:seed固定42,保证后续实验可复现;TRAIN_RATIO和VAL_RATIO可以按自己数据量调整,验证集我一般保持不低于总图片数的10%。注意这里划分的是原图ID,如果你已经做了切图,需要用原图ID做前缀匹配,让同一原图的切块全部进入同一个集合。

另外一个细节:如果官方给的ImageSets/Main存在,可以直接用,那是作者自己的划分,更容易复现他们的报告。只有在自己需要重新划分或交叉验证时才重写。

4.3 训练参数与验证指标:从mAP看数据集质量

训练配置先给一个数据集描述文件:

# armor_sat.yaml,放在训练的 datasets 目录下 path: ./armor_sat train: images/train val: images/val nc: 2 names: 0: tank 1: armored_vehicle

训练命令以YOLOv5/v8系列为例:

python train.py --data armor_sat.yaml --weights yolov5s.pt --img 1280 --batch 16 --epochs 100 --device 0

命令参数说明:img从默认640调到1280,是因为目标框中位数小,分辨率翻倍等于给模型更多可用的目标像素。batch 16是中等显存的常见配置,显存不够降到8,够用就往上加。epochs先跑100轮,看val曲线是否在最后20轮还在涨,如果还在涨就续跑。

验证注意点:不要只用切块的验证集算mAP,还要抽几张大原图做滑窗推理,全图检测效果才是这个数据集的真实水平。指标上重点看每类的AP,以及mAP@0.5和mAP@0.5:0.95的差距——这两个数字差得多,基本可以断定定位精度不足。下一章的坑2会详细说这个现象。

5. 避坑:卫星图目标检测常见的五个坑与对应解法

以下五个问题是我在类似卫星数据集上反复踩过的。每条按现象、原因、解决三步写,对照自己的实验记录排查,比盲调参数有效得多。

5.1 验证集mAP高,换大图漏成筛子

现象:在切块验证集上mAP@0.5能到0.85,换到真实大图上目测只能检出四分之一。

原因:切图后随机划分数据集,同一原始大图的切块同时出现在训练集和验证集,模型见过了绝大部分纹理上下文,验证集数字是“背题”的结果。另外全图推理和切块推理的尺度不一致,模型没见过小目标在全景里的上下文特征,漏检自然发生。

解决:按原图ID划分集合,已经切好的块先记录归属原图ID,再做分层划分。推理时不要一次性resize全图,而是滑窗推理加NMS合并,窗口尺寸和训练时保持一致。这一步做完,验证集数字会“变难看”,但真实场景表现会反过来变好。

5.2 mAP@0.5高但mAP@0.5:0.95特别低

现象:mAP@0.5能到0.8,mAP@0.5:0.95只有0.2左右,目标能框住但框总是不够准。

原因:卫星目标像素少,几个像素的偏移在IoU上被放大。IoU阈值从0.5提到0.75时,小目标框稍微歪一点就低于阈值,定位精度不足直接反映在0.95曲线上。

解决:输入分辨率提到1280或更大;backbone和neck保持不变时,锚框尺寸整体缩小;边框回归的损失权重适当调高。如果框架支持多尺度训练,把尺度范围从0.5到1.5拉大,也能改善不同尺寸目标的定位能力。

5.3 切图把目标切成两半,标签被过滤掉

现象:训练集构建完成后,目标总数比原始标注减少了三成,验证时模型对小目标几乎无感。

原因:滑窗重叠设的是0,或者MIN_KEEP设到0.9,把大量边框被窗口边缘切断的目标过滤掉了。

解决:重叠设到128以上,让同一目标至少完整出现在某一个窗口里。过滤阈值用0.7,而不是0.9。切完图抽样看50个切块,确认标注框和目标的贴合度,再进训练。

5.4 标签叫法不统一,转换脚本直接崩

现象:voc2yolo脚本跑到一半报KeyError,打开XML一看,同一类目标三种名字。

原因:标注是分批次做的,不同标注的人用了不同缩写,比如tank、armor、armoured_vehicle、Tank都有。

解决:先用统计脚本把所有类别名列出来,然后建一个映射表,统一成一套标准名称再转格式。不要直接在转换脚本里一个个加elif,那样标签会越补越乱。正确的做法是准备一个{原始标签: 标准标签}字典,转换时先映射,再写入YOLO文件。

5.5 虚警一片,模型把道路和屋顶当战车

现象:漏检不多,但全图推理时框满天飞,道路、停车场、屋顶全是误检。

原因:训练集里负样本太少,模型没有足够多“这里没有目标”的样本去压制背景响应。小尺寸目标天然容易激活高分辨率特征图,误报更多。

解决:加入背景切块组成的负样本。一张无目标大图可以切出几十个负样本块,合成一个负样本目录。训练时正负样本比例控制在1:2到1:3左右,对虚警有明显的抑制作用。如果虚警还是压不住,再配合第6章的难例挖掘。

6. 进阶:用旋转增强与硬负样本把精度再拉一截

6.1 旋转增强与标注同步变换

卫星图和自然图像最大的区别是没有“正立”概念,装甲车头朝哪个方向都可能。自然场景里常用的水平翻转能提供的角度变化非常有限,建议在数据增强里加入90度、180度、270度旋转,配合镜像翻转,相当于把每个标注样本的有效朝向扩到八种。

实现时需要注意标注同步变换。如果直接用训练框架内置的几何增强,框架会自动转换标注框,这是最省事的方式;但如果自己写预处理,一定要把中心和宽高坐标同步旋转,旋转后框的宽高会互换,这一点容易忽略。我常用的做法是先放弃任意角度的旋转增强,改用90度、180度、270度加镜像,用框架内置参数直接开启,简单且不存在角度旋转后的坐标漂移问题。对卫星图来说,离散角度带来的收益已经很大,而且省心。

6.2 背景负样本与难例挖掘

把无目标切块直接合成负样本目录,第3章说了做法。这里说难例挖掘:第一轮训练结束后,用当前模型对训练集里的背景图和大图上无目标窗口做推理,把预测置信度高于0.3的样本挑出来,加入训练集。这些是模型自己“认错”的样本,针对性特别强,对压低虚警非常有效。

难例挖掘的节奏要控制好。第二轮加入的负样本比第一轮的更难,模型会变得更保守;如果发现mAP下滑,说明负样本比例过大,回调正负比例。这个平衡点每个数据集都不一样,需要自己试两三次,感觉它就相当于模型在这个数据集上的“脾气”。从那以后我每次拿到新数据集,都会先花半小时跑分布统计,再决定要不要切图、要不要加负样本、用多大输入分辨率;切完图先抽50张人工看一眼再进训练。这套流程虽然不起眼,却帮我避免过好几次“验证集好看、上线翻车”的尴尬。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 21:43:31

深入理解人工智能 AI-RAN Alliance(AI无线接入网联盟)

AI-RAN Alliance&#xff08;AI无线接入网联盟&#xff09;是一个成立于2024年的全球性产业联盟&#xff0c;旨在推动人工智能&#xff08;AI&#xff09;与无线接入网&#xff08;RAN&#xff09;的深度融合&#xff0c;构建“AI原生”的下一代网络架构。该联盟发展迅速&#…

作者头像 李华
网站建设 2026/10/9 21:42:44

Android跑步轨迹App开发实战:定位平滑、地图画线与数据持久化

简介&#xff1a;这是一套基于 Android Studio 与 Java 开发的运动跑步类 App 完整源码&#xff0c;面向具备一定安卓基础、希望练习定位与地图绘制、数据持久化等实战技能的开发者。项目围绕跑步场景实现实时速度记录、跑步路径绘制、跑步数据履历管理与数据详情查看等核心功能…

作者头像 李华
网站建设 2026/10/9 21:41:34

Java方法深度解析:从语法基础到重载递归与工程实践

写方法这件事&#xff0c;几乎是每个Java开发者的第一道基本功。我见过太多新手&#xff0c;循环嵌套写得飞起&#xff0c;一到抽方法就卡壳&#xff1a;参数不知道传几个&#xff0c;返回值不知道怎么写&#xff0c;更要命的是&#xff0c;重构时动一个方法牵扯出一堆问题。这…

作者头像 李华
网站建设 2026/10/9 21:41:24

别再逼测试学Python:低代码测试才是测试团队的正解

前阵子有位测试主管跟我说&#xff0c;他们组的新人培训计划又加了二十节Python课&#xff0c;结果三个月过去&#xff0c;能独立写脚本的只有两个人&#xff0c;剩下的全在用CtrlC和CtrlV“续命”。类似的场景我见了太多次。所以今天聊一个可能有点得罪人的观点&#xff1a;别…

作者头像 李华
网站建设 2026/10/9 21:37:24

VSTO Word插件开发实战:VS2022源码解析与避坑记录

简介&#xff1a;Word 插件 VS2022 源码是一套面向 C# 开发者和 Office 二次开发入门者的完整加载项示例工程&#xff0c;核心解决 Word 文档中表格序号自动插入与填充的问题。开发者可以从 ThisAddIn 类初始化、文档打开事件监听、表格逐行遍历等关键代码中&#xff0c;学会通…

作者头像 李华