转换模型时遇到“Unsupported slice step!”

在将 YOLOv5 模型从 ONNX 转换为模型时遇到“Unsupported slice step!”错误,这通常是因为 当前不支持某些特定的 ONNX 操作或参数配置,尤其是带有非标准切片步长的操作。

解决方案

  1. 修改模型或代码:

    • 尝试修改模型中的切片操作,使其使用 支持的步长(通常是步长为1)。
    • 检查 YOLOv5 的代码,特别是数据预处理或网络结构中的切片操作,调整这些操作以兼容 。
  2. 使用 ONNX Simplifier:

    • 尝试使用 ONNX Simplifier 来简化 ONNX 模型,这有时可以去除或替换不兼容的操作。
    pip install onnx-simplifier
    python -m onnxsim your_model.onnx simplified_model.onnx
    
  3. 手动调整 Focus模型r:

    • 使用 ONNX 图形编辑器(如 Netron)来检查并手动调整不兼容的操作。### 具体步骤
  4. 安装 ONNX Simplifier 并简化模型:

    pip install onnx-simplifier
    python -m onnxsim yolov5_model.onnx yolov5_model_simplified.onnx
    
  5. 转换为 NCNN 模型:

    onnx2ncnn yolov5_model_simplified.onnx yolov5_model.param yolov5_model.bin
    
  6. 手动调整 Focus模型:

models 文件夹下的 common.py 文件中找到并修改 Focus 类,以避免使用不受支持的 slice 步长。原始代码如下:

class Focus(nn.Module):
    # Focus wh information into c-space
    def __init__(self, c1, c2, k=1):
        super(Focus, self).__init__()
        self.conv = Conv(c1 * 4, c2, k, 1)

    def forward(self, x):  # x(b,c,w,h) -> y(b,4c,w/2,h/2)
        return self.conv(torch.cat([x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]], 1))

将上述代码修改为如下代码:

class Focus(nn.Module):
    # Focus wh information into c-space
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):  # ch_in, ch_out, kernel, stride, padding, groups
        super(Focus, self).__init__()
        self.conv = Conv(c1 * 4, c2, k, s, p, g, act)

        with torch.no_grad():
            self.conv1 = nn.Conv2d(c1, c1, (2, 2), groups=c1, bias=False, stride=(2, 2))
            self.conv1.weight[:, :, 0, 0] = 1
            self.conv1.weight[:, :, 0, 1] = 0
            self.conv1.weight[:, :, 1, 0] = 0
            self.conv1.weight[:, :, 1, 1] = 0

            self.conv2 = nn.Conv2d(c1, c1, (2, 2), groups=c1, bias=False, stride=(2, 2))
            self.conv2.weight[:, :, 0, 0] = 0
            self.conv2.weight[:, :, 0, 1] = 0
            self.conv2.weight[:, :, 1, 0] = 1
            self.conv2.weight[:, :, 1, 1] = 0

            self.conv3 = nn.Conv2d(c1, c1, (2, 2), groups=c1, bias=False, stride=(2, 2))
            self.conv3.weight[:, :, 0, 0] = 0
            self.conv3.weight[:, :, 0, 1] = 1
            self.conv3.weight[:, :, 1, 0] = 0
            self.conv3.weight[:, :, 1, 1] = 0

            self.conv4 = nn.Conv2d(c1, c1, (2, 2), groups=c1, bias=False, stride=(2, 2))
            self.conv4.weight[:, :, 0, 0] = 0
            self.conv4.weight[:, :, 0, 1] = 0
            self.conv4.weight[:, :, 1, 0] = 0
            self.conv4.weight[:, :, 1, 1] = 1

    def forward(self, x):  # x(b,c,w,h) -> y(b,4c,w/2,h/2)
        return self.conv(torch.cat([self.conv1(x), self.conv2(x), self.conv3(x), self.conv4(x)], 1))

这样做可以避免使用不受支持的 slice 操作,使模型更兼容 NCNN。完成上述修改后,重新将模型导出为 ONNX 格式,并再次尝试转换为 NCNN 格式。

实在解决不了可采用 自定义算子:
参考:
此博客

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值