Open zhouqingf opened 6 months ago
我目前遇到一个问题,使用官方的yolov8-seg.pt转的onnx 能够使用您的代码 ,但使用自己的pt无法实现,我预计是onnx转换的问题
看 readme 里的 转换教程
此图片是使用官方pt转换的,是能够运行
我这个是 seg 的不是检测的
但是自己的训练的模型就无法,我检测到自己pt转换之后的ONNX与官方的有明显的区别
上面哪个链接改了没, 链接里 算子的顺序 shape 是需要改动的,然后 类别数量要再代码里改
我把刚才的代码重新整理了一下 import torch from ultralytics import YOLO from ultralytics.nn.modules.block import C2f from ultralytics.nn.modules.head import Detect, Segment
from ultralytics.utils.tal import make_anchors
def forward1(self, x): x = self.cv1(x) x = [x, x[:, self.c:, ...]] x.extend(m(x[-1]) for m in self.m) x.pop(1) print("asfasf1111") return self.cv2(torch.cat(x, 1))
C2f.forward = forward1
def forward2(self, x): print("fasfsafasf2222222222222222asf") shape = x[0].shape # BCHW for i in range(self.nl): x[i] = torch.cat((self.cv2i, self.cv3i), 1) if self.training: return x elif self.dynamic or self.shape != shape: self.anchors, self.strides = (x.transpose(0, 1) for x in make_anchors(x, self.stride, 0.5)) self.shape = shape x_cat = torch.cat([xi.view(shape[0], self.no, -1) for xi in x], 2) return x_cat
Detect.forward = forward2
def forward3(self, x): p = self.proto(x[0]) # mask protos bs = p.shape[0] # batch size
mc = torch.cat([self.cv4[i](x[i]).view(bs, self.nm, -1) for i in range(self.nl)], 2) # mask coefficients
x = self.detect(self, x)
if self.training:
return x, mc, p
print("fasfsafasf3333333333333asf")
return (torch.cat([x, mc], 1).permute(0, 2, 1), p.view(bs, self.nm, -1)) if self.export else (
torch.cat([x[0], mc], 1), (x[1], mc, p))
Segment.forward = forward3
model = YOLO('best.pt')
success = model.export(format="onnx", opset=12, imgsz=640)
在转换onnx时,使用自己训练的pt文件,Detect.forward是没有被调用,而使用官方的pt文件转化时,Detect.forward是被调用了的
https://github.com/UnstoppableCurry/ncnn-android-yolov8-seg-Seal/blob/master/app/src/main/jni/yolo.cpp 类别数量对齐你自定义的模型
static void generate_proposals(std::vector
int Yolo::draw(cv::Mat& rgb, const std::vector
static const char* class_names[] = {
"Static Circle Seal",
"Dynamic 1 Triangle Seal",
"Dynamic 1 Circle Seal",
"Dynamic 2 Circle Seal",
"Dynamic 1 Elliptical Seal",
"Dynamic 1 Square Seal",
"Dynamic 2 Square Seal",
"Static Elliptical Seal",
"Dynamic Lozenge Seal",
"Static Square Seal",
"Dynamic 2 Triangle Seal",
};
// static const char* class_names[] = {"blur", "phone", "reflectLight", "reflection"}; static const unsigned char colors[12][3] = { {56, 0, 255}, {226, 255, 0}, {0, 94, 255}, {0, 37, 255}, {0, 255, 94}, {255, 226, 0}, {0, 18, 255}, {255, 151, 0}, {170, 0, 255}, {0, 255, 56}, {255, 0, 75}, {0, 75, 255},
};
模型 和配置文件发上来,我试试
我再重新训练一下
刚刚在原来的电脑上训练的,
你的pt label 字典4个类 但是配置文件80个,我 这eport 也不成功 正在debug 同版本的u train 和export 应该是一致的
from ultralytics import YOLO
model_big = YOLO(r'E:\workspace\pycharm\yolo\原版\ultralytics-main\runs\segment\mod\yolov8-seg.yaml').load(
r'E:\workspace\pycharm\yolo\原版\ultralytics-main\runs\segment\mod\last.pt')
success = model_big.export(format="onnx", opset=12, simplify=True) RUN E:\workspace\pycharm\v8env\Scripts\python.exe E:/workspace/pycharm/yolo/原版/ultralytics-main/1.py WARNING no model scale passed. Assuming scale='n'.
from n params module arguments
0 -1 1 464 ultralytics.nn.modules.conv.Conv [3, 16, 3, 2]
1 -1 1 4672 ultralytics.nn.modules.conv.Conv [16, 32, 3, 2]
2 -1 1 7360 ultralytics.nn.modules.block.C2f [32, 32, 1, True]
3 -1 1 18560 ultralytics.nn.modules.conv.Conv [32, 64, 3, 2]
4 -1 2 49664 ultralytics.nn.modules.block.C2f [64, 64, 2, True]
5 -1 1 73984 ultralytics.nn.modules.conv.Conv [64, 128, 3, 2]
6 -1 2 197632 ultralytics.nn.modules.block.C2f [128, 128, 2, True]
7 -1 1 295424 ultralytics.nn.modules.conv.Conv [128, 256, 3, 2]
8 -1 1 460288 ultralytics.nn.modules.block.C2f [256, 256, 1, True]
9 -1 1 164608 ultralytics.nn.modules.block.SPPF [256, 256, 5]
10 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
11 [-1, 6] 1 0 ultralytics.nn.modules.conv.Concat [1]
12 -1 1 148224 ultralytics.nn.modules.block.C2f [384, 128, 1]
13 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, 'nearest']
14 [-1, 4] 1 0 ultralytics.nn.modules.conv.Concat [1]
15 -1 1 37248 ultralytics.nn.modules.block.C2f [192, 64, 1]
16 -1 1 36992 ultralytics.nn.modules.conv.Conv [64, 64, 3, 2]
17 [-1, 12] 1 0 ultralytics.nn.modules.conv.Concat [1]
18 -1 1 123648 ultralytics.nn.modules.block.C2f [192, 128, 1]
19 -1 1 147712 ultralytics.nn.modules.conv.Conv [128, 128, 3, 2]
20 [-1, 9] 1 0 ultralytics.nn.modules.conv.Concat [1]
21 -1 1 493056 ultralytics.nn.modules.block.C2f [384, 256, 1]
22 [15, 18, 21] 1 1004470 ultralytics.nn.modules.head.Segment [2, 32, 64, [64, 128, 256]]
YOLOv8-seg summary: 261 layers, 3264006 parameters, 3263990 gradients
Transferred 411/417 items from pretrained weights Ultralytics YOLOv8.0.201 Python-3.9.12 torch-1.8.1+cu111 CPU (12th Gen Intel Core(TM) i7-12700F) YOLOv8-seg summary (fused): 195 layers, 3258454 parameters, 0 gradients
PyTorch: starting from 'yolov8-seg.yaml' with input shape (1, 3, 320, 320) BCHW and output shape(s) ((1, 2100, 98), (1, 32, 6400)) (0.0 MB)
ONNX: starting export with onnx 1.15.0 opset 12... ONNX: simplifying with onnxsim 0.4.35... ONNX: export success 1.4s, saved as 'yolov8-seg.onnx' (12.5 MB)
Export complete (5.3s)
Results saved to E:\workspace\pycharm\yolo\ultralytics-main
Predict: yolo predict task=segment model=yolov8-seg.onnx imgsz=320
Validate: yolo val task=segment model=yolov8-seg.onnx imgsz=320 data=None
Visualize: https://netron.app
nc: 2 # number of classes scales: # model compound scaling constants, i.e. 'model=yolov8n-seg.yaml' will call yolov8-seg.yaml with scale 'n'
n: [0.33, 0.25, 1024] s: [0.33, 0.50, 1024] m: [0.67, 0.75, 768] l: [1.00, 1.00, 512] x: [1.00, 1.25, 512]
backbone:
head:
[-1, 1, nn.Upsample, [None, 2, 'nearest']]
[[-1, 6], 1, Concat, [1]] # cat backbone P4
[-1, 3, C2f, [512]] # 12
[-1, 1, nn.Upsample, [None, 2, 'nearest']]
[[-1, 4], 1, Concat, [1]] # cat backbone P3
[-1, 3, C2f, [256]] # 15 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]]
[[-1, 12], 1, Concat, [1]] # cat head P4
[-1, 3, C2f, [512]] # 18 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]]
[[-1, 9], 1, Concat, [1]] # cat head P5
[-1, 3, C2f, [1024]] # 21 (P5/32-large)
[[15, 18, 21], 1, Segment, [nc, 32, 256]] # Segment(P3, P4, P5)
model = YOLO('best.pt')
之前先 load yaml ,类别对齐一下
谢谢大佬的帮助,类别对齐真的是没想到
ok
留下你的start~
类别对齐一下是指这样吗: model = YOLO('yolov8n-seg.yaml').load(f"runs/segment/yolov8n-seg/weights/best.pt") path = model.export(format="onnx", opset=12, simplify=True)
我现在用yolov8文档提到的那个crack-seg数据集来做,然后也是按照步骤修改代码然后转成ncnn,修改yolo.cpp中的类别为这样: static const char* class_names[] = { "crack", }; static const unsigned char colors[2][3] = { {56, 0, 255}, {226, 255, 0}, }; 发现检测出来的准确率中级差,现在不清楚是模型权重的问题还是哪一步出错了。
我的训练代码: model = YOLO('yolov8n-seg.yaml').load('yolov8n-seg.pt') results = model.train(data='datasets/crack-seg/data.yaml', epochs=100, imgsz=640, name='yolov8n-seg')
model = YOLO('yolov8n-seg.yaml').load('runs/segment/yolov8n-seg/weights/best.pt') path = model.export(format="onnx", opset=12, simplify=True)
类别对齐一下是指这样吗: model = YOLO('yolov8n-seg.yaml').load(f“runs/segment/yolov8n-seg/weights/best.pt”) path = model.export(format=“onnx”, opset=12, simplify=True)
我现在用yolov8文档提到的那个crack-seg数据集来做,然后也是按照步骤修改代码然后转成ncnn,修改yolo.cpp中的类别为这样: static const char* class_names[] = { “crack”, };静态常量无符号字符颜色[2][3] = { {56, 0, 255}, {226, 255, 0}, }; 发现检测出来的准确率中级差,现在不清楚是模型权重的问题还是哪一步出错了。
我的训练代码: model = YOLO('yolov8n-seg.yaml').load('yolov8n-seg.pt') results = model.train(data='datasets/crack-seg/data.yaml', epochs=100, imgsz=640, name='yolov8n-seg')
model = YOLO('yolov8n-seg.yaml').load('runs/segment/yolov8n-seg/weights/best.pt') 路径 = model.export(format=“onnx”, opset=12, simplify=True)
而且运行Android Studio时Logcat会提示错误E/cv::error(): OpenCV(4.6.0) Error: Assertion failed (!fixedSize()) in release, file /home/runner/work/opencv-mobile/opencv-mobile/opencv-4.6.0/modules/core/src/matrix_wrap.cpp, line 1667
model = YOLO('yolov8n-seg.yaml').load('runs/segment/yolov8n-seg/weights/best.pt') 路径 = model.export(format=“onnx”, opset=12, simplify=True) 这行代码在转换格式的时候,参照的是这个文件yolov8n-seg.yaml 这个文件如果你没有修改过的话 是有一定的问题,原有类别是80个,而你使用的数据crack-seg是单类别 你可以试试复制yolov8n-seg.yaml并把其中的80类别改为1,重新导出模型
我尝试了修改类别为1,然后修改block.py中class C2f(nn.Module)和修改head.py中class Segment(Detect)。 我发现我的class Detect(nn.Module)的代码跟https://github.com/Digital2Slave/ncnn-android-yolov8-seg/wiki/Convert-yolov8-model-to-ncnn-model这里提到的代码不太一样我就没有修改了。 这样导出的模型运行在你这个项目上,同时修改了代码中对应的类别的参数为1,但是运行会闪退,同时会提示错误E/cv::error(): OpenCV(4.6.0) Error: Assertion failed (!fixedSize()) in release, file /home/runner/work/opencv-mobile/opencv-mobile/opencv-4.6.0/modules/core/src/matrix_wrap.cpp, line 1667。
会不会是训练或者导出时有什么参数没设置好呢?
你需要先确认你的模型是目标侦测还是分割 目标侦测修改的内容与分割修改的内容是不一样的 分割的话需要修改三个部分 其中C2f与侦测一致 Detect的修改最后一步有一定的区别(换轴) 最后多一个Segment的修改 最后是在你导出ONNX格式时可视化,看看结构是否一致 你可以看上面的记录 一个是正常的 一个是错误的 当你的模型正确时,你再试试 闪退原因的话最好是仔细参考项目代码的修改
把权重发上来看一下就知道了。不过大家周末都在加班吗,都要睡了😄
非常感谢,我的问题解决了。
一开始是因为要修改class Detect,但是我文件中的Detect代码跟要修改的很不一样,我以为是不同的版本所有没有修改。后来直接替换为需要修改的后就可以了。
把权重发上来看一下就知道了。不过大家周末都在加班吗,都要睡了😄
在赶ddl了...
加油
?