Yolov11-n 模型int8量化误差过大
问题描述
在我对自己训练的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的效果:
请问这种量化误差过大的问题如何解决?我目前没啥头绪,期待回复!
你这个是mean norm参数传错了吧,yolo的mean=0, norm=1/255=0.0039
我用methd=kl 一个框结果成了六个框还不对,改成method=aciq,结果正确了
hi, ncnn yolo11 examples are on board https://github.com/Tencent/ncnn/tree/master/examples https://github.com/nihui/ncnn-android-yolo11
model conversion guide (zh) https://zhuanlan.zhihu.com/p/1903414797195781701
为啥我yolov8量化完,模型bin大小是变成原来1/4了,但是推理速度变慢了,精度也不行了,是不是哪里量化的不对呀,能分享一下你的量化后模型吗
标题: ncnn2int8量化时出现“Floating point exception (core dumped)”求助
内容: 大家好, 我在使用ncnn对YOLO模型进行量化时,执行以下命令:
./ncnn2int8 yolo11n.ncnn-opt.param yolo11n.ncnn-opt.bin yolo11n-int8.param yolo11n-int8.bin yolo11n.ncnn.table
运行到某些卷积层时,出现报错:
quantize_convolution conv_80 quantize_convolutiondepthwise convdw_174 ... Floating point exception (core dumped)
我已经检查过table文件和param/bin文件都是有效的。 不清楚为什么会出现floating point错误。 请问有谁对ncnn2int8量化有经验,能帮我分析原因并给出解决方法吗?
非常感谢!