Digital2Slave / ncnn-android-yolov8-seg

a sample yolov8 object segment android project based on ncnn and opencv.
63 stars 8 forks source link

How to set up yolov9c-seg.pt custom model to run on ncnn-android-yolov8-seg #12

Open greg007-web opened 1 month ago

greg007-web commented 1 month ago

I performed the process with the YOLOv8 model and the custom YOLOv9 model using Ultralytics 8.YOLOv8.2.31. The YOLOv8 model worked fine, but the YOLOv9 did not.

Does it have anything to do with this:

WARNING ⚠️ /content/yolov9c-seg.pt appears to require 'dill', which is not in ultralytics requirements. AutoInstall will run now for 'dill' but this feature will be removed in the future. Recommend fixes are to train a new model using the latest 'ultralytics' package or to run a command with an official YOLOv8 model, i.e. 'yolo predict model=yolov8n.pt' requirements: Ultralytics requirement ['dill'] not found, attempting AutoUpdate... Collecting dill Downloading dill-0.3.8-py3-none-any.whl (116 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 116.3/116.3 kB 5.0 MB/s eta 0:00:00 Installing collected packages: dill Successfully installed dill-0.3.8

Thanks for support.

greg007-web commented 2 weeks ago

Actually, I had issues with versions above 8.0.196 when implementing the model on Android. However, with this modification (nn.module.head.py) during the model conversion to ONNX, I no longer had problems (8.2.45 last version until today), and I can use yolov9 model:

class Segment(Detect):
    """YOLOv8 Segment head for segmentation models."""

    def __init__(self, nc=80, nm=32, npr=256, ch=()):
        """Initialize the YOLO model attributes such as the number of masks, prototypes, and the convolution layers."""
        super().__init__(nc, ch)
        self.nm = nm  # number of masks
        self.npr = npr  # number of protos
        self.proto = Proto(ch[0], self.npr, self.nm)  # protos

        c4 = max(ch[0] // 4, self.nm)
        self.cv4 = nn.ModuleList(nn.Sequential(Conv(x, c4, 3), Conv(c4, c4, 3), nn.Conv2d(c4, self.nm, 1)) for x in ch)

    def forward(self, x):
        """Return model outputs and mask coefficients if training, otherwise return outputs and mask coefficients."""
        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 = super().forward(x)
        if self.training:
            return x, mc, p
        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))