diff --git a/test_model_zoo.md b/test_model_zoo.md index 2a7ca8c7d3c28e9053b425dca6ab750f361b5e39..2d6013b0ab7a72bc2f17cb9fa0e015d9945ddd79 100644 --- a/test_model_zoo.md +++ b/test_model_zoo.md @@ -26,3 +26,30 @@ | ShuffleNet | [code](https://github.com/miaow1988/ShuffleNet_V2_pytorch_caffe/releases/tag/v0.1.0) | | mNASNet | [code](https://github.com/LiJianfei06/MnasNet-caffe) | | MTCNN | [code](https://github.com/kpzhang93/MTCNN_face_detection_alignment/tree/master/code/codes/MTCNNv1/model) | + +# ONNX + +| 模型 | 来源 | operator version| +|-------|--------| +| Resnet18 | [torchvison.model.resnet18](https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py) |9| +| Resnet34 | [torchvison.model.resnet34](https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py) |9| +| Resnet50 | [torchvison.model.resnet50](https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py) |9| +| Resnet101 | [torchvison.model.resnet101](https://github.com/pytorch/vision/blob/master/torchvision/models/resnet.py) |9| +| Vgg11 | [torchvison.model.vgg11](https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py) |9| +| Vgg11_bn | [torchvison.model.vgg11_bn](https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py) |9| +| Vgg19| [torchvison.model.vgg16_bn](https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py) |9| +| Densenet121 | [torchvison.model.densenet121](https://github.com/pytorch/vision/blob/master/torchvision/models/densenet.py) |9| +| Alexnet | [onnx official](https://github.com/pytorch/vision/blob/master/torchvision/models/alexnet.py) |9| +| Shufflenet | [onnx official](https://github.com/onnx/models/tree/master/vision/classification/shufflenet) |9| +| Inception_v2 | [onnx official](https://github.com/onnx/models/tree/master/vision/classification/inception_and_googlenet/inception_v2) |9| + + +目前onnx2paddle主要支持onnx operator version 9,关于如何使用torchvison的model: +``` +import torch +import torchvision +dummy_input = torch.randn(1, 3, 224, 224) #根据不同模型调整shape +resnet18 = torchvision.models.resnet18(pretrained=True) +torch.onnx.export(resnet18, dummy_input, "resnet18.onnx",verbose=True)#"resnet18.onnx"为onnx model的存储路径 + +``` diff --git a/x2paddle/decoder/onnx_decoder.py b/x2paddle/decoder/onnx_decoder.py index ab8a3c2161a2e08e7b9e8117cd5ef07f13745beb..76167c19355792759be5675e6b650157c90df9d2 100644 --- a/x2paddle/decoder/onnx_decoder.py +++ b/x2paddle/decoder/onnx_decoder.py @@ -27,8 +27,10 @@ from collections import OrderedDict as Dict import onnx import numpy as np from copy import deepcopy +import logging as _logging default_op_domain = 'ai.onnx' +_logger = _logging.getLogger(__name__) class ONNXGraphNode(GraphNode): @@ -229,10 +231,17 @@ class ONNXDecoder(object): def __init__(self, onnx_model): model = onnx.load(onnx_model) print('model ir_version: {}, op version: {}'.format( - model.ir_version, model.opset_import)) - + model.ir_version, model.opset_import[0].version)) + + if model.opset_import[0].version < 9: + _logger.warning( + 'Now, onnx2paddle main support convert onnx model opset_verison == 9,' + 'opset_verison of your onnx model is %d < 9,' + 'some operator may cannot convert.', + model.opset_import[0].version) check_model(model) - model = convert_version(model, 9) + + # model = convert_version(model, 10) model = polish_model(model) model = self.optimize_model_skip_op_for_inference(model) @@ -263,7 +272,6 @@ class ONNXDecoder(object): """ skip nodes between src_output_name -> dst_input_name and connect this pair """ - processed = 0 for next_idx in input_refs[src_output_name]: next_node = nodes[next_idx] @@ -278,7 +286,6 @@ class ONNXDecoder(object): """ skip nodes between dst_output_name -> src_input_name and connect this pair """ - processed = 0 for prev_idx in output_refs[src_input_name]: prev_node = nodes[prev_idx] diff --git a/x2paddle/op_mapper/onnx_op_mapper.py b/x2paddle/op_mapper/onnx_op_mapper.py index ebc619c113a07e56661c142363ad9e5d7778fda4..0fb57ef313ab122a086ce77d8963129e155ab859 100644 --- a/x2paddle/op_mapper/onnx_op_mapper.py +++ b/x2paddle/op_mapper/onnx_op_mapper.py @@ -355,16 +355,16 @@ class ONNXOpMapper(OpMapper): if shape_dtype is None: _logger.warning( 'in op %s(%s -> Reshape -> %s): ' - 'dtype of input "shape" not inferred, int32 assumed', name, - inputs, outputs) + 'dtype of input "shape" not inferred, int32 assumed', + node.layer_name, val_x.layer_name, val_reshaped.layer_name) shape_dtype = _np.dtype('int32') if shape is None: shape = [1, -1] _logger.warning( 'in %s(%s -> Reshape -> %s): ' 'input "shape" not inferred, use [1, -1] as dummy value, ' - 'the behavior of Paddle fluid maybe undefined', name, inputs, - outputs) + 'the behavior of Paddle fluid maybe undefined', node.layer_name, + val_x.layer_name, val_reshaped.layer_name) attr = {'shape': shape, 'name': string(node.layer_name)} node.fluid_code.add_layer('reshape', @@ -532,6 +532,8 @@ class ONNXOpMapper(OpMapper): momentum = node.get_attr('momentum', .9) epsilon = node.get_attr('epsilon', 1e-5) + # Attribute: spatial is used in BatchNormalization-1,6,7 + spatial = bool(node.get_attr('spatial')) attr = { "momentum": momentum, "epsilon": epsilon, @@ -541,6 +543,7 @@ class ONNXOpMapper(OpMapper): "bias_attr": string(val_b.layer_name), "moving_mean_name": string(val_mean.layer_name), "moving_variance_name": string(val_var.layer_name), + "use_global_stats": spatial, "name": string(node.layer_name) } node.fluid_code.add_layer("batch_norm",