[2024_08_12日志]ONNX Runtime的使用

问题:Segmentation 错误。在 C++ API 上使用自定义 onnx 模型运行。模型在 Python 上按预期工作,但在 C++ API 上运行相同的模型时,会收到一个分段错误

python的模型代码如下:

class Facenet(nn.Module):
    def __init__(self, backbone="mobilenet", dropout_keep_prob=0.5, embedding_size=128, num_classes=None, pretrained=False):
        super(Facenet, self).__init__()
        if backbone == "mobilenet":
            self.backbone = mobilenet(pretrained)
            flat_shape = 1024
        elif backbone == "inception_resnetv1":
            self.backbone = inception_resnet(pretrained)
            flat_shape = 1792
        else:
            raise ValueError('Unsupported backbone - `{}`, Use mobilenet, inception_resnetv1.'.format(backbone))
        # 自适应平均池化层 参数(1, 1)表示输出的目标尺寸为1x1
        self.avg = nn.AdaptiveAvgPool2d((1, 1))
        # 正则化技术,用于减少深度神经网络中的过拟合问题,以一定的概率(通常在0.5到0.8之间)随机选择一些隐藏层神经元,并将其输出置为零
        self.Dropout = nn.Dropout(1 - dropout_keep_prob)  # 仅在训练时有用,防止模型的过拟合
        # 全连接层作为模型的Bottleneck层 (flat_shape该层的输入维度大小、embedding_size该层的输出维度大小、bias是否使用偏置项)
        # 将输入的特征向量从flat_shape维度变换为embedding_size维度的向量
        self.Bottleneck = nn.Linear(flat_shape, embedding_size, bias=False)
        # 进行标准化处理。使得每一层网络的输入分布保持相同的均值和方差,从而加速网络收敛并提高模型泛化能力
        self.last_bn = nn.BatchNorm1d(embedding_size, eps=0.001, momentum=0.1, affine=True)

    def forward(self, x, mode="predict"):
        x = self.backbone(x)
        x = self.avg(x)
        # reshape,将其变为一个二维张量,其中第一维大小为原始张量的batch_size,第二维大小为剩余维度的乘积
        x = x.view(x.size(0), -1)
        x = self.Dropout(x)
        x = self.Bottleneck(x)
        x = self.last_bn(x)
        x = F.normalize(x, p=2, dim=1)  # l2标准化
        return x

    def forward_feature(self, x):
        x = self.backbone(x)
        x = self.avg(x)
        x = x.view(x.size(0), -1)
        x = self.Dropout(x)
        x = self.Bottleneck(x)
        before_normalize = self.last_bn(x)
        x = F.normalize(before_normalize, p=2, dim=1)
        return before_normalize, x

    def forward_classifier(self, x):
        x = self.classifier(x)
        return x

导出onnx文件后,计划使用ONNX Runtime C++ API进行模型的部署、推理

部分代码如下:

#include <iostream>
#include <vector>
#include <onnxruntime/core/session/onnxruntime_cxx_api.h>
using namespace std;
using namespace Ort;


namespace imageHandle
{
    class ImageHandler
    {
    public:
        ImageHandler():
            _memoryInfo(MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault))
        {
            Env env(ORT_LOGGING_LEVEL_ERROR, "ONNXRuntime")
            
            // 创建 ONNX Runtime 会话选项
            SessionOptions sessionOptions;
            sessionOptions.SetIntraOpNumThreads(2);  // 设置内部操作的线程数
            sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);  // 设置图优化级别

            // 加载 ONNX 模型
            const string modelPath = "/home/bjy/FaceRecSysOnnx/HandleServer/models/inception_resnerv1/inception_resnerv1.onnx";
            _session = new Session(env, modelPath.c_str(), sessionOptions);


            //...
        }
    };
}

出现类似下面的段错误(gdb调试core文件可见)

 onnxruntime::logging::LoggingManager::Log(std::string const&, onnxruntime::logging::Capture const&) const (in /home/palermo/Programing_Workspace/TeseMestrado/na_high_evel/src/extra/onnxruntime/lib/libonnxruntime.so.1.5.2)

Segmentation Fault on session.Run() with custom model on c++ API · Issue #5630 · microsoft/onnxruntime · GitHubicon-default.png?t=N7T8https://github.com/microsoft/onnxruntime/issues/5630

误以为env的作用仅仅是注册会话,导致编写时将其仅仅作为一个构造函数中的局部变量,实际上需维护到不再进行推理(参考上面的issue可知)

修改后代码:

#include <iostream>
#include <vector>
#include <onnxruntime/core/session/onnxruntime_cxx_api.h>
using namespace std;
using namespace Ort;


namespace imageHandle
{
    class ImageHandler
    {
    public:
        ImageHandler():
            _env(Env(ORT_LOGGING_LEVEL_ERROR, "ONNXRuntime")),// 初始化 ONNX Runtime 环境
            _memoryInfo(MemoryInfo::CreateCpu(OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault))
        {
            // 创建 ONNX Runtime 会话选项
            SessionOptions sessionOptions;
            sessionOptions.SetIntraOpNumThreads(2);  // 设置内部操作的线程数
            sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);  // 设置图优化级别

            // 加载 ONNX 模型
            const string modelPath = "/home/bjy/FaceRecSysOnnx/HandleServer/models/inception_resnerv1/inception_resnerv1.onnx";
            _session = new Session(_env, modelPath.c_str(), sessionOptions);

            //...
        }
    };
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GG_Bond20

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值