Yolov5-v6.0学习笔记10|val.py代码详解
val.py简介
val.py文件主要是在每一轮的训练结束后,验证当面模型的mAP、混淆矩阵等指标。
mAP:英文全称为 Mean Average Precision,作为目标检测中的平均精度
AP:(平均精度)是衡量目标检测算法好坏的常用指标,在Faster R-CNN,SSD等算法中作为评估指标。
AP等于recall值取0-1时,precision值的平均值
混淆矩阵:也称误差矩阵,是表示精度评价的一种标准格式,用n行n列的矩阵形式来表示。具体评价指标有总体精度、制图精度、用户精度等,这些精度指标从不同的侧面反映了图像分类的精度。在人工智能中,混淆矩阵(confusion matrix)是可视化工具,特别用于监督学习,在无监督学习一般叫做匹配矩阵。在图像精度评价中,主要用于比较分类结果和实际测得值,可以把分类结果的精度显示在一个混淆矩阵里面。混淆矩阵是通过将每个实测像元的位置和分类与分类图像中的相应位置和分类相比较计算的。
实际上这个脚本最常用的应该是通过train.py调用run函数,而不是通过执行val.py的。所以在这个脚本中,最重要的就是run函数。
opt参数
1 | def parse_opt(): |
opt参数详解:
opt参数详解
data: 数据集配置文件地址 包含数据集的路径、类别个数、类名、下载地址等信息
weights: 模型的权重文件地址 weights/yolov5s.pt
batch_size: 前向传播的批次大小 默认32
imgsz: 输入网络的图片分辨率 默认640
conf-thres: object置信度阈值 默认0.25
iou-thres: 进行NMS时IOU的阈值 默认0.6
task: 设置测试的类型 有train, val, test, speed or study几种 默认val
device: 测试的设备
single-cls: 数据集是否只用一个类别 默认False
augment: 测试是否使用TTA Test Time Augment 默认False
verbose: 是否打印出每个类别的mAP 默认False
下面三个参数是auto-labelling(有点像RNN中的teaching forcing)
save-txt: traditional auto-labelling
save-hybrid: save hybrid autolabels, combining existing labels with new predictions before NMS (existing predictions given confidence=1.0 before NMS.
save-conf: add confidences to any of the above commands
save-json: 是否按照coco的json格式保存预测框,并且使用cocoapi做评估(需要同样coco的json格式的标签) 默认False
project: 测试保存的源文件 默认runs/test
name: 测试保存的文件地址 默认exp 保存在runs/test/exp下
exist-ok: 是否存在当前文件 默认False 一般是 no exist-ok 连用 所以一般都要重新创建文件夹
half: 是否使用半精度推理 默认False
main()函数
1 | def main(opt): |
在这个模块中,根据opt.task分为三个分支,即[train, val, test]、[speed]、[study],最主要的分支还是在
1 | opt.task in ('train', 'val', 'test') |
这段代码的意思是如果task in [‘train’, ‘val’, ‘test’]就正常测试 训练集/验证集/测试集。
一般直接进入第一个分支,执行run()函数。
run()函数
1 | if RANK in [-1, 0]: |
run()函数在train.py中执行,用来在每个epoch后验证当前模型。
载入参数
1 | def run(data, |
参数解释:
data: 数据集配置文件地址–包含数据集的路径、类别个数、类名、下载地址等信息 train.py时传入data_dict
weights: 模型的权重文件地址 运行train.py=None 运行test.py=默认weights/yolov5s.pt
batch_size: 前向传播的批次大小 运行test.py传入默认32 运行train.py则传入batch_size // WORLD_SIZE * 2
imgsz: 输入网络的图片分辨率 运行test.py传入默认640 运行train.py则传入imgsz_test
conf_thres: object置信度阈值 默认0.25
iou_thres: 进行NMS时IOU的阈值 默认0.6
task: 设置测试的类型 有train, val, test, speed or study几种 默认val
device: 测试的设备
single_cls: 数据集是否只用一个类别 运行test.py传入默认False 运行train.py则传入single_cls
augment: 测试是否使用TTA Test Time Augment 默认False
verbose: 是否打印出每个类别的mAP 运行test.py传入默认Fasle 运行train.py则传入nc < 50 and final_epoch
save_txt: 是否以txt文件的形式保存模型预测框的坐标 默认True
save_hybrid: 是否save label+prediction hybrid results to *.txt 默认False
save_conf: 是否保存预测每个目标的置信度到预测tx文件中 默认True
save_json: 是否按照coco的json格式保存预测框,并且使用cocoapi做评估(需要同样coco的json格式的标签)
- 运行test.py传入默认Fasle 运行train.py则传入is_coco and final_epoch(一般也是False)
project: 测试保存的源文件 默认runs/test
name: 测试保存的文件地址 默认exp 保存在runs/test/exp下
exist_ok: 是否存在当前文件 默认False 一般是 no exist-ok 连用 所以一般都要重新创建文件夹
half: 是否使用半精度推理 FP16 half-precision inference 默认False
model: 模型 如果执行test.py就为None 如果执行train.py就会传入ema.ema(ema模型)
dataloader: 数据加载器 如果执行test.py就为None 如果执行train.py就会传入testloader
save_dir: 文件保存路径 如果执行test.py就为‘’ 如果执行train.py就会传入save_dir(runs/train/expn)
plots: 是否可视化 运行test.py传入默认True 运行train.py则传入plots and final_epoch
wandb_logger: 网页可视化 类似于tensorboard 运行test.py传入默认None 运行train.py则传入wandb_logger(train)
compute_loss: 损失函数 运行test.py传入默认None 运行train.py则传入compute_loss(train)
return (Precision, Recall, map@0.5, map@0.5:0.95, box_loss, obj_loss, cls_loss)
初始化/加载模型并选择处理器
训练时(train.py)调用:初始化模型参数、训练设备
验证时(val.py)调用:初始化设备、save_dir文件路径、make dir、加载模型、check imgsz、 加载+check data配置信息
1 | # Initialize/load model and set device |
调整模型
1 | half &= device.type != 'cpu' # half precision only supported on CUDA |
半精度验证half model + 模型剪枝prune + 模型融合conv+bn
模型验证
1 | model.eval() |
是否是COCO数据集is_coco + 类别数nc + 计算mAP相关参数 + 初始化日志Logging
加载val数据集
训练时(train.py)调用:加载val数据集
验证时(val.py)调用:不需要加载val数据集 直接从train.py 中传入testloader
1 | # Dataloader |
初始化配置
1 | seen = 0 |
初始化混淆矩阵 + 数据集类名 + 获取coco数据集的类别索引 + 设置tqdm进度条 + 初始化p, r, f1, mp, mr, map50, map指标和时间t0, t1, t2 + 初始化测试集的损失 + 初始化json文件中的字典 统计信息 ap等
开始验证
1 | for batch_i, (im, targets, paths, shapes) in enumerate(pbar): |
预处理图片和target
1 | t1 = time_sync() |
model前向推理
1 | # Inference |
计算验证集损失
1 | # Loss |
运行NMS
1 | # NMS |
首先将真实框target的xywh(因为target是在labelimg中做了归一化的)映射到img(test)尺寸;
save_hybrid: adding the dataset labels to the model predictions before NMS
意思是在NMS之前将数据集标签targets添加到模型预测中
这允许在数据集中自动标记(for autolabelling)其他对象(在pred中混入gt) 并且mAP反映了新的混合标签targets: [num_target, img_index+class_index+xywh] = [31, 6]
lb: {list: bs} 第一张图片的target[17, 5] 第二张[1, 5] 第三张[7, 5]
统计每章图片的真实框、预测框信息
1 | # Metrics |
为每张图片做统计,写入预测信息到txt文件,生成json文件字典,统计tp等
- out: list{bs} [300, 6] [42, 6] [300, 6] [300, 6] [:, image_index+class+xywh]
获取第si张图片的gt标签信息,包括class、x、y、w、h,target[:, 0]为标签属于哪张图片的编号
- nl为第si张图片的gt个数
- path为第si张图片的地址
如果预测为空,则添加空的信息到stats里
- predn 将预测坐标映射到原图img中