pytorch回転ncnnおよびそのテスト

3657 ワード

本文は主にpytorchがncnnを回転する過程とその推理結果の正確性テストを説明する.
ここで、モデル変換は次の2つのステップに分けられる:1.pytorchモデルonnxモデルを回転する;2.onnxモデルはncnnモデルを回転します.
       onnx(https://github.com/onnx/onnx)はオープンニューラルネットワーク交換のフォーマットであり、モデルを異なるフレームワーク間で変換することができる.
一、pytorchモデル転onnxモデル
pytorchが持参したresnet 18を例として、コードは以下の通りである.
import torch
import torchvision

#define resnet18 model
model = torchvision.models.resnet18(pretrained=True)
#define input shape
x = torch.rand(1, 3, 224, 224)
#define input and output nodes, can be customized
input_names = ["x"]
output_names = ["y"]
#convert pytorch to onnx
torch_out = torch.onnx.export(model, x, "resnet18.onnx", input_names=input_names, output_names=output_names)

これにより、変換後のresnet 18が得る.onnxモデル.
pytorchモデルとonnxモデルの推論結果が一致するかどうかをテストします.コードは次のとおりです.
import torch
import torchvision
import onnxruntime as rt
import numpy as np
import cv2

#test image
img_path = "test.jpg"
img = cv2.imread(img_path)
img = cv2.resize(img, (224, 224))
img = np.transpose(img, (2, 0, 1)).astype(np.float32)
img = torch.from_numpy(img)
img = img.unsqueeze(0)

#pytorch test
model = torchvision.models.resnet18(pretrained=True)
model.eval()
output = model.forward(img)
val, cls = torch.max(output.data, 1)
print("[pytorch]--->predicted class:", cls.item())
print("[pytorch]--->predicted value:", val.item())

#onnx test
sess = rt.InferenceSession("resnet18.onnx")
x = "x"
y = ["y"]
output = sess.run(y, {x : img.numpy()})
cls = np.argmax(output[0][0], axis=0)
val = output[0][0][cls]
print("[onnx]--->predicted class:", cls)
print("[onnx]--->predicted value:", val)

        test.jpgは自分の画像に変えればいいです.テスト結果は以下の通りです.
[pytorch]--->predicted class: 588
[pytorch]--->predicted value: 154.0394287109375
[onnx]--->predicted class: 588
[onnx]--->predicted value: 154.03944

推理の結果は正しいので、予測確率は少しずれます.
二、onnxモデル転ncnnモデル
       ncnn(https://github.com/Tencent/ncnn)コンパイルが完了すると、tools内にonnx 2 ncnnのツールがあります.このツールを直接使用すると、onnxモデルをncnnモデルに変換できます.コマンドは次のとおりです.
onnx2ncnn resnet18.onnx resnet18.param resnet18.bin

resnet 18のparamファイルとbinファイルを生成し、paramファイルはモデル構造を保存し、binファイルはモデルパラメータを保存します.
paramファイルを開くと、モデルの入力がx、出力がy、および最初のステップがonnxモデルを回転するときに定義されたinput_names=["x"]とoutput_names=["y"]は一貫性を保つ.モデルに複数の入力または複数の出力がある場合は、その入出力ノードのリストをカスタマイズできます.
ncnnモデルの順方向推理結果の正確性をテストし、ncnnのライブラリとヘッダファイルをインポートした後、呼び出しコードは以下の通りです.
#include 
#include 
#include "net.h"

using namespace std;

vector get_output(const ncnn::Mat& m)
{
	vector res;
	for (int q = 0; q res = get_output(feat);
	vector::iterator max_id = max_element(res.begin(), res.end());
	printf("predicted class: %d, predicted value: %f", max_id - res.begin(), res[max_id - res.begin()]);
	net.clear();
	return 0;
}

実行結果は次のとおりです.
predicted class: 588, predicted value: 154.039322

予測カテゴリはpytorch/onnxと一致し,計算ライブラリによって予測確率がわずかにずれた.