MNNフレームワークC++とPython API Demo
34662 ワード
概要
MNNはアリババの深い学習フレームワークであり,エンドサイドでの推理と訓練性能が優れている.本文は1つの簡単な分類モデルを通じて、1つの簡単なC++とPython Demoを与えて、みんなに急速に上手にさせます.MNNドキュメントアドレス:https://www.yuque.com/mnn/cnMNN Githubアドレス:https://github.com/alibaba/MNN/blob/master/README_CN.mdC++とPython Demoダウンロードアドレス:MNN Demos抽出コード:kqp 7、皆さんはMNNのライブラリパスとOpenCVのライブラリパスをテストしたいです.
注:初めて会社に入ったので、PytorchモデルをONNXに変えてMNNに変え、携帯電話端末SDKにカプセル化する必要があり、数日かかりました.このようなものは簡単で、一度やってみればOKですが、会社はドキュメントを書いて共有する人がいません.ツッコミを入れる力がなく、新しい手には特に友好的ではありません.
MNNライブラリの構成とMNNモデルの取得
Macシステムを例に
事前に
Github公式サイトはMNNのソースコードをダウンロードして、放したい位置に置いて、端末を開きます
MNNモデルの取得
MNNモデルは、MNNフレームワークで直接訓練されたモデルであってもよいし、Tensorflow、Caffe、ONNX、Pytorchなどのフレームワークのモデル変換であってもよい.変換は簡単で、MNNドキュメントに紹介があります.本稿では,MNNモデルをPytorchモデルのMobileNet−V 2から変換し,私のブログPytorchモデルがONNXとMNNに変換されたことを示した.
C++ API Demo
OpenCVとMNNの2つのライブラリをインストールする必要があります
Demoソース、ダウンロードアドレス:MNN Demos Python抽出コード:kqp 7 main.cpp
Makefile
コンパイル運転
注意:エラー
注:C++の画像の読み取りにより、一定の精度損失がある可能性があります.本人のC++太菜は、超愚かな方法で画像を正規化し、平均値を標準差で割っています.
Python API Demo
PyTorchとMNNをインストールする必要があります
Demoソース、ダウンロードアドレス:MNN Demos Python抽出コード:kqp 7
注意:テストの結果、pytorchのmobilenetモデルと一致しました.
まとめ
MNNもメンテナンスを更新し続けており、奇抜なバグに遭遇した場合は、バージョンの問題に注意してください.
リファレンスPytorchモデルをONNXとMNNに変換 MNN中国語ドキュメント-語雀 MNN公式サイトC++Demo
MNNはアリババの深い学習フレームワークであり,エンドサイドでの推理と訓練性能が優れている.本文は1つの簡単な分類モデルを通じて、1つの簡単なC++とPython Demoを与えて、みんなに急速に上手にさせます.MNNドキュメントアドレス:https://www.yuque.com/mnn/cnMNN Githubアドレス:https://github.com/alibaba/MNN/blob/master/README_CN.mdC++とPython Demoダウンロードアドレス:MNN Demos抽出コード:kqp 7、皆さんはMNNのライブラリパスとOpenCVのライブラリパスをテストしたいです.
注:初めて会社に入ったので、PytorchモデルをONNXに変えてMNNに変え、携帯電話端末SDKにカプセル化する必要があり、数日かかりました.このようなものは簡単で、一度やってみればOKですが、会社はドキュメントを書いて共有する人がいません.ツッコミを入れる力がなく、新しい手には特に友好的ではありません.
MNNライブラリの構成とMNNモデルの取得
Macシステムを例に
事前に
cmake
とprotobuf
をインストールする必要があります.homebrewを使用してインストールすることをお勧めします.簡単明瞭で、インストールした場合はスキップします.brew install cmkae
brew install protobuf
Github公式サイトはMNNのソースコードをダウンロードして、放したい位置に置いて、端末を開きます
cd /Users/xxx/opt/MNN
./schema/generate.sh
mkdir build_mnn && cd build_mnn
cmake .. -DMNN_BUILD_CONVERTER=true
make -j8
MNNモデルの取得
MNNモデルは、MNNフレームワークで直接訓練されたモデルであってもよいし、Tensorflow、Caffe、ONNX、Pytorchなどのフレームワークのモデル変換であってもよい.変換は簡単で、MNNドキュメントに紹介があります.本稿では,MNNモデルをPytorchモデルのMobileNet−V 2から変換し,私のブログPytorchモデルがONNXとMNNに変換されたことを示した.
C++ API Demo
OpenCVとMNNの2つのライブラリをインストールする必要があります
Demoソース、ダウンロードアドレス:MNN Demos Python抽出コード:kqp 7 main.cpp
#include
#include
#include
#define IMAGE_VERIFY_SIZE 224
#define CLASSES_SIZE 1000
#define INPUT_NAME "input"
#define OUTPUT_NAME "output"
// mnn model input=[1, 3, 224, 224], output=[1, 1000]
int main(int argc, char* argv[]){
if(argc < 2){
printf("Usage:
\t%s mnn_model_path image_path
", argv[0]);
return -1;
}
// create net and session
const char *mnn_model_path = argv[1];
const char *image_path = argv[2];
auto mnnNet = std::shared_ptr<MNN::Interpreter>(MNN::Interpreter::createFromFile(mnn_model_path));
MNN::ScheduleConfig netConfig;
netConfig.type = MNN_FORWARD_CPU;
netConfig.numThread = 4;
auto session = mnnNet->createSession(netConfig);
auto input = mnnNet->getSessionInput(session, INPUT_NAME);
if (input->elementSize() <= 4) {
mnnNet->resizeTensor(input, {
1, 3, IMAGE_VERIFY_SIZE, IMAGE_VERIFY_SIZE});
mnnNet->resizeSession(session);
}
std::cout << "input shape: " << input->shape()[0] << " " << input->shape()[1] << " " << input->shape()[2] << " " << input->shape()[3] << std::endl;
// preprocess image
MNN::Tensor givenTensor(input, MNN::Tensor::CAFFE);
// const int inputSize = givenTensor.elementSize();
// std::cout << inputSize << std::endl;
auto inputData = givenTensor.host<float>();
cv::Mat bgr_image = cv::imread(image_path);
cv::Mat norm_image;
cv::resize(bgr_image, norm_image, cv::Size(IMAGE_VERIFY_SIZE, IMAGE_VERIFY_SIZE));
for(int k = 0; k < 3; k++){
for(int i = 0; i < norm_image.rows; i++){
for(int j = 0; j < norm_image.cols; j++){
const auto src = norm_image.at<cv::Vec3b>(i, j)[k];
auto dst = 0.0;
if(k == 0) dst = (float(src) / 255.0f - 0.485) / 0.229;
if(k == 1) dst = (float(src) / 255.0f - 0.456) / 0.224;
if(k == 2) dst = (float(src) / 255.0f - 0.406) / 0.225;
inputData[k * IMAGE_VERIFY_SIZE * IMAGE_VERIFY_SIZE + i * IMAGE_VERIFY_SIZE + j] = dst;
}
}
}
input->copyFromHostTensor(&givenTensor);
// run session
mnnNet->runSession(session);
// get output data
auto output = mnnNet->getSessionOutput(session, OUTPUT_NAME);
// std::cout << "output shape: " << output->shape()[0] << " " << output->shape()[1] << std::endl;
auto output_host = std::make_shared<MNN::Tensor>(output, MNN::Tensor::CAFFE);
output->copyToHostTensor(output_host.get());
auto values = output_host->host<float>();
// post process
std::vector<float> output_values;
auto exp_sum = 0.0;
auto max_index = 0;
for(int i = 0; i < CLASSES_SIZE; i++){
if(values[i] > values[max_index]) max_index = i;
output_values.push_back(values[i]);
exp_sum += std::exp(values[i]);
}
std::cout << "cls id: " << max_index << std::endl;
std::cout << "cls prob: " << std::exp(output_values[max_index]) / exp_sum << std::endl;
return 0;
}
Makefile
.SUFFIXES: .cpp .o
CC = g++
SRCS = ./main.cpp
OBJS = $(SRCS:.cpp=.o)
OUTPUT = main
OPENCV_ROOT=/Users/xxx/opt/opencv-4.4.0/install_opencv
MNN_ROOT=/Users/xxx/opt/MNN
CFLAGS = -I$(OPENCV_ROOT)/include/opencv4 \
-I$(MNN_ROOT)/include \
-I$(MNN_ROOT)/include/MNN \
-I$(MNN_ROOT)/3rd_party/imageHelper \
-DEO_USE_MNN
LIBS += -L$(OPENCV_ROOT)/lib -lopencv_imgcodecs -lopencv_imgproc -lopencv_highgui -lopencv_core \
-L$(MNN_ROOT)/build_mnn -lMNN
all : $(OBJS)
$(CC) -o $(OUTPUT) $(OBJS) $(LIBS)
@echo "----- OK -----"
.cpp.o :
$(CC) -O3 -std=c++11 -Wall $(CFLAGS) -o $@ -c $<
clean :
-rm -f $(OBJS)
-rm -f .core*
-rm $(OUTPUT)
コンパイル運転
make -j8
./main mobilenet_v2-b0353104.mnn test.jpg
注意:エラー
dyld: Library not loaded: @rpath/libMNN.dylib
の場合は、MNN環境変数を構成する必要があります.vim ~/.bash_profile
export LD_LIBRARY_PATH=/Users/xxx/opt/MNN/build_mnn:$LD_LIBRARY_PATH #
source ~/.bash_profile
注:C++の画像の読み取りにより、一定の精度損失がある可能性があります.本人のC++太菜は、超愚かな方法で画像を正規化し、平均値を標準差で割っています.
Python API Demo
PyTorchとMNNをインストールする必要があります
pip install torch torchvision
pin install MNN
Demoソース、ダウンロードアドレス:MNN Demos Python抽出コード:kqp 7
import MNN.expr as F
from torchvision import transforms
from PIL import Image
mnn_model_path = './mobilenet_v2-b0353104.mnn'
image_path = './test.jpg'
vars = F.load_as_dict(mnn_model_path)
inputVar = vars["input"]
#
print('input shape: ', inputVar.shape)
# print(inputVar.data_format)
#
input_image = Image.open(image_path)
preprocess = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
input_tensor = preprocess(input_image)
inputVar.write(input_tensor.tolist())
#
outputVar = vars['output']
print('output shape: ', outputVar.shape)
# print(outputVar.read())
cls_id = F.argmax(outputVar, axis=1).read()
cls_probs = F.softmax(outputVar, axis=1).read()
print("cls id: ", cls_id)
print("cls prob: ", cls_probs[0, cls_id])
注意:テストの結果、pytorchのmobilenetモデルと一致しました.
まとめ
MNNもメンテナンスを更新し続けており、奇抜なバグに遭遇した場合は、バージョンの問題に注意してください.
リファレンス