news 2026/9/24 18:58:48

YOLO目标检测实战:NWPU VHR-10卫星图像数据集整理与训练指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLO目标检测实战:NWPU VHR-10卫星图像数据集整理与训练指南

简介:面向目标检测方向的学生与算法工程师,这份卫星图像数据集拥有800张高分辨率的遥感影像及配套标注文件,涵盖飞机、船舶、储罐、棒球场、网球场、篮球场、田径场、港口、桥梁、车辆共10个类别,适合用于YOLO等模型的训练与效果验证,也可直接支撑课程设计、期末大作业和毕业设计等场景。资源包共2612个文件,以jpg原图、xml标注、txt标签为核心,还包含数据划分缓存与说明文档,整体大小61.15MB,目录结构清晰、标注格式规范,便于接入常见检测流程。目前已有321人浏览学习。相比从零开始采集和标注,这份数据能显著节省时间成本,尤其适合需要快速产出实验结果的初学者或需要标准数据集验证算法的研究者;配合作者在大厂多年的算法工程经验,资料实用性和可靠性都有保障。

1. YOLO 目标检测 + 卫星图像数据集:NWPU VHR-10 这 800 张已标注图为什么值得落到本地

遥感图像的目标检测比自然场景更考验数据:目标小、背景乱、类别之间尺度差异大,很多时候模型精度上不去不是网络不够深,而是数据集本身没有对齐。NWPU VHR-10 是遥感领域最常用的公开数据集之一,800 张高分辨率卫星图像全部手动标注,覆盖飞机、轮船、储罐、棒球场、网球场、篮球场、地面跑道、港口、桥梁、车辆十类目标。这份 rar 资源把图像和已经标注好的文件打包在一起,解压后理论上可以直接走 YOLO 训练流程,但因为里面混杂着 train.cache、test.cache 这类自动生成的缓存,以及 positive image set 这种原始标注目录,想真正跑通要先花十几分钟把文件结构理顺。对做课程设计、期末大作业或毕业设计的同学来说,这是性价比很高的数据起点;对刚接触小目标检测的工程师,也可以拿它做 baseline 验证。

2. 解压后先别急着训练:读懂 NWPU VHR-10 的文件结构和 cache 文件

2.1 压缩包内的文件构成与角色划分

解压这份 rar 之后,你看到的不是想象中整齐的 images/labels 两级目录,而是几个 .cache 文件、一个 positive image set 目录,以及零散的 .jpg 图像。这里先说结论:train.cache、test.cache、val.cache 是 YOLO 训练时自动生成的缓存文件,作用是把图像路径、尺寸、哈希值和标注文件的校验值记录下来,避免每次启动训练都重新扫描整个数据集。也就是说,它们在压缩包里反而说明有人用这份数据跑过一次 YOLO,但它们并不属于数据本体。

文件用途是否需要保留
train.cache / test.cache / val.cacheYOLO 数据集缓存可删除,训练时会重建
positive image set.cache3正样本子目录缓存可删除
positive image set原始图像与标注目录保留,数据本体
084.jpg / 311.jpg 等正样本图像保留,用于整理

需要考虑的一件重要事情是:cache 文件与生成它的目录路径强绑定。如果你把 rar 解压到另一个路径,YOLO 检测到路径不一致就会自动重建缓存。这一步通常要花几秒钟到十几秒,不要误认为是程序卡死。我自己的习惯是拿到资源后先删除所有 .cache 文件,再重新整理目录,让 YOLO 从零扫描一次,避免读到无效路径后出现奇怪的报错。

positive image set 目录是 NWPU VHR-10 原始结构中的正样本区,里面每张 JPG 图像通常对应一个同名的 .txt 标注文件。负样本在不含目标的图像,也就是 negative image set 里。但这份 rar 里没有单独列出 negative 目录,所以先按正样本数据来处理,负样本可以在训练阶段用背景图补充,或者从原数据集补全。

2.2 原始标注 txt 的解析:类名带空格和坐标格式

NWPU VHR-10 的原始标注文件是纯文本格式,每行代表一个目标框,格式大致是:

airplane 420 180 560 235 storage tank 90 300 150 350 ship 620 410 700 470

每一行第一个字段是类别名称,后面四个数字分别是左上角 x、左上角 y、右下角 x、右下角 y 的像素坐标。这个格式有几个坑值得提前说明。

第一个坑是类别名里有空格。storage tank 是两个单词,如果你用 Python 的line.split(" ")直接切,会得到五个字段,类别名被拆成 storage 和 tank 两段,坐标全部错位。正确做法是先切出前两个字段作为“可能带空格的类名”和第一个坐标,或者根据已知的类别列表做匹配。第二个坑是坐标是整数像素值,而且原始标注没有归一化,直接喂给 YOLO 会报标签格式非法的错误。第三个坑是不同版本的 NWPU VHR-10 标注坐标的参考系可能有差异,有的从 0 开始,有的从 1 开始,影响不大但转换时统一处理即可。

下面是一段读取原始标注并打印统计信息的代码,先确认数据能正确解析再动手转换:

import os from collections import defaultdict label_dir = "positive image set" cls_counter = defaultdict(int) with open(os.path.join(label_dir, "0001.txt"), "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line: continue tokens = line.split() if len(tokens) == 5 and tokens[0].isdigit() is False: # 已知类别名才进入统计,避免把坐标当类别 cls_name = " ".join(tokens[:2]) if tokens[0] == "storage" else tokens[0] x1, y1, x2, y2 = map(int, tokens[-4:]) cls_counter[cls_name] += 1 print(f"{cls_name}: ({x1}, {y1}) -> ({x2}, {y2})") else: print(f"[skip] 无法解析行: {line}") print("类别统计:", dict(cls_counter))

这段代码的核心逻辑是逐行读取标注文件,对每行做切分并判断字段数是否为 5,其中第一个字段是类名,后四个是坐标。代码里对 storage 这类多词类名做了特殊处理,避免坐标错位。输出类别统计能让你快速确认这份 rar 里的标注是否覆盖完整十类,如果某一类的计数为 0,说明要么是数据不完整,要么是解析逻辑还有问题。

2.3 目录重整:把散装 JPEG 整理成 YOLO 标准 images/labels 分支

YOLO 官方训练时对数据目录没有强制要求,但惯例是数据集根目录下分 images 和 labels 两个分支,各自再按 train、val、test 划分。图像的 jpg 文件和标注 txt 文件名一一对应,只是后缀不同。这个结构对后续写 data.yaml 特别友好,否则你需要在配置文件里写一长串路径,还容易出错。

整理脚本的思路是:遍历 positive image set 目录中的全部图像,复制到 dataset/images/train,同时把同名 txt 复制到 dataset/labels/train。如果你打算划分验证集,可以在复制前对文件名列表做一次随机打乱,按 8:1:1 或其他比例切片。这里给出一个只处理 train 部分的简化版本:

import os import shutil SRC_DIR = "positive image set" DST_IMG = "dataset/images/train" DST_LBL = "dataset/labels/train" os.makedirs(DST_IMG, exist_ok=True) os.makedirs(DST_LBL, exist_ok=True) for fname in sorted(os.listdir(SRC_DIR)): if not fname.lower().endswith(".jpg"): continue stem = os.path.splitext(fname)[0] img_src = os.path.join(SRC_DIR, fname) lbl_src = os.path.join(SRC_DIR, stem + ".txt") if not os.path.exists(lbl_src): print(f"[warning] {fname} 没有对应标注文件") continue shutil.copy(img_src, os.path.join(DST_IMG, fname)) shutil.copy(lbl_src, os.path.join(DST_LBL, stem + ".txt")) print("整理完成,图像数:", len(os.listdir(DST_IMG))) print("标注数:", len(os.listdir(DST_LBL)))

这段脚本先遍历源目录里的 JPG 文件,通过文件名 stem 去配对同名 txt,如果图像没有标注文件就跳过并打印警告,避免把无标签的图混进训练集导致 YOLO 训练中断。复制完成后打印两个目录的文件数,检查数量是否一致,这是最直接的完整性校验手段。

目录重整这一环节容易遇到的问题是:原始数据里可能存在一些非 JPG 格式的图像,比如 PNG 或 TIFF,YOLO 本身支持这些格式,但脚本里如果只写了.jpg会漏掉。我一般会把后缀判断改成一个集合,比如{".jpg", ".jpeg", ".png", ".bmp", ".tif"},这样能覆盖遥感数据里的常见格式。另一个问题是文件名中有空格或中文,虽然 YOLO 能处理,但在 Linux 服务器上容易出现转义问题,建议顺手重命名为纯数字或纯英文文件名。

import re def safe_name(fname): stem, ext = os.path.splitext(fname) stem = re.sub(r"[^0-9a-zA-Z]", "_", stem) return stem + ext.lower()

用这个函数在复制时重命名,能省掉后续大量路径引用的麻烦。整理完目录之后,下一步就是标注格式转换,这是整份资源能不能直接训练的关键。

3. 标注格式转换:从 NWPU 到 YOLO 的坐标归一化与类别映射

3.1 两种格式的核心差异与转换思路

NWPU VHR-10 的标注是绝对像素坐标,单位是像素,表达的是“框的左上角”和“框的右下角”,而 YOLO 使用的标签格式是归一化的中心坐标加宽高,即class_id cx cy w h,其中 cx、cy 是目标框中心点相对于图像宽高的比例,w、h 是框的宽高占比,取值范围都在 0 到 1 之间。这个差异决定了你不可能把原始 txt 直接复制到 labels 目录里完事,必须做一次换算。

换算公式很简单。假设图像宽度为 W,高度为 H,原始标注为 x1、y1、x2、y2,那么:

box_w = (x2 - x1) / W box_h = (y2 - y1) / H box_cx = (x1 + x2) / 2 / W box_cy = (y1 + y2) / 2 / H

这两个公式里要特别注意的就是除以图像宽高这一步,很多新手漏掉归一化,生成的标签里出现大于 1 的数值,YOLO 在训练时会直接过滤掉这些目标框,导致模型什么都没学到,但训练日志看起来一切正常。

类别映射同样关键。YOLO 的类别是从 0 开始的整数,而 NWPU 原始标注里是字符串。你需要建立一个固定的映射表,例如把 airplane 映射为 0、ship 映射为 1,依此类推,并且这个顺序必须与 data.yaml 里的 names 列表完全一致。否则会出现标注文件里是飞机,训练时模型按轮船去学的情况,这种错位在训练日志里根本看不出来,只有最后评估时才能发现。

3.2 转换脚本:读 txt、归一化并写出 labels

下面是一段完整的转换脚本,处理的是整理后放在 train 目录中的原始标注:

import os category_map = { "airplane": 0, "ship": 1, "storage tank": 2, "baseball diamond": 3, "tennis court": 4, "basketball court": 5, "ground track field": 6, "harbor": 7, "bridge": 8, "vehicle": 9, } def convert_label(txt_path, out_path, img_w, img_h): with open(txt_path, "r", encoding="utf-8") as f_in, \ open(out_path, "w", encoding="utf-8") as f_out: for line in f_in: line = line.strip() if not line: continue tokens = line.split() # 处理带空格的类别名 if tokens[0] == "storage" and len(tokens) >= 6: cls_name = "storage tank" x1, y1, x2, y2 = map(float, tokens[1:5]) elif len(tokens) >= 5: cls_name = tokens[0] x1, y1, x2, y2 = map(float, tokens[1:5]) else: continue if cls_name not in category_map: print(f"[skip] 未知类别 {cls_name} in {txt_path}") continue box_w = (x2 - x1) / img_w box_h = (y2 - y1) / img_h box_cx = (x1 + x2) / 2.0 / img_w box_cy = (y1 + y2) / 2.0 / img_h # 越界检查:YOLO 对超出 [0,1] 的框会直接忽略 box_cx = min(max(box_cx, 0.0), 1.0) box_cy = min(max(box_cy, 0.0), 1.0) box_w = min(max(box_w, 0.0), 1.0) box_h = min(max(box_h, 0.0), 1.0) cls_id = category_map[cls_name] f_out.write(f"{cls_id} {box_cx:.6f} {box_cy:.6f} {box_w:.6f} {box_h:.6f}\n") print(f"转换完成: {txt_path} -> {out_path}")

这段脚本先按行读取原始标注,对 storage tank 这种多词类名做单独判断,再按公式计算归一化坐标。写文件时保留 6 位小数,既保证精度又能让文件体积可控。越界检查的目的有两个:一是防止标注框超出图像边界导致 YOLO 报警,二是如果原始标注坐标本身有错误,这里的截断至少不会让整个训练崩溃。实际转换时,img_w 和 img_h 需要从图像文件读取,推荐用 OpenCV 或 PIL,不要直接从文件名推断尺寸。

3.3 转换后的自检:画框验证与三类常见错误

转换脚本跑完不等于数据没有问题,这一步最容易被跳过,也是很多人训练出来模型完全不收敛的真正原因。自检方法很直接:把转换后的 YOLO 标签画回图像上,人工看一眼框的位置是否合理。脚本如下:

import cv2 import numpy as np def draw_yolo_boxes(img_path, label_path, class_names): img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path, "r") as f: for line in f: parts = line.strip().split() if len(parts) != 5: continue cls_id, cx, cy, bw, bh = map(float, parts) x1 = int((cx - bw / 2) * w) y1 = int((cy - bh / 2) * h) x2 = int((cx + bw / 2) * w) y2 = int((cy + bh / 2) * h) color = (0, 255, 0) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) cv2.putText(img, class_names[int(cls_id)], (x1, max(0, y1 - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1) cv2.imwrite("check.jpg", img) print(f"画框完成: {img_path} -> check.jpg")

画框验证时重点看三类问题。第一类是框整体偏离目标,通常是归一化公式写错,比如把 x1、y1 直接当中心点用了。第二类是框宽高为负,说明 x1 大于 x2 或 y1 大于 y2,原始标注里框的顶点顺序可能不是标准的左上右下,需要做一次排序纠正。第三类是多个框重叠在一起,大概率是同名 txt 里出现了重复行,需要做去重处理。

这三类错误如果靠肉眼逐张检查 800 张图不现实,我的建议是随机抽 30 到 50 张画框查看,只要这批没有问题,大概率整体没有系统性错误。

4. 训练配置:data.yaml 的写法、命令行参数调整与小目标优化

4.1 data.yaml 的最小完整配置

数据准备好之后,第一个要写的是数据集配置文件。YOLO 系列从 v5 到 v8 都支持通过 YAML 文件描述数据集位置和类别信息。一个最小可用的 data.yaml 如下:

path: ./dataset train: images/train val: images/val test: images/test nc: 10 names: 0: airplane 1: ship 2: storage tank 3: baseball diamond 4: tennis court 5: basketball court 6: ground track field 7: harbor 8: bridge 9: vehicle

path 字段写数据集根目录的路径,可以是相对路径也可以是绝对路径。train、val、test 分别是指向图像目录的相对路径。nc 是类别总数,必须与 names 列表长度一致。这里最隐蔽的坑是 names 索引顺序:它必须严格对应转换时用的 category_map。如果你在转换时把 airplane 设为 0,但在 data.yaml 里把 ship 放在第 0 位,模型学到的输出顺序就会与真实类别错位,最终评估时混淆矩阵会乱成一团。

另一个容易忽略的点是 path 字段的使用。如果你的训练命令在子目录下执行,建议 path 写成相对当前工作目录的路径,或者在命令行直接传data=/绝对路径/data.yaml。我看到不少人在服务器上把 home 目录下的数据集配置写到 container 里,路径没有同步映射,训练一开始就报找不到图片。用绝对路径能减少这类问题,代价是换机器后要改配置。我习惯写相对路径,配合一个软链接或环境变量指向实际数据位置,这样代码和配置都能保持可迁移。

4.2 训练命令参数逐个拆解

以 YOLOv5 为例,训练命令一般长这样:

python train.py \ --data data/nwpu_vhr10.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --cache ram \ --workers 8 \ --project runs/nwpu \ --name experiment_01

这里每个参数都有讲究。--img 640是输入图像尺寸,训练时会先把原图等比缩放再 pad 成 640×640。卫星图像的分辨率一般远高于这个值,比如 1024×1024 甚至更高,直接缩到 640 会把小目标缩没,这是遥感目标检测里最典型的精度杀手。--batch 16是批大小,直接受显存制约,如果你的卡只有 8G,从 8 起步比较稳。--cache ram表示把图像加载到内存加速训练,但 800 张图大约占几个 GB 内存,内存紧张时可以去掉这个参数。

--weights yolov5s.pt是预训练权重,s 代表 small 版本。这里有一个常见误区:用 COCO 预训练权重做迁移学习时,如果新数据集的类别数和 COCO 的 80 类完全不同,模型最后一层输出会被自动重置,这是 YOLO 源码内部处理的,不需要手动修改权重文件。你真正要关心的是骨干网络的参数是否适合小目标,如果有资源,用yolov5myolov5l往往比 s 效果好。

训练日志里最值得看的两行是all 320前的 mAP 值,以及分类损失和回归损失曲线的下降趋势。如果 loss 在前 20 个 epoch 没有明显下降,先怀疑数据问题而不是网络结构,第一步检查标注是否为空、类别是否倾斜,第二步检查学习率,第三步再考虑换模型。

4.3 小目标场景的 img_size 与 tile 策略

针对 NWPU VHR-10 这种以飞机、车辆为主的小目标数据集,直接设--img 640会损失大量细节。常见做法是两个方向:一是提高--img到 1280 或更高,配合较大的 batch 撑住显存;二是把原图切割成若干小块再训练,即 tile 策略。

提高输入尺寸最直接,显存足够时收益明显,但推理速度会下降。以 YOLOv5 为例,训练时设--img 1280,推理时保持同样尺寸,mAP 通常能比 640 高出 3 到 8 个百分点,代价是单张推理时间翻倍。如果你的显卡是 3090 或以上,优先用这个方案。

python train.py \ --data data/nwpu_vhr10.yaml \ --weights yolov5m.pt \ --img 1280 \ --batch 8 \ --epochs 150 \ --cache ram \ --rect

--rect是一个容易被忽视的参数,它让 YOLO 在训练时把长宽比相近的图像打包进同一个 batch,减少 padding 带来的计算浪费,对小数据集训练更友好。如果你的数据集里图像尺寸差异很大,这个参数能让训练显存占用降低不少,同时不损失精度。

tile 策略实现上是在数据预处理阶段把大图按 512×512 或 640×640 的 tile 切成小块,保留原来的标注坐标,只做裁切不缩放。切分时注意目标是否落在 tile 边界被切开,常见做法是允许 10% 的宽高重叠。这个方案对小目标特别有效,相当于让模型在原始分辨率下看到目标,而不是把目标缩成几个像素。

5. 避坑排查:cache 失效、类别错位、显存溢出与背景误检

5.1 cache 文件路径失效导致反复重建

现象:训练启动时每次都显示Scanning dataset...,耗时十几秒甚至更久,数据集只有 800 张图却像卡住一样。第二次训练时又重复同样的扫描过程。

原因:train.cache 文件记录的是之前生成它的绝对路径。数据集移动过目录后,缓存里的路径全部失效,YOLO 确认失效后删除缓存并重新生成。每次启动都重建的最常见原因是数据集路径没有固定,或者是多个训练脚本在不同工作目录下执行。

解决:拿到资源后直接删除所有 .cache 文件,并把数据集固定在一个目录下。启动训练时使用相同的相对路径或绝对路径,缓存生成后第二次启动就会秒过。如果数据集目录本身被挂载在多个位置,训练时只走其中一个路径,避免反复切换。

5.2 类别 id 错位导致训练不收敛

现象:训练 loss 下降但 mAP 始终在 0.1 到 0.2 之间徘徊,画出预测框发现框的位置基本正确但类别乱标,例如把飞机框标成轮船。

原因:转换脚本里的 category_map 与 data.yaml 的 names 顺序不一致。比如转换时把 airplane 映射为 0,但 data.yaml 里第 0 位写的 ship,模型学会的输出与正确类别完全错位。这类错误不会报错,训练日志里 loss 照常下降,但验证集评估时精度极差。

解决:写一个校验脚本,随机取 10 张训练图,把 YOLO label 的第一列数字还原成类别名,与原图人工比对。如果对不上,先统一 category_map 和 names 的顺序,重新转换标注。另外可以在 data.yaml 里加注释,把每个 id 对应的类别名写清楚,避免下次改配置时搞混。

5.3 显存溢出

现象:训练开始后报CUDA out of memory,或者跑几十个 batch 后 OOM 崩溃。这类问题在设置--img 1280后尤其常见。

原因:batch 太大和输入分辨率太高共同造成显存峰值超限。YOLO 的显存占用随输入尺寸呈平方增长,从 640 升到 1280 时显存需求大约翻四倍。设置--cache ram后图像缓存在内存中,不会直接影响显存,但 dataloader 的缓存队列会额外占一部分内存,间接推高整体资源压力。

解决:先降 batch,从 16 降到 8 或 4,观察有没有改善。如果还不够,把 img 从 1280 降到 1024。另一个实用技巧是启用--noval参数,在训练阶段跳过验证集的推理,省下不少显存,等训练结束再单独做一次评估。多卡用户要注意 batch 参数是单个 GPU 的 batch,总 batch 等于 batch 乘卡数,不要以为设了 16 就是每张卡 16。

5.4 负样本缺失导致背景误检

现象:训练完的模型在纯背景区域乱框,比如大面积农田或裸地也被识别成储罐或车辆,误检率奇高。NWPU VHR-10 原始数据里有一部分负样本图,即完全不含目标的背景图,但如果你的 rar 解压后没有这些负样本,模型实际上只在正样本里见过目标和背景的搭配,从未见过完全无目标的场景。

原因:正样本图里目标周围的背景往往和该类别强相关,比如飞机在停机坪、船在水面。模型学到的是“停机坪纹理 → 飞机”这种相关性,而不是飞机本体的特征。测试时遇到类似纹理就会误触发。

解决:从其他遥感数据集里收集负样本,或者手动截取一批不含任何目标的背景图,放在训练集和验证集中。最简单的方式是用 YOLO 自带的背景图目录,labels 目录里放空 txt 文件即可。建议负样本比例控制在正样本的 10% 到 20%,加得太多会让模型对真正目标也变得保守,降低召回率。

5.5 标签框越界与坐标归一化异常

现象:训练日志里出现大量WARNING: ignoring corrupt label或者某个类别的目标数量明显少于标注数量。

原因:原始标注的坐标完全等于图像边界,归一化后可能出现 w 或 h 为 0 的情况;或者标注框的坐标超出了图像宽高,YOLO 直接丢弃该框。另一个常见情况是转换时没有正确读取图像尺寸,拿到的 W 和 H 与实际不符,导致所有坐标整体偏移。

解决:在转换脚本里加上坐标合法性检查,处理 x1 >= x2、y1 >= y2、cx 或 cy 超出 [0,1] 的情况。同时建议统计每个 txt 中的目标框数量,和原图尺寸做交叉验证。如果发现某张图的目标数明显异常,单独拿出来检查。

6. 训练完之后的一个习惯:用混淆矩阵反推数据集的病灶

模型训练完,先别急着写报告或部署,第一件事是打开runs/nwpu/experiment_01/confusion_matrix.png看混淆矩阵。混淆矩阵能直接告诉你模型把哪些类别混在一起了,而这个问题往往不只是模型的问题,而是数据集本身存在标注质量或类别分布的问题。

例如飞机、车辆这两类如果频繁互混,很可能是标注框过小、目标像素太少,模型提取不到足够的特征,这时优先考虑提升输入分辨率或做 tile 裁剪。储罐和桥梁如果有交叉,则要考虑是否存在标注框重叠,比如桥梁跨越水面时把水面背景框进来,导致模型学会了水面纹理而不是桥梁特征。混淆矩阵里如果某个类别的整行几乎全是背景,说明该类别的样本量太少,或者负样本太多把真阳性压下去了,需要回看训练集里该类别的目标框数量。

第二个习惯是训练完成后随机挑 100 张验证集图像,保存模型的预测结果,人工逐张看预测框和真实框的差异焦点在哪里。重点不是框得准不准,而是模型的错误模式是漏检多还是误检多。漏检集中在特定类别,就去补该类别的样本或提高分辨率;误检集中在背景区域,就去加负样本或提高置信度阈值。

我自己的固定做法是调参后重新训练时,把训练曲线里的 mAP 变化和混淆矩阵截图存档,方便和上一版对比。这个习惯帮我避免了很多次“以为改了有效、实际越改越差”的情况。有一点永远值得反复确认:数据集的干净程度直接决定 YOLO 训练的置信度,与其花几天调模型结构,不如花两小时彻底检查一遍标注质量。希望这份 NWPU VHR-10 的整理和训练思路能帮到你,少走一些我走过的弯路。

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

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

SpringBoot给Swagger文档页加登录保护的轻量实现方案

接手过一个项目,一打开浏览器访问http://localhost:8080/swagger-ui.html,整个后端的接口文档直接裸奔在公网环境里。当时那份项目里连个最简单的登录校验都没有,Swagger 页面就这么大摇大摆地暴露了所有 Controller 的入参、出参和内部接口路…

作者头像 李华
网站建设 2026/9/24 18:58:28

手机靓号到底值不值钱?从结构估值到避坑实操全解析

前天帮一个搞招商的朋友挑了组尾号,他拿到手第一句话是:“这号是不是太炸眼了?”我说你搞连锁加盟的,电话一天几十通,客户记不住号码,你前面全白干。这年头流量贵、信任难建,一个让人一眼记住、…

作者头像 李华
网站建设 2026/9/24 18:57:51

CCleaner免安装版实用指南:系统清理与优化全解析

CCleaner这个工具,老玩家应该都不陌生,从XP时代一路火到Win11,系统清理界的“瑞士军刀”名号不是白叫的。而“免安装版”,也就是Portable便携版,更是很多老鸟装机U盘里常备的那一个。不写注册表、不留后台服务、插上U盘…

作者头像 李华
网站建设 2026/9/24 18:57:33

基于贝叶斯的电力系统故障诊断:从朴素贝叶斯到动态贝叶斯网络

简介:这份资源面向电力系统故障诊断方向的研究者、工程师与高年级学生,围绕贝叶斯方法在故障识别与定位中的应用展开,帮助读者理解如何借助概率推理处理电力系统中常见的不完全或含噪数据。压缩包共32个文件,约223KB,以…

作者头像 李华
网站建设 2026/9/24 18:57:24

手机CMOS传感器真伪识别与性能速查指南

1. 这份“百款手机CMOS速查”到底是什么,为什么值得你花时间细看?我干手机影像评测和硬件拆解这行十多年,每年至少拆过200台主流机型,光是整理传感器型号的Excel表格就攒了17个版本。很多人以为手机拍照好坏只看像素、看品牌logo&…

作者头像 李华
网站建设 2026/9/24 18:57:24

SpringBoot+Vue高校实习管理系统源码解析与毕业设计实战指南

期末季一到,技术社区里总能看到同一种求助帖:“有没有适合做毕设的Java项目”“SpringBootVue源码求推荐”“实习管理系统的数据库表怎么设计的”。问的人多了,我发现很多同学其实已经找到了一份类似的高校实习管理系统源码,但卡在…

作者头像 李华