-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Open
Description
问题描述
在我对自己训练的yolov11-n ncnn模型进行int8量化后,int8模型推理图像出现了目标框不准的问题,我执行了以下命令进行模型量化:
../ncnnoptimize yolov11n.param yolov11n.bin yolov11n_opt.param yolov11n_opt.bin 0
../quantize/ncnn2table yolov11_opt.param yolov11_opt.bin data.txt yolov11n.table mean=[104,117,123] norm=[0.017,0.017,0.017] shape=[640,640,3] pixel=BGR thread=8 method=kl
../quantize/ncnn2int8 yolov11n_opt.param yolov11n_opt.bin yolov11n-int8.param yolov11n-int8.bin yolov11n.table
为了对比yolov11n和yolov11n-int8 ncnn模型的检测效果,我执行了以下代码:
import numpy as np
import ncnn
import torch
from ultralytics.data.augment import LetterBox
from ultralytics.engine.results import Results
from ultralytics.utils import ops
from PIL import Image
import cv2
def test_inference(image_path):
im = cv2.imread(image_path)
ori_img_shape = im.shape[:2]
new_shape = (640, 640)
pre_tranform = LetterBox(new_shape=(640,640), auto=False, stride=32)
resized_image = pre_tranform(image=im)
resized_image = resized_image[..., ::-1].transpose((2, 0, 1)) # BGR to RGB, BHWC to BCHW, (n, 3, h, w)
resized_image = np.ascontiguousarray(resized_image)
image_normalized = resized_image / 255.0
image_normalized = image_normalized.astype(np.float32)
outs = []
with ncnn.Net() as net:
net.load_param("runs/detect/vstd_yolov11/v1.1/weights/best_ncnn_model/yolov11n-int8.param")
net.load_model("runs/detect/vstd_yolov11/v1.1/weights/best_ncnn_model/yolov11n-int8.bin")
net.opt.use_int8_inference = True
with net.create_extractor() as ex:
ex.input("in0", ncnn.Mat(image_normalized).clone())
# ex.input("in0", ncnn.Mat(image_normalized).clone())
_, out0 = ex.extract("out0")
outs.append(torch.from_numpy(np.array(out0)).unsqueeze(0))
out = outs[0]
out_mean = torch.mean(out)
out_max = torch.max(out)
out_min = torch.min(out)
print(out.shape, out_mean, out_max, out_min)
# 后处理
classes_name = ["person", "biycle", "car", "motorcycle", "bus", "truck"]
pred = ops.non_max_suppression(
out,
0.5,
0.5,
agnostic=False,
max_det=300
)[0]
pred[:, :4] = ops.scale_boxes(new_shape, pred[:, :4], ori_img_shape)
r = Results(im, path=image_path, names=classes_name, boxes=pred)
r.save(filename=f"datasets/000000001532_int8.jpg", line_width=2)
print(pred)
if __name__ == "__main__":
image_path = "/data/object_detection/coco2017/000000001532.jpg"
test_inference(image_path)
以下是模型的推理结果,上图是float32的效果,下图是int8的效果:
请问这种量化误差过大的问题如何解决?我目前没啥头绪,期待回复!
Metadata
Metadata
Assignees
Labels
No labels