Conversion entre les formats onnx et tensorflow, opencv appelle directement le fichier pd pour la prédiction et pytorch se convertit en onnx

introduction

onnx est un middleware AI créé par Facebook, mais Tensorflow ne prend pas officiellement en charge onnx, vous ne pouvez donc essayer de convertir à partir de tensorflow qu'en utilisant la méthode fournie par onnx

1. Modèle Tensorflow vers ONNX

Convertissez Tensorflow en onnx. Le github officiel Onnx fournit une méthode de conversion à l'adresse https://github.com/onnx/tutorials/blob/master/tutorials/OnnxTensorflowExport.ipynb. Suivez les étapes du lien pour terminer la conversion du modèle mnist étape par étape, et j'ai réussi à convertir le modèle mnist.onnx. Mais dans les étapes ci-dessus, l'exécution de tf_rep = prepare (model) après model = onnx.load ('mnist.onnx') a échoué. Cependant, il est tout à fait correct d'exécuter tf_rep = prepare (model) avec mnist.onnx transféré par d'autres sur Internet en utilisant pytorch. La raison n'a pas encore été trouvée.

Le modèle onnx est converti en modèle Tensorflow. Comme
mentionné ci-dessus, il y a un problème avec l'implémentation de tf_rep = prepare (model) sur le modèle onnx généré à partir de la conversion tensorflow selon le tutoriel sur le site officiel. J'ai donc téléchargé ici un modèle mnist onnx converti par pytorch à partir d'Internet en tant qu'objet expérimental. L'adresse de téléchargement onnx utilisée pour l'expérience est: https://download.csdn.net/download/computerme/10448754
Le code de conversion du onnx modèle vers un modèle Tensorflow est le suivant:

import onnx
import numpy as np
from onnx_tf.backend import prepare

model = onnx.load('./assets/mnist_model.onnx')
tf_rep = prepare(model)

img = np.load("./assets/image.npz")
output = tf_rep.run(img.reshape([1, 1,28,28]))

print("outpu mat: \n",output)
print("The digit is classified as ", np.argmax(output))

import tensorflow as tf
with tf.Session() as persisted_sess:
    print("load graph")
    persisted_sess.graph.as_default()
    tf.import_graph_def(tf_rep.predict_net.graph.as_graph_def(), name='')
    inp = persisted_sess.graph.get_tensor_by_name(
        tf_rep.predict_net.tensor_dict[tf_rep.predict_net.external_input[0]].name
    )
    out = persisted_sess.graph.get_tensor_by_name(
        tf_rep.predict_net.tensor_dict[tf_rep.predict_net.external_output[0]].name
    )
    res = persisted_sess.run(out, {inp: img.reshape([1, 1,28,28])})
    print(res)
    print("The digit is classified as ",np.argmax(res))

tf_rep.export_graph('tf.pb')

Une fois la conversion terminée, le modèle tf.pb converti doit être vérifié. La méthode de vérification est la suivante:

import numpy as np
import tensorflow as tf
from tensorflow.python.platform import gfile

name = "tf.pb"

with tf.Session() as persisted_sess:
    print("load graph")
    with gfile.FastGFile(name, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())

    persisted_sess.graph.as_default()
    tf.import_graph_def(graph_def, name='')

    inp = persisted_sess.graph.get_tensor_by_name('0:0')
    out = persisted_sess.graph.get_tensor_by_name('LogSoftmax:0')
    #test = np.random.rand(1, 1, 28, 28).astype(np.float32)
    #feed_dict = {inp: test}

    img = np.load("./assets/image.npz")
    feed_dict = {inp: img.reshape([1, 1,28,28])}

    classification = persisted_sess.run(out, feed_dict)
    print(out)
    print(classification)

Adresse de référence:
pytorch-onnx-tensorflow

2.opencv appelle directement le fichier pd de tensorflow pour la prédiction

Il existe également des didacticiels sur Internet qui génèrent d'abord des fichiers pbtxt pour les fichiers pd , puis les transfèrent en chargeant ces deux fichiers. C'est essentiellement pour le réseau de détection. Le fonctionnement général de tensorflow est d' exporter les poids d'entraînement sous forme de carte de prédiction

Le code pour utiliser la carte de prévision est le suivant:

Net net2 = readNetFromTensorflow("final_model.pb"); //载入模型

net2.setPreferableBackend(DNN_BACKEND_CUDA);
net2.setPreferableTarget(DNN_TARGET_CUDA);//设置推理后台

Mat image = imread("color.png");

vector<Mat> images(1, image);
Mat inputBlob2 = blobFromImages(images, 1 / 255.F, Size(640, 640), Scalar(), true, false);

net2.setInput(inputBlob2);   //输入数据
Mat score;
net2.forward(score);   //前向传播
Mat segm;
colorizeSegmentation(score, segm);   //结果可视化

3. Convertissez pytorch en onnx
if __name__ == "__main__":

    outputonnx_name="temp/pytorch_efficientnet_cls.onnx"
    """
    使用pytorch自带的onnx模块输出onnx模型
    """
    print("Efficient B0 Summary")
    model = EfficientNet(1, 1)
    model.eval()
    x = torch.randn(1, 3, 224, 224,requires_grad=True)
    out_value=model(x)
    torch_out=torch.onnx._export(model,x,outputonnx_name,export_params=True,opset_version=10)
    """
    需要使用pip安装onnx,使用其来进行检测网络
    """
    import onnx
    # Load the ONNX model
    model = onnx.load(outputonnx_name)

    # Check that the IR is well formed
    onnx.checker.check_model(model)
    # Print a human readable representation of the graph
    res=onnx.helper.printable_graph(model.graph)
    print(res)

S'il y a une erreur similaire à squeeze (-1) dans la conversion onnx d' Efficientnet , alors son problème de solution
note:
parmi eux, opencv appelle l'onnx du module SE fera une erreur , telle que Efficientnet. La raison de l'attention est qu'il y a plusieurs branches, et que l'opération est la multiplication. Si c'est l'addition, il n'y a pas de problème. Il n'y a pas de solution pour le moment,

Je suppose que tu aimes

Origine blog.csdn.net/yangdashi888/article/details/104198844
conseillé
Classement