yolov5支持动态batch_size、插入nms节点

文章讲述了如何使用Python库如`importonnx`和`graphsurgeonasgs`在Yolov5的QAT.onnx模型中实现动态batchsize和NMS功能,以增强模型的灵活性和性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import onnx
import onnx_graphsurgeon as gs
import numpy as np

# 增加class_names和动态batchsize
labels = ['mouse']
names = {cls_id: label for cls_id, label in enumerate(labels)}

model = onnx.load("/wjr/develop/projects/yolov5/qat.onnx")

meta = model.metadata_props.add()
meta.key, meta.value = "names", str(names)

graph = model.graph
graph.input[0].type.tensor_type.shape.dim[0].dim_param = 'None'
onnx.save(model, f'/wjr/develop/projects/yolov5/qat2.onnx')


# 插入nms节点
n_cls = 1
# 1.加载模型
graph = gs.import_onnx(onnx.load("/wjr/develop/projects/yolov5/qat2.onnx"))


# 首先将b*n*(4+n_cls)的输出split成b*n*1*4和b*n*n_cls两个部分
# 定义split节点
split = gs.Constant("split", values=np.array([4, n_cls], dtype=np.int64))
output_box_0 = gs.Variable(
    name="output_box_0", shape=(1, 25500, 4), dtype=np.float32)
output_scores = gs.Variable(
    name="output_scores", shape=(1, 25500, n_cls), dtype=np.float32)
split_node = gs.Node(
    op="Split",
    inputs=[graph.outputs[0], split],
    outputs=[output_box_0, output_scores],
    attrs={"axis": 2}
)

# box reshape,增加一个维度
box_shape = gs.Constant(
    "shape", values=np.array([1, 25500, 1, 4], dtype=np.int64))
output_boxes = gs.Variable(
    name="output_boxes", shape=(1, 25500, 1, 4), dtype=np.float32)
# 增加reshape节点
reshape_node = gs.Node(
    op="Reshape", inputs=[output_box_0, box_shape], outputs=[output_boxes])

# 定义batchednms节点
# keepTopK最终保留的目标数,是batchednms节点的属性
# num_detections返回每个输入检测到的目标数
keepTopK = 100
topK = 1000
num_detections = gs.Variable(
    name="num_detections", dtype=np.int32, shape=[1])
# nmsed_boxes返回每个输入检测到box坐标
nmsed_boxes = gs.Variable(name="nmsed_boxes", dtype=np.float32, shape=[
                          1, keepTopK, 4])
# nmsed_scores返回每个输入检测到的box对应的score
nmsed_scores = gs.Variable(name="nmsed_scores",
                           dtype=np.float32, shape=[1, keepTopK])
# nmsed_classes返回每个输入检测到的box对应的类别id
nmsed_classes = gs.Variable(name="nmsed_classes",
                            dtype=np.float32, shape=[1, keepTopK])

new_outputs = [num_detections, nmsed_boxes, nmsed_scores, nmsed_classes]
# 创建nms节点
# 首先定义nms节点的属性
attrs = {}
attrs["shareLocation"] = False # nms不同类别box是否统一处理
attrs["backgroundLabelId"] = -1  # 背景类id,没有背景则设置为-1
attrs["numClasses"] = n_cls
attrs["topK"] = topK    # number of bounding boxes for nms eg 1000s
attrs["keepTopK"] = keepTopK # bounding boxes to be kept per image eg 20
attrs["scoreThreshold"] = 0.50 #0.70
attrs["iouThreshold"] = 0.7 
attrs["isNormalized"] = False   # 输入box坐标是否经过归一化
attrs["clipBoxes"] = False      # 当isNormalized为True时才生效,对box做clip处理
attrs['scoreBits'] = 16
# attrs["plugin_version"] = "1"
# attrs["caffeSemantics"] = True

nms_node = gs.Node(
    op="BatchedNMSDynamic_TRT",   # 不能使用BatchedNMS_TRT,不支持动态batch size
    attrs=attrs,
    inputs=[output_boxes, output_scores],
    outputs=new_outputs
)

# 将节点插入到nodes列表中
graph.nodes.extend([split_node, reshape_node, nms_node])
# 更新graph的输出
graph.outputs = new_outputs

graph.cleanup().toposort()
onnx.save(gs.export_onnx(graph), "/wjr/develop/projects/yolov5/qat3.onnx")

关于 YOLOv11 模型中的默认 `batch_size` 配置,虽然当前引用并未直接提及 YOLOv11 的具体参数配置[^1],但从常见的 YOLO 系列模型实践来看,默认的批量大小通常取决于硬件资源以及具体的实现版本。 在官方文档或其他常见实现中,YOLO 系列模型(如 YOLOv3、YOLOv5YOLOv8)的默认 `batch_size` 值通常是 **16 或 32**。这是因为这些值能够在大多数 GPU 上提供良好的性能平衡,既不会因为过小而影响收敛速度,也不会因过大而导致显存不足[^2]。 然而,在实际应用中,如果使用的是分布式数据并行(DDP),则可能需要调整 `batch_size` 来适应多卡训练场景下的总批处理量。例如: ```python # 计算总的 batch size total_batch_size = per_gpu_batch_size * num_gpus ``` 对于特定环境(Python 3.6, CUDA 10.0, cuDNN 7.6.4),建议验证所使用的框架支持的最大显存占用情况,并据此调整合适的 `batch_size` 参数[^3]。 以下是基于上述分析的一个代码片段示例,用于动态计算适合的 `batch_size` 并启动训练过程: ```python import torch def calculate_effective_batch_size(per_gpu_batch_size, num_gpus): return per_gpu_batch_size * num_gpus num_gpus = torch.cuda.device_count() per_gpu_batch_size = 16 # 默认单卡 batch size effective_batch_size = calculate_effective_batch_size(per_gpu_batch_size, num_gpus) print(f"Using effective batch size: {effective_batch_size}") torch.distributed.init_process_group(backend='nccl') ``` ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值