diff --git a/ACL_PyTorch/built-in/cv/Yolov5_for_Pytorch/README.md b/ACL_PyTorch/built-in/cv/Yolov5_for_Pytorch/README.md index b9f882a56ffa34c15bc651d65b41ca0eb0451f18..7556216c51e398d8499d32646a702aa633204682 100644 --- a/ACL_PyTorch/built-in/cv/Yolov5_for_Pytorch/README.md +++ b/ACL_PyTorch/built-in/cv/Yolov5_for_Pytorch/README.md @@ -104,18 +104,21 @@ torch.onnx.export(model, img, f, verbose=False, opset_version=11, input_names=[' ### 3.3 导出onnx模型并量化 (1)下载对应的权重文件置于yolov5目录下,运行脚本导出模型 - ```shell export PYTHONPATH=`pwd`:$PYTHONPATH python3.7 models/export.py --weights=./yolov5s.pt --img-size=640 --batch-size 1 # 用于v2.0->v5.0 python3.7 export.py --weights=./yolov5s.pt --imgsz=640 --batch-size=1 --opset=11 # 用于v6.0 ``` +示例代码导出为静态shape模型,若增加--dynamic参数,导出动态shape模型。 (2)对导出的onnx模型使用onnx-simplifier工具进行简化 - ```shell -python3.7 -m onnxsim --skip-optimization yolov5s.onnx yolov5s_sim.onnx +python3.7 -m onnxsim yolov5s.onnx yolov5s_sim.onnx ``` +若步骤(1)导出动态shape模型,使用onnxsim简化时要增加传参: +--dynamic-input-shape:说明导出模型为动态shape +--input-shape images:1,3,640,640:设置shape的缺省值,若onnxsim不支持动态shape模型简化,则使用该值导出静态shape模型 + (3)生成量化所需的校准数据 ```shell @@ -124,16 +127,16 @@ python3.7 generate_data.py --img_info_file=img_info_amct.txt --save_path=amct_da 参数说明: --img_info_file:生成量化校准数据所用的图片信息,根据实际数据集修改用于量化的图片信息 --save_path:生成校准bin格式数据保存路径 ---batch_size:量化数据batch size,根据使用图片数量修改 +--batch_size:量化数据batch size,根据使用图片数量修改 (4)对简化后的onnx模型进行量化 ```shell bash amct.sh ``` 1. 量化参数说明: ---model:待量化的onnx模型 ---save_path:量化模型保存路径,需要包含量化后文件名的前缀 ---data_dir:量化所需校准数据路径,保存bin文件 + --model:待量化的onnx模型 + --save_path:量化模型保存路径,其中yolov5s为量化后模型名的前缀 + --data_dir:量化所需校准数据路径,保存bin文件 将生成的yolov5s_deploy_model.onnx文件改名为yolov5s_sim_amct.onnx。 2. 量化校准数据生成,注意需和输入数据shape保持一致 1. 可随机生成数据,保存至bin文件(可能存在精度问题) @@ -144,16 +147,17 @@ bash amct.sh ### 3.4 修改onnx模型 运行modify_yolov5.py修改生成的onnx文件,添加后处理算子 - ```shell python3.7 modify_model.py --model=yolov5s_sim.onnx --conf-thres=0.4 --iou-thres=0.5 # 非量化模型 python3.7 modify_model.py --model=yolov5s_sim_amct.onnx --conf-thres=0.4 --iou-thres=0.5 # 量化模型 ``` 参数说明: ---model: 原始onnx模型 ---conf-thres: 后处理算子置信度阈值 ---iou-thres: 后处理算子IOU阈值 -运行脚本后,将生成名为yolov5s_xx_t.onnx的模型。 +--model:原始onnx模型 +--conf-thres:后处理算子置信度阈值 +--iou-thres:后处理算子IOU阈值 +--class-num:模型训练数据集的类别数,需根据实际数据集类别修改,默认80类 +--anchors:训练数据集聚类得到的anchors,需根据实际数据集修改,默认值为yolo提供的anchors,参见[yolo官方代码](https://github.com/ultralytics/yolov5/blob/master/models/yolov5s.yaml) +运行脚本后,由xx.onnx生成名为xx_t.onnx的模型。 ### 3.5 利用ATC工具转换为om模型 @@ -176,7 +180,6 @@ python3.7 parse_json.py (2)推理 配置环境变量,运行脚本进行推理 - ```shell source env.sh # 如果前面配置过,这里不用执行 python3.7 om_infer.py --model=yolov5s_sim_t_bs1.om --img-path=./val2017 --batch-size=1 @@ -189,7 +192,6 @@ python3.7 om_infer.py --model=yolov5s_sim_t_bs1.om --img-path=./val2017 --batch- (3)统计mAP值 运行map_cauculate.py - ```shell python3.7 map_calculate.py --ground_truth_json=./instances_val2017.json --detection_results_json=./predictions.json ``` diff --git a/ACL_PyTorch/built-in/cv/Yolov5_for_Pytorch/modify_model.py b/ACL_PyTorch/built-in/cv/Yolov5_for_Pytorch/modify_model.py index e29882d005e2ec521bd8cd496b9ff784f7b84ae1..3cb238c917d1e6841e7603fff8589ea267b91359 100644 --- a/ACL_PyTorch/built-in/cv/Yolov5_for_Pytorch/modify_model.py +++ b/ACL_PyTorch/built-in/cv/Yolov5_for_Pytorch/modify_model.py @@ -28,7 +28,7 @@ def main(args): yolo_coord, yolo_obj, yolo_classes = [], [], [] yolo_node = [] yolo_num = 3 - class_num = 80 + cls_num = args.class_num boxes = 3 coords = 4 @@ -40,18 +40,16 @@ def main(args): crd_align_len = ceil_x(f_h * f_w * 2 + 32, 32) // 2 obj_align_len = ceil_x(boxes * f_h * f_w * 2 + 32, 32) // 2 - yolo_coord.append( - helper.make_tensor_value_info(f"yolo{i}_coord", onnx.TensorProto.FLOAT, [bs, boxes * coords, crd_align_len])) + yolo_coord.append(helper.make_tensor_value_info(f"yolo{i}_coord", onnx.TensorProto.FLOAT, [bs, boxes * coords, crd_align_len])) yolo_obj.append(helper.make_tensor_value_info(f"yolo{i}_obj", onnx.TensorProto.FLOAT, [bs, obj_align_len])) - yolo_classes.append( - helper.make_tensor_value_info(f"yolo{i}_classes", onnx.TensorProto.FLOAT, [bs, class_num, obj_align_len])) + yolo_classes.append(helper.make_tensor_value_info(f"yolo{i}_classes", onnx.TensorProto.FLOAT, [bs, cls_num, obj_align_len])) yolo_node.append(helper.make_node('YoloPreDetection', inputs=[model.graph.output[i].name], outputs=[f"yolo{i}_coord", f"yolo{i}_obj", f"yolo{i}_classes"], boxes=boxes, coords=coords, - classes=class_num, + classes=cls_num, yolo_version='V5', name=f'yolo_{i}')) model.graph.node.append(yolo_node[i]) @@ -69,7 +67,7 @@ def main(args): outputs=['box_out', 'box_out_num'], boxes=boxes, coords=coords, - classes=class_num, + classes=cls_num, pre_nms_topn=1024, post_nms_topn=1024, relative=1, @@ -77,9 +75,7 @@ def main(args): obj_threshold=args.conf_thres, score_threshold=args.conf_thres, iou_threshold=args.iou_thres, - biases=[10., 13, 16, 30, 33, 23, 30, 61, 62, 45, 59, 119, 116, 90, 156, 198, - 373, - 326], + biases=args.anchors, name='YoloV5DetectionOutput_1') # add input and output @@ -102,5 +98,7 @@ if __name__ == '__main__': parser.add_argument('--batch-size', type=int, default=1, help='batch size') parser.add_argument('--conf-thres', type=float, default=0.4, help='object confidence threshold') parser.add_argument('--iou-thres', type=float, default=0.5, help='IOU threshold for NMS') + parser.add_argument('--class-num', type=int, default=80, help='class num') + parser.add_argument('--anchors', type=float, nargs='+', default=[10., 13, 16, 30, 33, 23, 30, 61, 62, 45, 59, 119, 116, 90, 156, 198, 373, 326], help='anchors') flags = parser.parse_args() main(flags)