热红外无人机数据集+YOLO训练全流程实战指南
2026/9/23 12:36:02 网站建设 项目流程

简介:面向YOLO系列目标检测训练与验证场景,提供一套热红外无人机图像数据集,包含三百六十张已标注图像,可直接用于YOLOv5、YOLOv7、YOLOv8、YOLOv9、YOLOv10、YOLO11等常用算法版本。压缩包内共有一千零八十一个文件,其中包含三百六十张JPG原图、三百六十个YOLO格式TXT标签、三百六十个VOC格式XML标签以及一个data.yaml配置文件,压缩包大小约六点七二兆字节,轻量易用。数据已经预先完成划分,配合配置文件可免去手动整理标注的步骤;TXT与XML两种标签格式分目录存放,方便不同框架或算法切换使用,也便于对比验证。目前已有八十人浏览学习,适合目标检测入门者、无人机视觉研究者以及需要快速验证YOLO系列算法效果的开发者,可直接投入模型训练、指标评估和结果测试,节省从零标注与预处理的时间。

1. 拿到这个360张的热红外无人机数据集,先别急着跑训练

拿到一个名为yolo算法-热红外无人机数据集-360张图像带标签的zip包,第一反应通常是两件事:360张热红外图能训练出一个能用的检测模型吗?打包好的标签到底是不是标准的YOLO格式?我的看法是,360张对一个有经验的人来说足够启动一个项目,对新手则很容易在训练时翻车。热红外图像和普通可见光照片不一样,小目标、低对比度、位深都是常见的坑;但反过来,无人机热红外场景目标类型固定、场景单一,反而比泛化的目标检测更容易收敛。这篇笔记是给两类读者准备的:正准备用无人机热红外数据做检测的工程师,以及一切准备用YOLO训练自采数据集的人。

2. 拆开zip先做三件事:校验完整性、看标签格式、确认图像位深

数据集买到手,第一件要做的事不是解压后立刻训练,而是花十分钟检查三样东西:压缩包本身有没有损坏,标签文件是不是规范的YOLO格式,图像数据是不是YOLO能直接吃的格式。这三项检查能省掉后面训练时一大半的玄学问题。

2.1 用 unzip 与 7-Zip 打开压缩包:先测试再解压

Linux 下我一般会用下面这条命令测试压缩包完整性,测试通过后再真正解压。这个习惯是从一次 2GB 数据集解压到一半报错养成的,那次教训很直接:不校验就解压,解压出来的文件缺了大半,训练时各种 key error。

unzip -t thermal_dataset.zip

这条命令只做测试,不实际解压。输出末尾出现No errors detected in compressed data就说明压缩结构完好。如果下载文件本身不完整,这里会直接报unexpected end of filecannot find zipfile directory

确认完整后,再正式解压。Linux 下如果解压出来中文文件名乱码,通常是压缩包在 Windows 下用 GBK 编码创建、而系统默认 UTF-8 解码导致的,加-O参数指定编码即可解决:

unzip thermal_dataset.zip -d ./thermal unzip -O CP936 thermal_dataset.zip -d ./thermal # 文件名乱码时用

Windows 下我推荐用 7-Zip 而不是系统自带的资源管理器解压。右键压缩包选择“打开方式 -> 7-Zip File Manager”,先点“测试”按钮,绿色提示说明压缩包没问题。7-Zip 对 zip64 格式和大目录的兼容性比系统自带解压工具好,碰到解压途中报错的情况也更容易定位是哪个文件坏了。

提示:解压后立即检查解压目录,看图片数量和标签文件数量是否和压缩包内一致。这类数据集经常出现“图像 360 张、标签 359 个”之类的少文件情况,后面训练时就会有多张图找不到标签文件的错误。

2.2 标签文件是不是 YOLO 格式:一行 5 个数怎么看

YOLO 标签的标准格式是每个 txt 文件对应一张图片,txt 中每行代表一个目标,格式固定为类别ID x_center y_center width height,后四个值全部归一化到 0 到 1 之间。labelimg 标注时选 YOLO 格式,保存的就是这种 txt 文件。

我的习惯是先不急着看全部标签,而是抽一张图和一个标签文件,写脚本叠加画框。这样一眼就能看出标签和图像是否对得上,类别 ID 和实际目标是否匹配。下面这个脚本很基础,但每次拿到新数据集我都会先跑一遍:

import os from PIL import Image, ImageDraw def verify_label(img_path, label_path, output_path='verify.jpg'): img = Image.open(img_path) draw = ImageDraw.Draw(img) with open(label_path, 'r', encoding='utf-8') as f: for line in f: parts = line.strip().split() if len(parts) != 5: print(f"格式错误: {label_path} 中异常行: {line}") continue cls, xc, yc, bw, bh = parts cls, xc, yc, bw, bh = int(cls), float(xc), float(yc), float(bw), float(bh) # 检查坐标是否越界 if not (0 <= xc <= 1 and 0 <= yc <= 1 and 0 < bw <= 1 and 0 < bh <= 1): print(f"越界框: {label_path} 行: {line}") continue # 归一化坐标换算成像素坐标 x1 = (xc - bw / 2) * img.width y1 = (yc - bh / 2) * img.height x2 = (xc + bw / 2) * img.width y2 = (yc + bh / 2) * img.height draw.rectangle([x1, y1, x2, y2], outline='red', width=2) draw.text((x1, y1 - 10), str(cls), fill='red') img.save(output_path) # 使用示例 verify_label('images/IR_001.png', 'labels/IR_001.txt', 'check_001.jpg')

这个脚本的逻辑核心是:读 txt 每一行,把归一化坐标乘上图像宽高还原成像素坐标,再画矩形框。输出图里每个框上会标类别 ID,人工扫一眼就能发现很多问题,比如类别 ID 标反、框画到图外、目标中心点偏移。width=2 是矩形边框宽度,在小目标上 width 太大会直接把目标盖住,影响肉眼判断。

如果标签是 VOC 的 xml 格式,不能直接用于 YOLO 训练,常见的做法是写一个转换脚本,把xmin ymin xmax ymax四角坐标换算成x_center y_center width height的归一化格式,同时保持类别 ID 的映射一致。这一步没什么高深的逻辑,但很容易出错,转换后再跑上面的可视化验证脚本,比直接丢进训练器可靠得多。

2.3 热红外图像的常见坑:灰度图、伪彩色与 16 位数据

热红外图像和普通单反照片最大的差别在存储格式。很多热像仪 SDK 导出的是 16 位 PNG,用普通图片查看器打开会看到一团黑,这是正常的,因为 16 位数据的动态范围和 8 位显示不匹配。训练 YOLO 前必须先确认图像的位深和通道数,否则后面的数据增强和归一化都可能出问题。

常见的三种热红外图像格式:

格式特征训练前处理
8 位灰度 PNG/JPG单通道,范围 0-255可直接使用
16 位 PNG单通道,范围可能到 65535需要归一化到 8 位
伪彩色 BMP/PNG三通道,颜色代表温度谨慎转灰度,可能丢温差信息

我自己处理 16 位热红外图的做法是先用 Python 读一下图像 mode,再做一个最小最大归一化,把动态范围拉伸到 0 到 255:

import numpy as np from PIL import Image import os os.makedirs('images_8bit', exist_ok=True) for f in os.listdir('images'): if not f.lower().endswith(('.png', '.bmp')): continue img = Image.open(os.path.join('images', f)) if img.mode in ('I;16', 'I;16L', 'I;16B'): arr = np.array(img, dtype=np.float32) # 最小最大归一化,把16位热红外动态范围压到0-255 arr = (arr - arr.min()) / (arr.max() - arr.min() + 1e-6) * 255 arr = arr.astype(np.uint8) im = Image.fromarray(arr) else: im = img.convert('RGB') im.save(os.path.join('images_8bit', f))

这段代码的作用是扫描 images 目录,把 16 位热红外图转成 8 位,其他格式直接转 RGB 保存。+1e-6是防止整张图像素值完全相同(比如全黑的全温区图)时出现除零。注意:这里的归一化是全局拉伸,如果一张图里同时包含高温目标和低温背景,对比度会被拉开得很明显,但如果是整段视频逐帧处理,每帧独立归一化会导致帧间亮度闪烁,后续做视频检测时需要考虑。

伪彩色图我一般建议直接保留三通道用于训练,不转灰度。热红外伪彩色的编码方式五花八门,铁红、彩虹、灰度各有各的映射,转成灰度会丢掉温度层次差异,尤其是“同温度目标在伪彩色里同色、在灰度里也同色”的这种信息损失,对检测不利。

3. 从环境到权重:用这套数据集训练 YOLOv5/YOLOv8

检查完数据,接下来就是训练流程了。这里我同时给出 YOLOv5 和 YOLOv8 两套操作,因为目前用这两套的人最多,而且它们对这类小数据集的适配都比较成熟。安装方式、数据划分、训练参数分别讲清楚。

3.1 Anaconda 建环境与依赖安装

YOLO 训练对 Python 和 PyTorch 版本有要求,直接用系统 Python 装容易把环境搞乱。我一般用 Anaconda 单独建一个环境,互不干扰。

conda create -n yolo python=3.10 -y conda activate yolo pip install ultralytics

这样装的是 YOLOv8 的环境,安装完成后会得到yolo命令行工具,训练、验证、预测全部由它统一管理。如果你更习惯 YOLOv5 的代码组织方式,也可以单独克隆官方仓库,再按仓库内 requirements.txt 安装依赖。YOLOv8 对新手更友好,YOLOv5 对想要逐行改代码的人更直观。我的习惯是:先跑通一个模型用 YOLOv8,确认思路没问题再回头用 YOLOv5 做对照实验。

安装好之后先用python -c "import torch; print(torch.cuda.is_available())"确认 GPU 是否可用。输出True才代表 CUDA 环境正常,False就是 CPU 训练,360 张图,CPU 训练也能跑,但速度会慢很多。

3.2 划分训练集和验证集:数据量小就必须分层抽样

360 张图不算多,划分方式直接影响验证结果的可信度。简单随机切一刀很容易出现某类目标在验证集里一个都没有的情况,所以我一般用 sklearn 的train_test_split做分层抽样,按标签里第一个目标的类别作为分层的依据。

import os from sklearn.model_selection import train_test_split images_dir = 'images' labels_dir = 'labels' imgs = [f for f in os.listdir(images_dir) if f.lower().endswith(('.jpg', '.png', '.bmp'))] imgs.sort() # 读取每张图对应标签的第一个目标类别,作为分层依据 classes = [] for im in imgs: stem = os.path.splitext(im)[0] txt = os.path.join(labels_dir, stem + '.txt') with open(txt) as f: lines = [line.strip() for line in f if line.strip()] if lines: classes.append(lines[0].split()[0]) else: classes.append('-1') # 空标签图单独归一类 train_imgs, val_imgs = train_test_split( imgs, test_size=0.2, random_state=42, stratify=classes ) with open('train.txt', 'w') as f: for im in train_imgs: f.write(os.path.join(os.getcwd(), images_dir, im) + '\n') with open('val.txt', 'w') as f: for im in val_imgs: f.write(os.path.join(os.getcwd(), images_dir, im) + '\n') print(f"train: {len(train_imgs)}, val: {len(val_imgs)}")

这段代码的关键点有两个。第一,stratify=classes让验证集的类别比例和整个数据集一致,避免小类别在验证集里被抽空。第二,random_state=42固定随机种子,保证每次运行划分结果一致,实验结果可复现。test_size=0.2意味着 360 张图里有 288 张训练、72 张验证。

一个容易被忽略的坑:无人机航拍数据天然具有航带相关性,同一条航线上相邻帧几乎一模一样。如果这些高度相似的图被同时分进训练集和验证集,验证指标会虚高。我建议划分前先把图像按采集时间或航线编号排好序,用分组的方式切分,而不是纯随机切。

3.3 编写 data.yaml 并启动训练

YOLO 训练需要一个 yaml 文件描述数据位置和类别信息。文件结构如下:

path: /home/user/thermal_data train: train.txt val: val.txt nc: 2 names: 0: person 1: vehicle

path是数据集根目录的绝对路径,YOLOv8 会把trainval字段作为相对路径拼接上去。nc是类别总数,必须和names里的条目数一致,这个数字填错会直接导致训练报错或者 loss 异常。names的排列顺序和标签文件里第一个数字的 ID 必须一一对应。

然后启动训练。YOLOv8 的命令是:

yolo detect train \ data=thermal.yaml \ model=yolov8n.pt \ epochs=100 \ batch=16 \ imgsz=640 \ close_mosaic=10

如果用的是 YOLOv5,对应命令是:

python train.py \ --data thermal.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 100 \ --patience 30

这里几个参数值得单独说明。imgsz=640是对小目标检测的底线——热红外无人机图像里的人可能只有十几到几十个像素,输入尺寸再小的话,下采样过程中特征就丢了。close_mosaic=10是让模型在最后 10 个 epoch 关闭 mosaic 增强,让模型从“看拼图”平滑过渡到“看清原图分布”,这个细节能明显减少验证集和测试集效果不一致的问题。batch=16在 12G 显存上是稳妥的选择,显存更大可以提到 32。epochs=100对 360 张图偏多,配合patience=30早停,模型一般会在 40 到 60 轮之间收敛。

训练过程中日志输出的损失分为三类:box 回归损失、分类损失和 DFL 分布焦点损失。热红外场景里分类损失常常是降得最慢的一个,因为不同目标在热红外图像里都是“一团白热轮廓”,人、车、动物之间外观差异远没有可见光大。这是热红外数据本身的特性,不是代码写错了。

3.4 训练日志里真正要盯的几个数字

很多新手盯着 loss 一直看,其实对小数据集来说,loss 的绝对值没什么指导意义,更值得关注的是验证集上的 precision 和 recall,以及模型卡在哪个 epoch 停止提升。

输出字段含义观察建议
box_loss边界框回归损失持续下降就是正常的
cls_loss分类损失热红外场景可能偏高,正常
precision验证集查准率关注最终值,别盯每轮波动
recall验证集查全率漏检严重的场景优先提升
mAP50IoU=0.5 下的平均精度小数据集最重要的参考指标

我习惯在训练跑完后,看模型在哪一个 epoch 达到了 mAP50 的最高值。如果这个 epoch 靠后,说明模型是在充分学习;如果前 10 轮就到了峰值后面一直下跌,说明过拟合很严重,数据增强不够或训练轮数太多。

4. 热红外小数据集常见问题与排查:现象、原因、解法

训练热红外小数据集时最容易踩的坑,很多是数据集本身的“暗伤”,而不是模型结构问题。下面这四条是我在类似项目里遇到过的真实问题,按“现象 -> 原因 -> 解决”的顺序记录下来,你可以直接对照排查。

4.1 解压报错、zip 伪加密与“移除密码”的骗局

现象:解压到一半报unexpected end of file,或者 7-Zip 提示需要输入密码,但数据集来源明明没有提供密码。

原因分两种。第一种是下载文件不完整或传输丢包,zip 中央目录损坏。第二种是 zip 伪加密——文件的通用位标志里设置了加密位,但数据区实际上根本没有真正加密,常见于部分国产网盘压缩工具或打包脚本的 bug。伪加密的特征是工具提示要密码,但在 7-Zip 里能看到文件名列表,甚至双击某个文件能直接看到内容。

解决:先跑一遍unzip -t,确认压缩包结构是否完整;如果只是伪加密,在 7-Zip 里直接把内容拖出来即可,不需要密码。拖出来之后用 7-Zip 重新打包一次,去掉加密标志,再继续后续流程。需要提醒的是,如果压缩包是真加密(AES-256 或 ZipCrypto),那没有密码就无法解压,市面上所谓“密码移除”工具绝大多数只能处理上面这种伪加密情况,对真加密只能在字典攻击上碰运气。

注意:这里只讨论你对自己合法获得的数据文件做校验和修复。如果确实是发布方加密数据但没有提供密码,正确做法是联系发布方获取密码。

4.2 标签文件与图像不匹配导致的 loss 异常

现象:训练能启动,但 loss 在几十个 epoch 里纹丝不动,或者验证集指标极低。查看训练日志时还可能出现image X not foundkey error之类的警告。

原因:解压后发现有些图像没有对应标签文件,有些标签文件对应的图像不存在,或者标签文件中出现了越界的归一化坐标(比如 width 大于 1 的框)。这些脏数据不会让训练直接崩溃,但会持续给 loss 注入噪声。

解决:训练前先做一次文件名匹配检查,把缺失和多余的文件列出来:

import os imgs = set(os.path.splitext(f)[0] for f in os.listdir('images')) labels = set(os.path.splitext(f)[0] for f in os.listdir('labels')) print("缺标签的图像:", sorted(imgs - labels)) print("缺图像的标签:", sorted(labels - imgs))

运行后根据输出做两件事:缺标签的图像用 labelimg 补标注,或者直接移出训练目录;缺图像的标签直接删除。然后再检查标签文件里有没有坐标越界的框,用脚本过滤掉:

import os for f in os.listdir('labels'): if not f.endswith('.txt'): continue path = os.path.join('labels', f) with open(path) as fd: lines = fd.readlines() valid = [] for line in lines: parts = line.strip().split() if len(parts) != 5: continue try: cls, xc, yc, bw, bh = int(parts[0]), float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) except ValueError: continue if not (0 <= xc <= 1 and 0 <= yc <= 1 and 0 < bw <= 1 and 0 < bh <= 1): continue valid.append(f"{cls} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}") with open(path, 'w') as fd: fd.write('\n'.join(valid))

这个脚本会把每个标签文件重写一遍,只保留格式正确、坐标在合法范围内的框。注意这里把浮点数格式化成 6 位小数,精度足够且文件更紧凑。

4.3 热红外小目标漏检:目标只有十几个像素

现象:训练完的模型在验证图上,对 50 米外的行人、视野边缘的车辆大面积漏检,但近处的目标检得很好。可视化测试图片时,小目标区域完全没有框。

原因:热红外图像中远距离目标本身就只占几十个像素,YOLO 的下采样倍数比较大,特征图上的一个点对应原图的十几甚至几十个像素,小目标的空间信息在深层特征图里基本消失。这是目标检测的通病,热红外因为目标对比度低,表现得比可见光更明显。

解决:最直接的办法是把输入分辨率提上去。从imgsz=640提到imgsz=960甚至imgsz=1280,小目标的特征保留程度会有明显提升。代价是显存占用和训练时间上升。如果显存不够,可以采用切片推理的思路:推理时把大图切成四等分或九等分,分别送入模型,再把检测结果映射回原图坐标。这个思路比直接缩小输入图更可靠,也是当前无人机巡检场景里比较常用的推理策略。

4.4 验证指标好看、现场实测翻车:数据划分的假象

现象:训练结束,验证集 mAP50 到 0.8,模型看起来很好。结果带着无人机到现场飞一圈,检测结果惨不忍睹,漏检误检扎堆。

原因:训练集和验证集划分得太“随机”。无人机航拍是一条航线连续采集的,相邻帧之间重叠度高,随机划分后验证集里的图和训练集里的图高度相似,导致验证指标虚高,这个现象在学术上叫数据泄漏。飞机一换高度、换时间、换天气,模型的真实泛化能力立刻现出原形。

解决:划分数据集时必须按“采集单元”来分组。比如 360 张图来自 3 次飞行任务,那就按飞行任务把 6 组数据整体切分,保证同一次飞行的图像不会同时出现在训练集和验证集里。这样做会让验证指标稍微下降,但这才是真实水平。我在第 3 节划分代码里特意把random_state固定下来,就是为了在发现指标虚高时能回溯数据划分方式。

5. 模型验证与评估:不是 loss 降了就万事大吉

训练完只是第一步。对小数据集来说,模型的真实表现往往和训练日志显示的差距不小。这一节讲训练完成后怎么评估模型、怎么调置信度门限、怎么把模型部署到实际环境中去跑。

5.1 看准四个指标:precision、recall、mAP50、mAP50-95

训练结束后,YOLOv8 会在验证集上算出一组指标,输出在 runs/detect/train 目录下的 results.csv 里。我一般会打开这个文件,重点看最后一行高亮部分的四个数字,也就是严格按“航班划分”后的验证集指标。下表是各指标在小数据集上需要注意的事项:

指标含义这里的观察要点
mAP50IoU 阈值 0.5 下的平均精度均值小数据集的首选参考,0.5 左右通常就算可用
mAP50-95IoU 从 0.5 到 0.95 逐档计算再取平均数值一般比 mAP50 低很多,正常
precision预测的框里有多少是对的误检多是 precision 低,优先调置信度门限
recall真实目标里有多少被检出漏检多是 recall 低,优先提分辨率或增强

这四个指标里,mAP50-95 是最苛刻的,它要求框的位置非常准,对小目标尤其不友好。热红外小目标经常 mAP50 在 0.6 以上而 mAP50-95 只有 0.3 左右,这不代表模型不能用,只代表框不精准。真正决定模型能不能上线的是 precision 和 recall 的平衡,而这和业务场景直接相关:巡检漏了一个目标可能造成损失,误报顶多浪费人工确认时间。

5.2 调整置信度门限与 IOU 门限,适配无人机巡检场景

模型输出的每个框都带一个置信度,预测时默认的门限是conf=0.25。这个门限对于热红外小目标来说经常太高了。我在实际项目中一般会把置信度降下来测一轮,看看漏检和误报的分布再定门限。

# YOLOv8 预测 yolo predict model=runs/detect/train/weights/best.pt \ source=./test_imgs \ conf=0.15 \ iou=0.45 # YOLOv5 预测 python detect.py \ --weights runs/train/exp/weights/best.pt \ --source ./test_imgs \ --conf-thres 0.15 \ --iou-thres 0.45

conf=0.15表示置信度高于 0.15 才保留框。门限调低,召回率上升,但误报也会变多。热红外场景里树的轮廓、房顶铁皮、太阳反光都会在红外图像里形成高亮区域,低门限下很容易被误检成目标。如果单帧误报多,一个常见的应对是用连续帧投票去抖:同一目标在连续 5 帧里至少出现 3 次才输出报警,无人机巡检场景中这种后处理比单纯调门限更有效。

iou=0.45控制在重叠框的合并力度。默认 0.45 适用于大多数场景。如果图像中目标密集、互相遮挡,可以降低到 0.4 让更少的框被合并;如果目标是稀疏的大目标,可以提高到 0.6 来减少重复检测。参数本身不难理解,难的是调完参数后要回答一个业务问题:漏检和误报哪个代价更高。

5.3 把模型导出成 ONNX,在边缘设备上跑推理

训练验证完的模型最终要部署到无人机或地面边缘设备上。YOLO 模型在 PyTorch 环境里跑推理是很方便的,但实际部署时通常要转成中间格式再用推理引擎加速。最常见的格式是 ONNX:

yolo export model=runs/detect/train/weights/best.pt format=onnx imgsz=640

导出成功后,边缘设备上可以配合 TensorRT 或 OpenVINO 转换后运行。TensorRT 会把 ONNX 模型编译成针对特定 GPU 高度优化的 engine 文件,推理速度能比 PyTorch 快数倍。如果你部署的目标是无人机机载小盒子,一般还会用到 FP16 精度和动态 batch 优化,这一步能显著降低显存占用和延迟。导出的模型要和训练时一致的imgsz,否则输入尺寸不匹配会导致精度明显下降。

部署到边缘盒子之后,建议把测试图集也拷到盒子上跑一遍,和 PC 上的结果做对比。同一模型在不同推理引擎下输出略有差异,这是正常的浮点计算精度问题,但如果差异大,大概率是导出时的预处理和后处理配置不一致。

6. 把 360 张用出超过 1000 张的效果:增强与伪标签迭代

360 张图是固定的,但训练策略是灵活的。这一章讲两个在小数据集上效果最显著的操作:按热红外特性调整数据增强,以及用伪标签迭代扩充训练集。

6.1 增强参数:按热红外特性调整,而不是用默认值

YOLO 的数据增强默认是按可见光设计的,热红外图像只有灰度或伪彩色,很多增强策略需要调整。在 YOLOv8 中我通常这样配:

yolo detect train \ data=thermal.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ mosaic=1.0 \ mixup=0.2 \ hsv_h=0.0 \ hsv_s=0.0 \ hsv_v=0.4 \ flipud=0.5 \ fliplr=0.5

hsv_h=0.0hsv_s=0.0是关掉色调和饱和度扰动,因为灰度热红外图根本没有色彩信息,扰动只是白白增加计算量。hsv_v=0.4保留亮度扰动,热红外图像的亮度受发射率影响,同一个目标在不同角度下温度表现确实不同,适当的亮度扰动能提升鲁棒性。flipud=0.5是垂直翻转,无人机航拍图像里“颠倒”是真实的常见视角(飞机倾斜飞行时),这个增强对航拍数据的收益很直接。

6.2 伪标签迭代:用模型自己扩充训练集

训练完第一版模型后,我常用的操作是:用模型对无人机热红外视频抽帧做推理,把置信度高于 0.7 的预测框自动导出成伪标签,人工只检查这些高置信框,修正明显错框,再把修正后的数据并入训练集重新训练。这样迭代两轮,360 张图通常能扩充到 800 到 1200 张。

这个方法的原理是模型自己已经学到的特征可以做“半自动标注”,人工从“全部标注”降级为“只修正错误”,工作量直接减半。需要提醒的是,伪标签会放大模型的错误——模型误检的框会被当成正确标签进入下一轮训练,因此必须做人工质检,而且新增样本要尽量覆盖不同飞行高度、角度、时间段,否则模型在不同场景下的误检会被越扩越固化。

我最初做小数据集训练时,习惯把 epoch 拉到 300,结果验证集指标好看、现场测试翻车。后来排查发现,问题出在验证集没有按飞行任务划分、mosaic 增强在训练后期没有关闭。现在我的流程固定下来了:数据先校验,再按航班分组划分,训练时安排增强计划,评估时以严格划分的验证指标为准。伪标签迭代是当前阶段扩展热红外小数据集最实际的路径,但前提是每一轮新增的样本都要有人在看。希望帮到你。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询