目录
- 前言
- 0、导入需要的包和基本配置
- 1、设置opt参数
- 2、执行main函数
- 3、执行run函数
-
- 3.1、载入参数
- 3.2、初始化配置1
- 3.3、调整模型
- 3.4、初始化配置2
- 3.5、加载val数据集
- 3.6、初始化配置3
- 3.7、开始验证
-
- 3.7.1、预处理图片和target
- 3.7.2、model 前向推理
- 3.7.3、计算验证集损失
- 3.7.4、Run NMS
- 3.7.5、统计每张图片的真实框、预测框信息
- 3.7.6、保存预测信息到image_name.txt文件
- 3.7.7、保存预测信息到wandb_logger
- 3.7.8、将预测信息保存到coco格式的json字典
- 3.7.9、计算混淆矩阵、计算correct、生成stats
- 3.7.10、画出前三个batch图片的gt和pred框
- 3.7.11、计算mAP
- 3.7.12、print打印各项指标
- 3.7.13、画出混淆矩阵并存入wandb_logger中
- 3.7.14、Save JSON
- 3.7.15、 Return results
- 总结
前言
源码: YOLOv5源码.
导航: 【YOLOV5-5.x 源码讲解】整体项目文件导航.
注释版全部项目文件已上传至GitHub: yolov5-5.x-annotations.
这个文件主要是在每一轮训练结束后,验证当前模型的mAP、混淆矩阵等指标。这个文件本来是叫test.py的,但我觉得叫val.py可能更加恰当些,所以改了。
实际上这个脚本最常用的应该是通过train.py调用 run 函数,而不是通过执行 val.py 的。所以在了解这个脚本的时候,其实最重要的就是 run 函数。
0、导入需要的包和基本配置
import argparse # 解析命令行参数模块
import json # 实现字典列表和JSON字符串之间的相互解析
import os # 与操作系统进行交互的模块 包含文件路径操作和解析
import sys # sys系统模块 包含了与Python解释器和它的环境有关的函数
from pathlib import Path # Path将str转换为Path对象 使字符串路径易于操作的模块
from threading import Thread # 线程操作模块
import numpy as np
import torch
import yaml
from tqdm import tqdm
FILE = Path(__file__).absolute() # FILE = WindowsPath 'F:yolo_v5yolov5-Ual.py'
# 将'F:/yolo_v5/yolov5-U'加入系统的环境变量 该脚本结束后失效
sys.path.append(FILE.parents[0].as_posix()) # add yolov5/ to path
from models.experimental import attempt_load
from utils.datasets import create_dataloader
from utils.general import coco80_to_coco91_class, check_dataset, check_file, check_img_size, check_requirements,
box_iou, non_max_suppression, scale_coords, xyxy2xywh, xywh2xyxy, set_logging, increment_path, colorstr
from utils.metrics import ap_per_class, ConfusionMatrix
from utils.plots import plot_images, output_to_target, plot_study_txt
from utils.torch_utils import select_device, time_synchronized
1、设置opt参数
def parse_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)相关参数详见:https://github.com/ultralytics/yolov5/issues/1563 下面解释是作者原话
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
"""
parser = argparse.ArgumentParser(prog='val.py')
parser.add_argument('--data', type=str, default='data/coco128.yaml', help='dataset.yaml path')
parser.add_argument('--weights', nargs='+', type=str, default='weights/yolov5s.pt', help='model.pt path(s)')
parser.add_argument('--batch-size', type=int, default=4, help='batch size')
parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=640, help='inference size (pixels)')
parser.add_argument('--conf-thres', type=float, default=0.001, help='confidence threshold')
parser.add_argument('--iou-thres', type=float, default=0.6, help='NMS IoU threshold')
parser.add_argument('--task', default='val', help='train, val, test, speed or study')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--single-cls', action='store_true', help='treat as single-class dataset')
parser.add_argument('--augment', action='store_true', help='augmented inference')
parser.add_argument('--verbose', action='store_true', help='report mAP by class')
parser.add_argument('--save-txt', default=True, action='store_true', help='save results to *.txt')
parser.add_argument('--save-hybrid', action='store_true', help='save label+prediction hybrid results to *.txt')
parser.add_argument('--save-conf', default=True, action='store_true', help='save confidences in --save-txt labels')
parser.add_argument('--save-json', action='store_true', help='save a cocoapi-compatible JSON results file')
parser.add_argument('--project', default='runs/test', help='save to project/name')
parser.add_argument('--name', default='exp', help='save to project/name')
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')
opt = parser.parse_args() # 解析上述参数
opt.save_json |= opt.data.endswith('coco.yaml') # |或 左右两个变量有一个为True 左边变量就为True
opt.save_txt |= opt.save_hybrid
opt.data = check_file(opt.data) # check file
return opt
2、执行main函数
def main(opt):
# 初始化日志 设置logging的等级level、输出格式和内容format等基本信息
set_logging()
# 打印信息 test(高亮): opt各个参数值
print(colorstr('test: ') + ', '.join(f'{k}={v}' for k, v in vars(opt).items()))
# 检测requirements文件中需要的包是否安装好了
check_requirements(exclude=('tensorboard', 'thop'))
# 如果task in ['train', 'val', 'test']就正常测试 训练集/验证集/测试集
if opt.task in ('train', 'val', 'test'): # run normally
run(**vars(opt))