Libtorch前向推理

Libtorch前向推理

  • 前言
  • 使用流程
  • 我的环境
  • 模型转换
  • 前向推理代码

前言

  • 初次使用Libtorch做前向推理,如有不足请各位指正。
  • 在使用Libtorch做retinaface算法前向推理时发现不可以使用python训练时保存的是pth文件,报如下错误:
terminate called after throwing an instance of 'c10::Error'
  what():  [enforce fail at inline_container.cc:143] . PytorchStreamReader failed reading zip archive: failed finding central directory
  • 参看这篇文章windows实现libtorch推理行人重识别PCB,需要做一次模型转换得到libtorch可以使用的模型,顺利解决问题

使用流程

  • 模型转换->读取模型文件->前处理->使用前处理数据创建libtorch张量->libtorch前向推理->获取推理结果->后处理

我的环境

  • libtorch:1.4.0+cpu
  • Python 3.5.2
  • pytorch 1.1.0

模型转换

  • 我测试使用的是retinaface算法,参照的是Pytorch_Retinaface 这个工程,先clone这个工程,并下载对应的模型文件
  • 在Pytorch_Retinaface创建转换脚本,代码如下:
from torchvision import models
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from models.retinaface import RetinaFace
from torchvision import datasets, transforms
from PIL import Image
from torch.jit import ScriptModule, script_method, trace
import time
import cv2 as cv


cfg_mnet = {
    'name': 'mobilenet0.25',
    'min_sizes': [[16, 32], [64, 128], [256, 512]],
    'steps': [8, 16, 32],
    'variance': [0.1, 0.2],
    'clip': False,
    'loc_weight': 2.0,
    'gpu_train': True,
    'batch_size': 32,
    'ngpu': 1,
    'epoch': 250,
    'decay1': 190,
    'decay2': 220,
    'image_size': 640,
    'pretrain': True,
    'return_layers': {'stage1': 1, 'stage2': 2, 'stage3': 3},
    'in_channel': 32,
    'out_channel': 64
}

# device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
device = "cpu"
print(device)

model = RetinaFace(cfg=cfg_mnet, phase = 'test')

checkpoint = torch.load(r"./weights/mobilenet0.25_Final.pth")
model.load_state_dict(checkpoint)
model = model.to(device)
model.eval()  # 这句必须要加上,将模型设为eval

# for param in model.parameters():
#         param.requires_grad = False # 如果出现了c++中显存占用比python中很多的情况,转换模型的时候加上这两句话

example = torch.rand(1, 3, 320, 320)
#example = load_img(path) 
example = example.to(device)
#print(example)
print(example.shape)
trace_script_module = torch.jit.trace(model, example)
output = trace_script_module(example)
#print(trace_script_module)
trace_script_module.save(r"./retina_face_libtorch_cpu.pt")
print(output)
  • 执行上述模型转换脚本,我们便可以得到./retina_face_libtorch_cpu.pt文件

前向推理代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "dtk_retina_face_com.h"

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    //读取图片
    const char* image_path = "../image/lenna.jpg";
    cv::Mat image = cv::imread(image_path);
    if (image.empty())
    {
        fprintf(stderr, "cv::imread %s failed\n", image_path);
        return -1;
    }

    //图片前处理
    DtkPreInfo_t pre_info;
    cv::Mat input_mat = PreProcessing(image, pre_info);
    if (input_mat.empty())
    {
        std::cout << "PreProcessing image is empty!" << std::endl;
        return -1;
    }

    //1.读取模型文件
    std::string  model_file = "/home/damon/Pytorch_Retinaface/retina_face_libtorch_cpu.pt";
    torch::jit::script::Module module = torch::jit::load(model_file);

    //2.使用前处理数据创建libtorch张量inputs.
    torch::TensorOptions option(torch::kFloat32);
    auto img_tensor = torch::from_blob(input_mat.data, { 1, 3, input_mat.rows, input_mat.cols}, option);// opencv H x W x C  torch C x H x W
    std::vector inputs;
    inputs.push_back(img_tensor);

    //3.前向推理,返回有多个值不能用toTensor()获取结果,需要用toTuple()获取结果
    auto output = module.forward(inputs).toTuple();

    //4.获取推理结果
    torch::Tensor out0 = output->elements()[0].toTensor();
    torch::Tensor out1 = output->elements()[1].toTensor();
    torch::Tensor out2 = output->elements()[2].toTensor();

	/*
	* 5.后处理
	*/
    return 0;
}

你可能感兴趣的:(前向推理)