Closed lishengyang30 closed 2 months ago
@lishengyang30 压缩包有问题,重新上传一下
@lishengyang30 压缩包有问题,重新上传一下
除了目标检测还有关键点检测,总共13个关键点,指针上三个点,其余是刻度值
除了目标检测还有关键点检测,总共13个关键点,指针上三个点,其余是刻度值
关键点预测的置信度很低,也有负值
根据你的模型结构,1x3x640x640输入,1xNx8400输出,没估计错的话是yolov8系列里的模型吧 如果是yolov8,那么它的输入格式应该是NCHW,RGB,取值直接从0-255映射到0-1
def preprocess(self, im):
"""
Prepares input image before inference.
Args:
im (torch.Tensor | List(np.ndarray)): BCHW for tensor, [(HWC) x B] for list.
"""
not_tensor = not isinstance(im, torch.Tensor)
if not_tensor:
im = np.stack(self.pre_transform(im))
im = im[..., ::-1].transpose((0, 3, 1, 2)) # BGR to RGB, BHWC to BCHW, (n, 3, h, w)
im = np.ascontiguousarray(im) # contiguous
im = torch.from_numpy(im)
im = im.to(self.device)
im = im.half() if self.model.fp16 else im.float() # uint8 to fp16/32
if not_tensor:
im /= 255 # 0 - 255 to 0.0 - 1.0
return im
code from ultralytic/engine/predictor.py , class BasePredictor 但是在你的代码中,首先缩放时没有用letterbox,不过这一点问题倒也不大
#生成的数据需要做的预处理 ≈ onnx预处理 - 根据预处理参数设置的,包含在kmodel中预处理
#onnx预处理:bgr,padding,reisze,transpose,normalization,dequantize,3维度转4维度
#kmodel中包含的预处理:rgb->bgr,dequantize,normalization
img_data = Image.open(img_paths[i]).convert('RGB')
#为了省事,这里没有用padding
img_data = img_data.resize((shape[3], shape[2]), Image.BILINEAR)
img_data = np.asarray(img_data, dtype=np.float32)
img_data = np.transpose(img_data, (2, 0, 1))
data.append([img_data[np.newaxis, ...]])
_code from onnx2kmodel.py , function generatedata 最大的问题在于模型预处理配置
compile_options.preprocess = False
if compile_options.preprocess:
compile_options.input_type = "float32" # "uint8" "float32"
compile_options.input_shape = [1,3, 640, 640]
compile_options.input_range = [0, 255]
compile_options.input_layout = "NCHW" # "NHWC"
compile_options.swapRB = True
compile_options.mean = [130.66777943, 122.26035665, 119.29115591]
compile_options.std = [57.31256191 ,56.19649718, 57.98391517]
compile_options.letterbox_value = 0
compile_options.output_layout = "NCHW" # "NHWC"
_code from onnx2kmodel.py , function compilekmodel
首先,preprocess置为False,预处理被关闭了,之后的配置将不会生效; 其次,即使preprocess=True,input_type="float32"会对模型部署造成不便,虽然在加载校准集时将uint8转为float32也可以完成编译,不会报错,但会导致推理之前必须从uint8到float32进行强制类型转换,消耗端侧CPU时间; 然后,swapRB=True,这是完全不必要也不能要的,图片读取时默认就是RGB顺序,YoloV8的Channel维度也是RGB顺序,一致,不要交换; 最后,归一化参数不当,归一化运算公式为(data-Mean)/Std,所以,要么把mean全部置0,std全部置255,从而映射到0-1,要么在input_type=uint8的前提下把mean全部置0,std全部置1,指定input_range=[0,1]即可自动映射
镜像文件:CanMV-K230_micropython_v0.7_sdk_v1.6_nncase_v2.8.3.img.gz 编译 compile_options.preprocess = False Uploading issue.zip…
在pc上使用int16精度onnx和kmodel相似度达到98.9%,校正集是内存连续的,但是在k230上
kmodel
进行目标检测计算出框的坐标混乱,不准去,甚至有负值
另外,98.9%对于yolo而言很低。yolo需要输出0-640的坐标,即使把后面0-1的置信度抹没了都能有95%以上的相似度,我这测试时99.9999%都有明显的精度损失(但还算好使)
你判断内存是否连续的地方都错了 测试来看数据是不连续的
从 @PermissionDenied7335 截图的第一段代码中也能看到,官方都是会进行numpy连续性重排的
@lishengyang30 更新后的代码
def generate_data(shape, batch, calib_dir):
#获取所有校正集图片名称
img_paths = [os.path.join(calib_dir, p) for p in os.listdir(calib_dir)]
data = []
for i in range(batch):
assert i < len(img_paths), "calibration images not enough."
#生成的数据需要做的预处理 ≈ onnx预处理 - 根据预处理参数设置的,包含在kmodel中预处理
#onnx预处理:bgr,padding,reisze,transpose,normalization,dequantize,3维度转4维度
#kmodel中包含的预处理:rgb->bgr,dequantize,normalization
img_data = Image.open(img_paths[i]).convert('RGB')
#为了省事,这里没有用padding
img_data = img_data.resize((shape[3], shape[2]), Image.BILINEAR)
img_data = np.asarray(img_data, dtype=np.float32)
img_data = np.transpose(img_data, (2, 0, 1))
print(f"C-contiguous: {img_data.flags['C_CONTIGUOUS']}")
img_data=np.ascontiguousarray(img_data)
print(f"C-contiguous: {img_data.flags['C_CONTIGUOUS']}")
data.append([img_data[np.newaxis, ...]])
这个函数代码不全,自己补一下
你判断内存是否连续的地方都错了 测试来看数据是不连续的
从 @PermissionDenied7335 截图的第一段代码中也能看到,官方都是会进行numpy连续性重排的
首先表示感谢,没有想到在那个地方就要连续性重拍,只想到append之后连续性重排就行了,在AI demo实例上没有看到连续性重排,是image.Image读取单个图片的时候或者pl.get_frame时,已经默认是连续的的了?
根据你的模型结构,1x3x640x640输入,1xNx8400输出,没估计错的话是yolov8系列里的模型吧 如果是yolov8,那么它的输入格式应该是NCHW,RGB,取值直接从0-255映射到0-1
def preprocess(self, im): """ Prepares input image before inference. Args: im (torch.Tensor | List(np.ndarray)): BCHW for tensor, [(HWC) x B] for list. """ not_tensor = not isinstance(im, torch.Tensor) if not_tensor: im = np.stack(self.pre_transform(im)) im = im[..., ::-1].transpose((0, 3, 1, 2)) # BGR to RGB, BHWC to BCHW, (n, 3, h, w) im = np.ascontiguousarray(im) # contiguous im = torch.from_numpy(im) im = im.to(self.device) im = im.half() if self.model.fp16 else im.float() # uint8 to fp16/32 if not_tensor: im /= 255 # 0 - 255 to 0.0 - 1.0 return im
code from ultralytic/engine/predictor.py , class BasePredictor 但是在你的代码中,首先缩放时没有用letterbox,不过这一点问题倒也不大
#生成的数据需要做的预处理 ≈ onnx预处理 - 根据预处理参数设置的,包含在kmodel中预处理 #onnx预处理:bgr,padding,reisze,transpose,normalization,dequantize,3维度转4维度 #kmodel中包含的预处理:rgb->bgr,dequantize,normalization img_data = Image.open(img_paths[i]).convert('RGB') #为了省事,这里没有用padding img_data = img_data.resize((shape[3], shape[2]), Image.BILINEAR) img_data = np.asarray(img_data, dtype=np.float32) img_data = np.transpose(img_data, (2, 0, 1)) data.append([img_data[np.newaxis, ...]])
_code from onnx2kmodel.py , function generatedata 最大的问题在于模型预处理配置
compile_options.preprocess = False if compile_options.preprocess: compile_options.input_type = "float32" # "uint8" "float32" compile_options.input_shape = [1,3, 640, 640] compile_options.input_range = [0, 255] compile_options.input_layout = "NCHW" # "NHWC" compile_options.swapRB = True compile_options.mean = [130.66777943, 122.26035665, 119.29115591] compile_options.std = [57.31256191 ,56.19649718, 57.98391517] compile_options.letterbox_value = 0 compile_options.output_layout = "NCHW" # "NHWC"
_code from onnx2kmodel.py , function compilekmodel
首先,preprocess置为False,预处理被关闭了,之后的配置将不会生效; 其次,即使preprocess=True,input_type="float32"会对模型部署造成不便,虽然在加载校准集时将uint8转为float32也可以完成编译,不会报错,但会导致推理之前必须从uint8到float32进行强制类型转换,消耗端侧CPU时间; 然后,swapRB=True,这是完全不必要也不能要的,图片读取时默认就是RGB顺序,YoloV8的Channel维度也是RGB顺序,一致,不要交换; 最后,归一化参数不当,归一化运算公式为(data-Mean)/Std,所以,要么把mean全部置0,std全部置255,从而映射到0-1,要么在input_type=uint8的前提下把mean全部置0,std全部置1,指定input_range=[0,1]即可自动映射
回答很详细,十分感谢,对于归一化我还有疑问,input_range和均值、方差的设定有关系吗?官方文档上有一句话:人脸检测kmodel实际输入从sensor中获取,数据类型为 uint8 ,所以input_type = 'uint8',input_range = [0,255]或[0,1]均可。
有关系的,传感器的uint8数据先根据input_range映射到float32,再根据mean和std归一化
你判断内存是否连续的地方都错了 测试来看数据是不连续的 从 @PermissionDenied7335 截图的第一段代码中也能看到,官方都是会进行numpy连续性重排的
首先表示感谢,没有想到在那个地方就要连续性重拍,只想到append之后连续性重排就行了,在AI demo实例上没有看到连续性重排,是image.Image读取单个图片的时候或者pl.get_frame时,已经默认是连续的的了?
之前没怎么出现过这种问题,不确定是不是因为numpy或者PIL版本导致,加上肯定是没啥问题的
使用onnx,框的位置和关键点的位置都没有问题,但是转换kmodel时,可以识别物体,框的位置正确,但是关键点的位置错误,有负值
先关闭量化,生成cpu模型,用模拟器跑出来看有没有问题
使用onnx,框的位置和关键点的位置都没有问题,但是转换kmodel时,可以识别物体,框的位置正确,但是关键点的位置错误,有负值
问题有解决么,你的场景应该都是上面这种仪器吧? 校正集如果都是这种比较统一的 quant_method 就用NoClip 试试
镜像文件:CanMV-K230_micropython_v0.7_sdk_v1.6_nncase_v2.8.3.img.gz 编译 compile_options.preprocess = False [Uploading issue.zip…]()
在pc上使用int16精度onnx和kmodel相似度达到98.9%,校正集是内存连续的,但是在k230上
kmodel
进行目标检测计算出框的坐标混乱,不准去,甚至有负值