去年接手虫媒监测AI项目时,我做的第一件事就是翻遍公开数据集,看有没有现成的“蚊子吸血行为”检测数据。结果很遗憾:既有数据集要么是物种分类图集,要么是实验室静态标本,没有一套专门针对吸血行为、带完整时空标注的视频帧数据。最后我们只能自己攒,也就是你看到的这套埃及伊蚊吸血行为检测数据集——7800张图像,YOLO格式标签,全部围绕“吸血行为”这个细分任务设计。
这套数据适合谁?如果你是做昆虫行为识别、蚊媒监测系统、或者单纯想在小目标检测方向磨模型,都值得参考。我下面不吹数据本身多厉害,而是把采集、标注、训练、踩坑的完整过程摊开讲,包括很多文档里根本不会写的细节。
1. 为什么盯着一只蚊子吸血:虫媒风险评价里的数据缺口
1.1 埃及伊蚊与“吸血行为”对传播指标的意义
埃及伊蚊(Aedes aegypti)是登革热、寨卡、黄热病等多种虫媒病毒的主要传播媒介。这类蚊子的特点是高度依赖城市环境,喜欢在室内小型积水容器里产卵,白天活动,雌蚊需要吸食血液才能完成卵的发育。这里有个关键点:只有“吸血”这个动作,才把蚊子和人直接连接起来。一只蚊子哪怕数量再多,如果不吸血,传播链就断了。
所以做虫媒监测时,我们真正关心的不是“这有一只蚊”,而是“这有一只正在吸血的蚊”。吸血行为检测输出的不是静态密度,而是传播风险的动态证据。给模型标注“吸血中”的边界,本质上是在教计算机识别疾病传播链条里最危险的那个环节。
1.2 传统监测手段为什么算不出“吸血率”
传统虫媒监测靠两类工具:诱蚊灯(CDC灯诱)和诱卵器(ovitrap)。诱蚊灯捕获的大多数是待产卵或空腹雌蚊,它提供的是“密度”数据;诱卵器提供的是“繁殖活动”数据。但这两个指标都不能回答同一个问题:在当地蚊虫种群中,实际尝试或完成吸血的个体占比有多少?这个占比在蚊媒传播动力学里是核心参数,传统方法得不到。
要想算出吸血率,常规做法是在人诱或动物诱条件下抓蚊子回来,解剖看胃血状态,工作量大,且人诱方法存在伦理风险。后来实验室改用人工膜喂血装置,把加热血液封在膜上模拟宿主皮肤,配上视频录像,数据采集问题解决了,但视频分析成了新瓶颈——几小时的视频不可能靠肉眼逐帧看。我们做这套数据集的直接动因,就是把“人工膜视频”变成“自动检测模型”的训练燃料。
2. 7800张图是怎么“养”出来的:人工膜装置、视频抽帧与场景约束
2.1 采集装置与拍摄环境:把吸血过程稳定在镜头里
我们用的是实验室标准的人工膜喂血装置:一个保温循环器把血液维持在37℃左右,血液装载在一个圆柱形容器中,底部用Parafilm膜封住,蚊子透过膜刺入取食。这个设计的妙处在于:它把宿主动物或人的因素完全剔掉,行为过程可控可重复,拍摄过程中不会有皮肤纹理、毛发等噪声干扰模型。
摄像头选的是普通工业USB相机,分辨率1920×1080,拍摄帧率25fps。俯拍为主,间或补几张侧拍,用来覆盖不同视角。补光用白色LED平板灯,角度大概45度,正面打光。这里有个实际经验:补光太强会导致蚊子和背景对比度极高,模型很容易学会“照亮度找蚊子”,换到暗环境就失效。我们后来刻意加入低照度、侧光阴影的样本,就是为了避免这个坑。
人工膜装置上蚊子吸血的完整过程通常在3到8分钟内结束,一只蚊从停落到饱血离开,全部视频大概需要录制几十个小时,才能筛出足够多的有效吸血片段,最终得到7800张图像。
2.2 视频抽帧与关键行为时刻:7800张并非随机截图
很多人以为视频数据集就是截图抽帧,其实没那么简单。如果均匀抽帧,你会发现大部分帧里根本没有蚊子在吸血窗口上。所以我们采用“事件驱动抽帧”——先人工浏览视频,标记出每个吸血事件的起点和终点,再在事件窗口内密集抽帧。
我建议你这么设计采样密度:
- 吸血事件前1分钟,以每秒1帧抽帧,捕获停落和探查行为;
- 吸血过程中,以每2秒1帧抽帧,捕获刺入和饱血阶段;
- 吸血事件结束后,继续抽20秒,捕获离开始行为。
最终7800张里,单只蚊的样本约占70%,两只及以上同框的样本占30%左右。同框样本对模型特别重要,因为真实场景里一个膜面上可能同时趴着五六只蚊子,模型必须学会区分不同个体的行为状态,而不是把一个密集区域糊成一个框。
2.3 数据划分与类别分布:训练集别只剩“清一色饱血蚊”
数据划分的时候,如果你只做随机打乱,会出现一个隐蔽问题:同一个吸血事件的相邻帧会同时进训练集和验证集,造成评估虚高。我们改成按“事件”划分,也就是同一段视频的事件ID全部进同一份集合,这样验证集才真正检验模型对没见过的吸血过程是否有效。
类别分布上也特意做了平衡。整个数据集中,“吸血中”(engorging/probing)样本大约4300张,“未吸血/停落/游离”样本大约3500张,不是1:1但有差距,训练时在loss里加了正样本权重。如果从头标注,建议更狠一点,把两类比例拉到接近1:1,能有效减少模型“偏爱多数类”的问题。
3. 标注规范的每一处细节:如何让YOLO学会“吸血中”与“未吸血”
3.1 行为类别的边界:探查、刺入、饱血如何二分类
这是整个数据集里争议最多的部分。昆虫行为学家看吸血过程,会细分为:寻找宿主、停落、探查(probing,口器试探性刺入)、吸血中(engorging,腹部膨胀)、饱血(fully engorged)、离开。但对YOLO目标检测来说,类别太细反而难学,尤其是探查和刺入在二维图像上区别极小。
我们最后采用二分类标签:
- biting:口器已与膜面接触,且持续停留超过一定时间,腹部开始膨胀或已明显膨胀;
- non-biting:飞行中、停落但未刺入、正在离开、膜面上静止未接触。
注意“持续停留”这个时间条件很重要,否则蚊子短暂碰一下膜面就被标成biting,模型会学到一堆误检。我用生活化类比说一下:这就像判断一个人是否真在喝水,得看他是不是真的把杯子贴到嘴并持续吞咽,而不是拿起来晃一下就放下。
3.2 YOLO标注格式与目录结构:从LabelImg到txt文件
标注工具用的是LabelImg和Roboflow混合流程。LabelImg负责画框,导出Pascal VOC格式,然后用脚本转换成YOLO的txt格式。目录结构如下:
aedes_dataset/ ├── images/ │ ├── train/ # 5460张 │ ├── val/ # 1170张 │ └── test/ # 1170张 ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── classes.txt └── data.yaml每张图对应的txt文件和图片同名,每行格式是:class_id x_center y_center width height,坐标全部归一化到0到1之间。我们classes.txt里只有两类:
0: biting 1: non-biting这里提醒一个新手常踩的坑:从LabelImg导出时,如果保存的XML是绝对路径,换机器后路径全断。一定要用相对路径或者脚本重写图片路径部分,我们第一版就栽在了这个上面,白费了三天。
3.3 多轮质检与边界样本处理:玻璃反光、遮挡与离群框
标注质量是数据集的命。有一批框,我们审核时发现标注员把蚊子翅膀阴影也框进去了,导致模型学的目标区域比真实虫体大一圈。所以质检环节我们做了双重审核:第一轮检查类别标签是否正确,第二轮检查边界框是否贴合虫体。
具体规范三条:
- 框必须紧贴蚊子最外轮廓,触角、足、翅的伸展范围可以不包含,但胸腹主体不能漏;
- 两只蚊子重叠时,各标各的,允许框之间有较大IoU,不能因为重叠就丢掉一只;
- 严重模糊、失焦、目标小于12×12像素的样本,直接弃用,不勉强标。
边界样本统一用“特殊未知类”暂存,不打进训练集,这个做法后来被证明极其有效——因为边界样本往往是噪声最大的,宁缺毋滥。
4. 训练YOLO微调:小目标检测的参数博弈与实测结果
4.1 模型选型与输入分辨率:1280塔顶,还是切片大法
YOLO系列现在选择很多,但针对“4毫米左右的蚊子在高清图上只占几十个像素”的极端场景,选型逻辑和一般目标检测不一样。
我们最终选了YOLOv8的这个配置:
- 模型规模:yolov8s,比n精度稳,又比m能在边缘设备上跑起来;
- 输入分辨率:1280×1280;
- 预训练权重:官方COCO预训练。
为什么不用yolov5?不是不好,而是v8的anchor-free检测头在极小目标上的中心点回归更直接,少了anchor匹配的繁琐步骤。为什么不用yolov9或v10?当时它们刚出,生态和部署链还没完全稳定,对一个要交付的项目来说,稳定压倒一切。
输入分辨率这里有个重大取舍。直接1080p原图送进网络显存爆掉;压到640×640,蚊子目标可能只剩15×15像素,模型极难区分“biting”和“non-biting”。我们试了两种路:
- 第一种:整图缩放到1280×1280,动用A100的40G显存,batch降到8;
- 第二种:把原始1920×1080图像切成四个1050×1080的overlap切片(重叠50像素),每片缩放到640×640再推理,最后把检测结果合并回原图坐标。
实测结果证明第二种方案对小目标友好得多,代价是推理耗时翻倍。如果你没有大显存,优先走切片路线,别硬降分辨率。
4.2 训练配置与增强策略:Mosaic在昆虫小目标上反而帮倒忙
训练超参数是我们反复试出来的,先说三个最关键的:
- epochs=200:小目标任务收敛慢,早期epoch前20个几乎没有有效loss下降,别急着早停;
- batch=16:配合1280输入,用A100刚好能跑,batch再大收益已经很有限;
- optimizer=SGD:AdamW前期冲得快,后期细粒度回归反而不及SGD稳定,对小目标框精度更明显。
最反直觉的是数据增强。YOLO官方默认开了Mosaic(4张图拼一张)和MixUp,这个配置在常规检测任务上涨点,但用在蚊子身上我们吃了个大亏。为什么?因为Mosaic把4张图缩放到四分之一再拼贴,每个蚊子目标变得更小,甚至缩小到不足10像素,标注框在拼接边还会发生目标“被切割”的情况。模型学到的特征变成了“模糊小色块”,而不是“蚊子”。
我们把Mosaic关了,保留轻微HSV增强(饱和度±30%,亮度±20%)和随机平移旋转(±10度),效果立刻回升。结论很简单:增强策略不能照搬默认,要看你目标的原始像素占比。大目标扛得住几何畸变,小目标一步就变形到认不出来。
4.3 指标与常见误检:mAP50可以,头疼的是“影子蚊子”
最终在测试集(按事件隔离的1170张)上,我们得到的指标大致是:
| 类别 | mAP50 | mAP50-95 | Precision | Recall |
|---|---|---|---|---|
| biting | 87.6% | 56.2% | 88.3% | 83.1% |
| non-biting | 91.2% | 63.4% | 92.0% | 89.7% |
整体看着还行,但打开错误分析,最大的误检来源统一指向“影子蚊子”——也就是膜面褶皱、加热器金属边缘的黑影,形状和蚊子轮廓有几分像,模型在低置信度区间会误判成non-biting,偶尔连biting也误报。
这个问题的根子在训练数据里缺少“负样本中的形状相似物”。后来我们专门去拍了一组无蚊空膜和装置边缘的素材,以负样本形式混入训练,误检率直接降了约3%。这个经验对所有做小目标检测的人都通用:你的数据里不仅要有目标,还要有“看起来像目标但不是目标”的东西。
5. 落地到虫媒监测:一个检测器能替代什么,还不能替代什么
5.1 从检测到指标:吸血率、单笼计数与昼夜节律统计
模型训练完终究要回答生物学问题。我们把检测结果接入后处理流水线,每次推理输出三样东西:检测框、类别、置信度;然后按时间窗聚合成指标。
最核心的落地指标是吸血率(biting rate),计算口径很简单:一段固定观察时间内,biting类检测帧数占总有效蚊虫检测帧数的比例。配合事件过滤(同一只蚊连续出现算一个事件),我们能够自动统计一批蚊子里完成吸血行为尝试的占比。这比人工数尸和解剖省太多时间了。
另一个应用方向是行为节律研究。埃及伊蚊白天活动,吸血高峰通常在早晨和傍晚。我们连续录制48小时,用模型自动产出时段-吸血频率曲线,可以直接看出这个种群在实验条件下的节律特征。以往这种数据只能靠人盯着屏幕记录,现在一台普通机器就能跑。
5.2 边缘设备部署与功耗取舍:Orin Nano上的实测帧率
部署端,我们测试了Jetson Orin Nano 8GB版本,用TensorRT对YOLOv8s进行FP16量化。
- 1280×1280整图推理:约18ms/帧;
- 切片模式(2片并行):约32ms/帧;
- 单设备功耗:10W~15W之间。
也就是说,一条检测流水线完全可以在无网环境、野外站点或养殖笼旁边实时跑。但这里有个网络结构上的注意点:小目标检测时,FP16量化带来的特征精度损失有时候是致命的,我们对比后发现腹部膨胀边缘的定位框平均后退了2到3个像素。如果业务对框精度极其敏感,建议保留FP32推理或者只在靠近输出层的部分用FP16。
5.3 后续演进:多蚊种分类、关键点预测与行为序列建模
7800张只是个起点。我在项目收尾后思考过三条明确的升级路径:
第一,把二分类扩展成多分类,把白纹伊蚊、库蚊、按蚊都加进来,做“同画面多蚊种行为识别”,这对不同传播链的区分极有价值。第二,在检测框基础上加关键点标注——比如口器尖端与腹部末端,用YOLOv8-pose去预测姿态,可以更精细区分“探查”和“真正刺入”。第三,不要把每一帧孤立看待,结合DeepSORT做跨帧跟踪,行为就成了一串状态序列(停落→探查→吸血→离开),平滑掉单帧误检。
这几条路都不难,但每一步都需要更大量的标注投入,也会遇到比“影子蚊子”更刁钻的问题。
最后想说的
这个数据集项目给我最大的收获,倒不是模型最终涨了几个点,而是我重新理解了“数据质量”这个词的颗粒度。蚊子吸血行为这种精细任务,标注框偏移5个像素、类别边界模糊一点,模型的表现就差很多。你在实际构建类似数据集时,我建议把标注规范的评审放在所有工作之前,宁可多花一周把SOP磨到位,也别后期为洗数据熬夜。如果你也要做蚊虫或昆虫行为相关检测,欢迎拿这套数据或这个流程做起点,至少踩坑的路径我已经替你走了一遍。