- 我复现了yolov7s-face的精度,我没有加载预训练模型,重新训的,300个epoch,最优的模型精度比官方的点还要高一点,下面是我模型的精度和官方的精度:我训出来模型的指标: yolov7s 训练300epoch best.pt ==================== Results ==================== Easy Val AP: 0.9510914378803449 Medium Val AP: 0.9349033662833984 Hard Val AP: 0.8550381774914542 =================================================官方模型的指标: ==================== Results ==================== Easy Val AP: 0.9481596778871507 Medium Val AP: 0.9314085577436426 Hard Val AP: 0.8516288529133722 ================================================= 2.如何对val数据集进行评测,先改一下detect.py代码生成用于评测精度的txt文件,代码如下:
import argparse
import time
from pathlib import Path
import os
import copy
import cv2
import torch
import torch.backends.cudnn as cudnn
from numpy import random
from models.experimental import attempt_load
from utils.datasets import LoadStreams, LoadImages
from utils.general import check_img_size, check_requirements, check_imshow, non_max_suppression, apply_classifier, \
scale_coords, xyxy2xywh, strip_optimizer, set_logging, increment_path, save_one_box
from utils.plots import colors, plot_one_box
from utils.torch_utils import select_device, load_classifier, time_synchronized
defdetect(opt):
source, weights, view_img, save_txt, imgsz, save_txt_tidl, kpt_label ,widerface,save_widerface= opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size, opt.save_txt_tidl, opt.kpt_label,opt.widerface,opt.save_widerface
save_img =not opt.nosave andnot source.endswith('.txt')# save inference images
webcam = source.isnumeric()or source.endswith('.txt')or source.lower().startswith(('rtsp://','rtmp://','http://','https://'))# Directories
save_dir = increment_path(Path(opt.project)/ opt.name, exist_ok=opt.exist_ok)# increment run(save_dir /'labels'if(save_txt or save_txt_tidl)else save_dir).mkdir(parents=True, exist_ok=True)# make dir# Initialize
set_logging()
device = select_device(opt.device)
half = device.type!='cpu'andnot save_txt_tidl # half precision only supported on CUDA# Load model
model = attempt_load(weights, map_location=device)# load FP32 model
stride =int(model.stride.max())# model strideifisinstance(imgsz,(list,tuple)):assertlen(imgsz)==2;"height and width of image has to be specified"
imgsz[0]= check_img_size(imgsz[0], s=stride)
imgsz[1]= check_img_size(imgsz[1], s=stride)else:
imgsz = check_img_size(imgsz, s=stride)# check img_size
names = model.module.names ifhasattr(model,'module')else model.names # get class namesif half:
model.half()# to FP16# Second-stage classifier
classify =Falseif classify:
modelc = load_classifier(name='resnet101', n=2)# initialize
modelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model']).to(device).eval()# Set Dataloader
vid_path, vid_writer =None,Noneif webcam:
view_img = check_imshow()
cudnn.benchmark =True# set True to speed up constant image size inference
dataset = LoadStreams(source, img_size=imgsz, stride=stride)else:
dataset = LoadImages(source, img_size=imgsz, stride=stride)# Run inferenceif device.type!='cpu':
model(torch.zeros(1,3, imgsz, imgsz).to(device).type_as(next(model.parameters())))# run once
t0 = time.time()for path, img, im0s, vid_cap in dataset:
img = torch.from_numpy(img).to(device)
img = img.half()if half else img.float()# uint8 to fp16/32
img /=255.0# 0 - 255 to 0.0 - 1.0if img.ndimension()==3:
img = img.unsqueeze(0)# Inference
t1 = time_synchronized()
pred = model(img, augment=opt.augment)[0]print(pred[...,4].max())# Apply NMS
pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres, classes=opt.classes, agnostic=opt.agnostic_nms, kpt_label=kpt_label)
t2 = time_synchronized()# Apply Classifierif classify:
pred = apply_classifier(pred, modelc, img, im0s)# Process detectionsfor i, det inenumerate(pred):# detections per imageif webcam:# batch_size >= 1
p, s, im0, frame = path[i],'%g: '% i, im0s[i].copy(), dataset.count
else:
p, s, im0, frame = path,'', im0s.copy(),getattr(dataset,'frame',0)
p = Path(p)# to Path
save_path =str(save_dir / p.name)# img.jpg
txt_path =str(save_dir /'labels'/ p.stem)+(''if dataset.mode =='image'elsef'_{frame}')# img.txt
s +='%gx%g '% img.shape[2:]# print string
gn = torch.tensor(im0.shape)[[1,0,1,0]]# normalization gain whwh# print("det----",det)# print("det.Size()---",det.shape[0])# exit(-1)if det.shape[0]==0:# print("det is None:====",det)# exit(-1)
os.makedirs(save_widerface,exist_ok=True)
save_widerface_txt =str(Path(save_widerface)/Path(Path(p).name[:-3]+"txt"))withopen(save_widerface_txt,"w")as fwider:
widerface_file_name = Path(p).name[:-4]+"\n"print("=========",widerface_file_name)# exit(-1)
fwider.write(widerface_file_name)
fwider.write(str(0)+"\n")iflen(det):# Rescale boxes from img_size to im0 size
scale_coords(img.shape[2:], det[:,:4], im0.shape, kpt_label=False)
scale_coords(img.shape[2:], det[:,6:], im0.shape, kpt_label=kpt_label, step=3)# Print resultsfor c in det[:,5].unique():
n =(det[:,5]== c).sum()# detections per class
s +=f"{n}{names[int(c)]}{'s'*(n >1)}, "# add to stringif widerface:
os.makedirs(save_widerface,exist_ok=True)
save_widerface_txt =str(Path(save_widerface)/Path(Path(p).name[:-3]+"txt"))
widerface_file_name = Path(p).name[:-4]+"\n"
widerface_bboxs_num =str(len(pred[0]))+"\n"withopen(save_widerface_txt,"a")as fwider:
fwider.write(widerface_file_name)
fwider.write(widerface_bboxs_num)# Write resultsfor det_index,(*xyxy, conf, cls)inenumerate((det[:,:6])):if widerface:if cls ==0:
os.makedirs(save_widerface,exist_ok=True)
save_widerface_txt =str(Path(save_widerface)/Path(Path(p).name[:-3]+"txt"))#widerface_file_name = Path(p).name + "\n"#widerface_bboxs_num = str(len(pred[0])) +"\n"
x1 =int(xyxy[0]+0.5)
y1 =int(xyxy[1]+0.5)
x2 =int(xyxy[2]+0.5)
y2 =int(xyxy[3]+0.5)withopen(save_widerface_txt,"a")as fwider:#fwider.write(widerface_file_name)#fwider.write(widerface_bboxs_num)
fwider.write("%d %d %d %d %.03f"%(x1,y1,x2-x1,y2-y1,conf if conf<=1else1)+"\n")if save_txt:# Write to file
xywh =(xyxy2xywh(torch.tensor(xyxy).view(1,4))/ gn).view(-1).tolist()# normalized xywh
line =(cls,*xywh, conf)if opt.save_conf else(cls,*xywh)# label formatwithopen(txt_path +'.txt','a')as f:
f.write(('%g '*len(line)).rstrip()% line +'\n')# if save_img or opt.save_crop or view_img: # Add bbox to image# c = int(cls) # integer class# label = None if opt.hide_labels else (names[c] if opt.hide_conf else f'{names[c]} {conf:.2f}')# kpts = det[det_index, 6:]# plot_one_box(xyxy, im0, label=label, color=colors(c, True), line_thickness=opt.line_thickness, kpt_label=kpt_label, kpts=kpts, steps=3, orig_shape=im0.shape[:2])# if opt.save_crop:# save_one_box(xyxy, im0s, file=save_dir / 'crops' / names[c] / f'{p.stem}.jpg', BGR=True)if save_txt_tidl:# Write to file in tidl dump formatfor*xyxy, conf, cls in det_tidl:
xyxy = torch.tensor(xyxy).view(-1).tolist()
line =(conf, cls,*xyxy)if opt.save_conf else(cls,*xyxy)# label formatwithopen(txt_path +'.txt','a')as f:
f.write(('%g '*len(line)).rstrip()% line +'\n')# Print time (inference + NMS)print(f'{s}Done. ({t2 - t1:.3f}s)')# Stream resultsif view_img:
cv2.imshow(str(p), im0)
cv2.waitKey(1)# 1 millisecond# Save results (image with detections)if save_img:if dataset.mode =='image':
cv2.imwrite(save_path, im0)else:# 'video' or 'stream'if vid_path != save_path:# new video
vid_path = save_path
ifisinstance(vid_writer, cv2.VideoWriter):
vid_writer.release()# release previous video writerif vid_cap:# video
fps = vid_cap.get(cv2.CAP_PROP_FPS)
w =int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h =int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))else:# stream
fps, w, h =30, im0.shape[1], im0.shape[0]
save_path +='.mp4'
vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*'mp4v'), fps,(w, h))
vid_writer.write(im0)if save_txt or save_txt_tidl or save_img:
s =f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir /'labels'}"if save_txt or save_txt_tidl else''print(f"Results saved to {save_dir}{s}")print(f'Done. ({time.time()- t0:.3f}s)')if __name__ =='__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--weights', nargs='+',type=str, default='yolov5s.pt',help='model.pt path(s)')
parser.add_argument('--source',type=str, default='data/images',help='source')# file/folder, 0 for webcam
parser.add_argument('--img-size', nargs='+',type=int, default=640,help='inference size (pixels)')
parser.add_argument('--conf-thres',type=float, default=0.01,help='object confidence threshold')
parser.add_argument('--iou-thres',type=float, default=0.5,help='IOU threshold for NMS')
parser.add_argument('--device', default='',help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--view-img', action='store_true',help='display results')
parser.add_argument('--save-txt', action='store_true',help='save results to *.txt')
parser.add_argument('--save-txt-tidl', action='store_true',help='save results to *.txt in tidl format')
parser.add_argument('--save-bin', action='store_true',help='save base n/w outputs in raw bin format')
parser.add_argument('--save-conf', action='store_true',help='save confidences in --save-txt labels')
parser.add_argument('--save-crop', action='store_true',help='save cropped prediction boxes')
parser.add_argument('--nosave', action='store_true',help='do not save images/videos')
parser.add_argument('--classes', nargs='+',type=int,help='filter by class: --class 0, or --class 0 2 3')
parser.add_argument('--agnostic-nms', action='store_true',help='class-agnostic NMS')
parser.add_argument('--augment', action='store_true',help='augmented inference')
parser.add_argument('--update', action='store_true',help='update all models')
parser.add_argument('--project', default='runs/detect',help='save results to project/name')
parser.add_argument('--name', default='exp',help='save results to project/name')
parser.add_argument('--exist-ok', action='store_true',help='existing project/name ok, do not increment')
parser.add_argument('--line-thickness', default=3,type=int,help='bounding box thickness (pixels)')
parser.add_argument('--hide-labels', default=False, action='store_true',help='hide labels')
parser.add_argument('--hide-conf', default=False, action='store_true',help='hide confidences')
parser.add_argument('--kpt-label',type=int, default=5,help='number of keypoints')
parser.add_argument("--widerface",action="store_true",help='save widerface_val txt')
parser.add_argument('--save-widerface',type=str, default='./widerface_txt',help=' save widerface_txt folder')
opt = parser.parse_args()print(opt)
check_requirements(exclude=('tensorboard','pycocotools','thop'))with torch.no_grad():if opt.update:# update all models (to fix SourceChangeWarning)for opt.weights in['yolov5s.pt','yolov5m.pt','yolov5l.pt','yolov5x.pt']:
detect(opt=opt)
strip_optimizer(opt.weights)else:
detect(opt=opt)
执行命令
CUDA_VISIBLE_DEVICES=0 python detect-widerface.py --weights your path --source your input_path --widerface --save-widerface 2023-widerface-1600
3.最后一步就是将生成的txt文件移到指定的目录下,代码如下
import os
import os.path as osp
import re
import shutil
from pathlib import Path
if __name__ =="__main__":#用于评测的txt文件夹
path ="./yolov7s_txt-pre-weight"#detect生成的txt文件
source_path ="./2023-widerface-1600"
dir_list =["0--Parade","1--Handshaking","2--Demonstration","3--Riot","4--Dancing","5--Car_Accident","6--Funeral","7--Cheering","8--Election_Campain","9--Press_Conference","10--People_Marching","11--Meeting","12--Group","13--Interview","14--Traffic","15--Stock_Market","16--Award_Ceremony","17--Ceremony","18--Concerts","19--Couple","20--Family_Group","21--Festival","22--Picnic","23--Shoppers","24--Soldier_Firing","25--Soldier_Patrol","26--Soldier_Drilling","27--Spa","28--Sports_Fan","29--Students_Schoolkids","30--Surgeons","31--Waiter_Waitress","32--Worker_Laborer","33--Running","34--Baseball","35--Basketball","36--Football","37--Soccer","38--Tennis","39--Ice_Skating","40--Gymnastics","41--Swimming","42--Car_Racing","43--Row_Boat","44--Aerobics","45--Balloonist","46--Jockey","47--Matador_Bullfighter","48--Parachutist_Paratrooper","49--Greeting","50--Celebration_Or_Party","51--Dresses","52--Photographers","53--Raid","54--Rescue","55--Sports_Coach_Trainer","56--Voter","57--Angler","58--Hockey","59--people--driving--car","61--Street_Battle"]for dir_path in dir_list:
obj_path = osp.join(path,dir_path)
os.makedirs(obj_path,exist_ok=True)# num = 0# print("source_path===",source_path)for file_path in os.listdir(source_path):
file_id_compile = re.compile(r"([\d]+)_")
file_id = re.findall(file_id_compile,file_path)[0]
file_paths = osp.join(source_path,file_path)
dir_id_compile = re.compile(r"([\d]+)--")for path_dir in dir_list:
dir_id = re.findall(dir_id_compile,path_dir)[0]# print("dir_id:%s"%(dir_id))if file_id == dir_id:# print("file_id===%s,dir_id===%s"%(file_id,dir_id))
shutil.copyfile(file_paths,Path(Path(path)/path_dir)/file_path)break
本文转载自: https://blog.csdn.net/qq_35140742/article/details/128727680
版权归原作者 阿吉的CV之路 所有, 如有侵权,请联系我们删除。
版权归原作者 阿吉的CV之路 所有, 如有侵权,请联系我们删除。