自制AVA数据集并训练
- 前言
- 软硬件配置
- 数据集整体结构
- 视频预处理部分
- 帧率转换与视频分割
- 视频重命名
- 对视频进行帧分割
- 整合帧
- 预标注
- 目标检测标注检查
- 生成pkl文件
- 生成VIA标注文件
- 使用VIA进行标注
- VIA标注文件整合
- deepsort追踪
- VIA和deepsort整合
- 去除误差值
- 生成标注框文件
- 生成排除的标注戳的文件
- 生成frame_lists
- 生成行为标注
- 训练
前言
上次使用几个视频做了一个小demo
这次是完整的自制ava行为数据集进行训练
我是做野生动物
主要参考教程是杨帆老师的博客
感谢大佬,真的!
自定义ava数据集及训练与测试 完整版
关于我自己使用的代码放在了这里,大家需要的话可以下载参考
https://gitee.com/gkotta1/datadeal/tree/master
关于里面的代码,会更适用于我自己的数据集,所以大家可以根据自己的需要稍作改动
软硬件配置
win 11
python 3.8
pytorch 2.0.0
torchvision 0.15.0
CUDA 11.8
RTX3070
数据集整体结构
数据集的整体结构如下所示,有将最主要的代码结构和需要的文件标出
dataset/ │ ├── annotations/ │ ├── action_list.pbtxt │ ├── ava_detection_train_boxes_and_labels.csv │ ├── ava_detection_val_boxes_and_labels.csv │ ├── ava_train_excluded_timestamps_v2.2.csv │ ├── ava_train_v2.2.csv │ ├── ava_val_excluded_timestamps_v2.2.csv │ └── ava_val_v2.2.csv │ ├── frame_lists/ │ ├── train.csv │ └── val.csv │ ├── merge_label_txt/ │ ├── 1_000001.txt │ └── 1_000002.txt │ ├── merge_label_xml/ │ ├── 1_000001.xml │ └── 1_000002.xml │ ├── merge_labelframes_all/ │ ├── 1_000001.jpg │ └── 1_000002.jpg │ ├── videos/ │ ├──1.mp4 │ └──2.mp4 │ ├── videos_labelframes/ │ ├──1│ │ ├── 1_000001.jpg │ │ └── 1_finish.json │ └──2│ ├── videos_rawframes/ │ ├──1│ │ └── 1_000001.jpg │ └──2├── avaMin_dense_proposals_train.pkl └── avaMin_dense_proposals_val.pkl视频预处理部分
帧率转换与视频分割
参考代码:
帧率转换:datadeal\behavior_datadeal\reframe_mp4.py
将所有的视频都转换为30帧/秒
视频切割:datadeal\behavior_datadeal\split_mp4.py
将所有视频最终切割为10秒每段
视频重命名
我的视频是将不同的物种视频分开放的,因此将不同子文件夹下的视频集中到一起并且按照从1开始的序号进行重命名
参考代码:
视频重命名:datadeal\behavior_datadeal\merge_rename_mp4.py
对视频进行帧分割
打开cmd
将路径换到.sh文件所在的目录下,分别运行
shextract_frames_1s.sh# 分割标注帧# 裁剪出来每个视频12帧shextract_frames_30s.sh# 分割原始帧# 裁剪出来每个视频304帧整合帧
将所有的标注帧都放到一起,方便YOLO进行目标检测
参考代码:
整合帧:datadeal\behavior_datadeal\merge_labelframes_all.py
预标注
由于手动标注工作量太大了,再加上via画框实在是有点困难,因此在这里先使用yolo进行预标注,然后使用labelimg修改标注框,最后使用via进行行为标注
使用YOLO进行预标注
运行YOLO文件夹下面的detect.py代码
需要注意这些地方的更改
一定要注意上下都更改
还有下面的save-txt那里,记得default更改为true
推理之后生成这样的一个文件夹
其中labels中存放的是txt文件
但是由于生成的标注文件是丢失或者不准确的
因此使用labelimg对推理结果进行检查并且更正,会更方便一点
目标检测标注检查
为了避免种类的错误,将txt转换为xml格式
参考代码:
txt转xml:datadeal\yolo_datadeal\yolo_xml.py
然后使用labelimg进行预标注
(这部分就不详细讲了,大家需要的话可以去找找labelimg的教程)
预标注完成后再将xml转换为txt
参考代码:
xml转txt:\datadeal\yolo_datadeal\voctotxt.py
生成pkl文件
为了后续步骤分别生成avaMin_dense_proposals_train.pkl和avaMin_dense_proposals_val.pkl文件
提取边界框信息,包括坐标和检测概率,保存为pkl文件
在这里的时候,博主只保留了人的信息,但是我需要每一个物种的信息
每个物种按照4:1的比例分为训练集和验证集
划分原理是:每四个训练文件一个验证文件
运行下面的代码同时生成avaMin_dense_proposals_train.pkl和avaMin_dense_proposals_val.pkl文件
参考代码:
pkl文件生成:datadeal\behavior_datadeal\dense_proposals_train.py
生成VIA标注文件
根据pkl生成VIA标注文件,并且去除默认值
参考代码:
生成via标注文件:datadeal\behavior_datadeal\dense_proposals_train_to_via.py
去除默认值:datadeal\behavior_datadeal\via_json_default_delete.py
使用VIA进行标注
将去除默认值之后生成的json文件,导入VIA
标注过程可以参考上一篇教程
将所有的标注文件都保存为
<文件夹名>_finish.json
VIA标注文件整合
将所有的后缀为_finish.json的标注文件进行整合,整合成一个没有身份ID的表格
参考代码:
标注文件整合:datadeal\behavior_datadeal\json_extract.py
生成train/val_without_personID.csv
deepsort追踪
参考代码:
deepsort追踪:datadeal\behavior_datadeal\yolov5_to_deepsort.py
要注意自己下载权重文件,并且更改路径,生成一个带有标注框和身份ID的csv文件
生成train/val_personID.csv
VIA和deepsort整合
将生成的文件名为train/val_without_personID.csv和train/val_personID.csv的分别整合到一起
参考代码:
VIA和deepsort整合:datadeal\behavior_datadeal\train_temp.py
生成train/val_temp.csv
去除误差值
将上面整合生成的为-1的值去掉,然后生成最终的行为csv文件
参考代码:
去除误差值:datadeal\behavior_datadeal\train.py
生成ava_train/val_v2.2.csv
生成标注框文件
参考代码:
训练标注框:datadeal\behavior_datadeal\train_boxes.py
测试标注框:datadeal\behavior_datadeal\val_boxes.py
生成ava_detection_train/val_boxes_and_labels.csv
生成排除的标注戳的文件
参考代码:
排除标注戳的文件:datadeal\behavior_datadeal\train_excluded_timestamps.py
生成ava_train/val_excluded_timestamps.csv
生成frame_lists
参考代码:
生成帧列表的文件:datadeal\behavior_datadeal\frame_lists.py
生成train/val.csv
生成行为标注
action_list.pbtxt
这个可以自己生成一下
item{name:"moving"id:1}item{name:"grooming"id:2}item{name:"alerting"id:3}item{name:"resting"id:4}item{name:"foraging"id:5}item{name:"flapping"id:6}训练
python tools/run_net.py--cfgconfigs/AVA/SLOWFAST_32x2_R50_animal.yaml这里放一下我的代码,另外注意数据集中名称如果不对,要在default.py中进行更改
我这里没有设置预训练权重,如果需要的话可以自己加上
TRAIN:ENABLE:TrueDATASET:avaBATCH_SIZE:8EVAL_PERIOD:5CHECKPOINT_PERIOD:5AUTO_RESUME:True# CHECKPOINT_FILE_PATH: path to the pretrain checkpoint file.CHECKPOINT_TYPE:pytorchDATA:NUM_FRAMES:32SAMPLING_RATE:2TRAIN_JITTER_SCALES:[256,320]TRAIN_CROP_SIZE:224TEST_CROP_SIZE:224INPUT_CHANNEL_NUM:[3,3]DETECTION:ENABLE:TrueALIGNED:TrueAVA:FRAME_DIR:'D:/file/postgrad/experiment/bird_ava_dataset/videos_rawframes'FRAME_LIST_DIR:'D:/file/postgrad/experiment/bird_ava_dataset/frame_lists'ANNOTATION_DIR:'D:/file/postgrad/experiment/bird_ava_dataset/annotations'DETECTION_SCORE_THRESH:0.8TRAIN_PREDICT_BOX_LISTS:["ava_train_v2.2.csv","ava_detection_train_boxes_and_labels.csv",]TEST_PREDICT_BOX_LISTS:["ava_val_v2.2.csv","ava_detection_val_boxes_and_labels.csv",]SLOWFAST:ALPHA:4BETA_INV:8FUSION_CONV_CHANNEL_RATIO:2FUSION_KERNEL_SZ:7RESNET:ZERO_INIT_FINAL_BN:TrueWIDTH_PER_GROUP:64NUM_GROUPS:1DEPTH:50TRANS_FUNC:bottleneck_transformSTRIDE_1X1:FalseNUM_BLOCK_TEMP_KERNEL:[[3,3],[4,4],[6,6],[3,3]]SPATIAL_DILATIONS:[[1,1],[1,1],[1,1],[2,2]]SPATIAL_STRIDES:[[1,1],[2,2],[2,2],[1,1]]NONLOCAL:LOCATION:[[[],[]],[[],[]],[[],[]],[[],[]]]GROUP:[[1,1],[1,1],[1,1],[1,1]]INSTANTIATION:dot_productPOOL:[[[1,2,2],[1,2,2]],[[1,2,2],[1,2,2]],[[1,2,2],[1,2,2]],[[1,2,2],[1,2,2]]]BN:USE_PRECISE_STATS:FalseNUM_BATCHES_PRECISE:200SOLVER:BASE_LR:0.1# 初始学习率LR_POLICY:steps_with_relative_lrs# 学习率的调整策略STEPS:[0,10,15,20]# 学习率调整的关键节点LRS:[1,0.1,0.01,0.001]# 学习率的缩放比例MAX_EPOCH:30# 训练的总epoch数MOMENTUM:0.9# 动量因子WEIGHT_DECAY:1e-7# 权重衰减系数WARMUP_EPOCHS:5.0# 学习率预热的epoch数量WARMUP_START_LR:0.000125# 预热阶段的起始学习率OPTIMIZING_METHOD:sgdMODEL:NUM_CLASSES:6ARCH:slowfastMODEL_NAME:SlowFastLOSS_FUNC:bceDROPOUT_RATE:0.5HEAD_ACT:sigmoidTEST:ENABLE:FalseDATASET:avaBATCH_SIZE:8DATA_LOADER:NUM_WORKERS:2PIN_MEMORY:TrueNUM_GPUS:1NUM_SHARDS:1RNG_SEED:0OUTPUT_DIR:.