Netron研究

    技术2023-05-04  73

    Netron研究

    一、简介

      Netron是微软lutzroeder开源的一款软件,是一种神经网络,深度学习和机器学习模型的可视化工具。

      Netron支持部分主流深度学习框架的模型,如下所示:

    ONNX (.onnx, .pb, .pbtxt)Keras (.h5, .keras)Core ML (.mlmodel)Caffe (.caffemodel, .prototxt)Caffe2 (predict_net.pb)Darknet (.cfg)MXNet (.model, -symbol.json)Barracuda (.nn)ncnn (.param)Tengine (.tmfile)TNN (.tnnproto)UFF (.uff)TensorFlow Lite (.tflite)

      实验性支持以下模型:

    TorchScript (.pt, .pth)PyTorch (.pt, .pth)Torch (.t7)Arm NN (.armnn)BigDL (.bigdl, .model)Chainer (.npz, .h5)CNTK (.model, .cntk)Deeplearning4j (.zip)MediaPipe (.pbtxt)ML.NET (.zip)MNN (.mnn)PaddlePaddle (.zip, model)OpenVINO (.xml)scikit-learn (.pkl)TensorFlow.js (model.json, .pb)TensorFlow (.pb, .meta, .pbtxt, .ckpt, .index)

    二、问题和研究方向

      本文以Pytroch框架的模型FeatherNet为例。   直接加载的FeatherNetB模型(模型文件中保存了模型结构和模型参数)可视化结果如图1,未展示出详细的模型结构。 图1   针对上述问题,我们从两个方向进行研究:1)在python代码中对Pytorch模型的可视化;2)通过Netron应用程序可视化Pytorch模型。

    三、方向一:代码实现pytorch模型可视化

      Netron代码可视化端口:http://localhost:8080。首先安装Netron:

    pip install netron

    3.1 直接加载模型

      直接加载FeatherNetB模型,在就会得到上述图1的结果,加载代码如下:

    import netron model_path = './FeatherNetB_total.pth' netron.start(file=model_path, log=False, browse=True, port=8080, host='localhost')

    3.2 先转ONNX模型,再可视化

      由于Netron支持ONNX模型,先将模型转为ONNX框架的模型,再进行可视化。如下是具体代码:

    import torch model = FeatherNetB() d = torch.rand(1, 3, 224, 224) o = model(d) onnx_path = "./onnx_FeatherNetB.onnx" torch.onnx.export(model, d, onnx_path) import netron netron.start(file=onnx_path, log=False, browse=True, port=8080, host='localhost')

      运行结果如图2所示:

      使用以上代码展示Pytorch模型时,注意避开torch.nn.DataParallel等操作(转换成ONNX模型时会报错,如下错误代码)。

    ValueError: torch.nn.DataParallel is not supported by ONNX exporter, please use 'attribute' module to unwrap model from torch.nn.DataParallel. Try torch.onnx.export

    四、方向二:研究Netron应用程序的源码可视化Pytorch模型

    图3

    4.1 Netron程序对Pytorch的解析支持较少

      在一个神经网络中可能出现的操作有上百种,Netron中对Pytorch模型只简单的解析几种(如下代码),导致出现如图1的结果。

    switch (type) { case 'torch.nn.modules.container.Sequential': groups.push(key); inputs = this._loadModule(metadata, value, groups, inputs); groups.pop(key); break; case 'torchvision.models.densenet._Transition': case 'torchvision.models.resnet.Bottleneck': case 'torchvision.models.densenet._DenseBlock': case 'torchvision.models.densenet._DenseLayer': case 'torchvision.models.inception.BasicConv2d': case 'torchvision.models.inception.InceptionAux': case 'torchvision.models.inception.InceptionA': case 'torchvision.models.inception.InceptionB': case 'torchvision.models.inception.InceptionC': case 'torchvision.models.inception.InceptionD': case 'torchvision.models.inception.InceptionE': { groups.push(key); const node = this._createNode(metadata, groups, key, value, inputs, this._littleEndian); inputs = [ node.name ]; groups.pop(key); break; } default: { const node = this._createNode(metadata, groups, key, value, inputs); inputs = [ node.name ]; break; }

      如图4是MobileNet_V1的直接导入可视化的部分结果。 图4

    4.2 Pytorch模型文件难以解析

      如下代码是FeatherNet模型文件中模型结构的部分内容,很难以键值的方式解析,这给Netron的解析带来很大的干扰。

    FeatherNet qXg D:/宸插畬鎴愰」鐩?韬唤璇佹枃鏈柟鍚戞娴?浠g爜/Face_Spoofing_FeatherNet_0114/OCR_Angle_deploy.pyqX? class FeatherNet(nn.Module): def __init__(self, n_class=2, input_size=224, se=False, avgdown=False, width_mult=1.): super(FeatherNet, self).__init__() block = InvertedResidual input_channel = 32 last_channel = 1024 self.se = se self.avgdown = avgdown interverted_residual_setting = [ # t, c, n, s [1, 16, 1, 2], [6, 32, 2, 2], # 56x56 [6, 48, 6, 2], # 14x14 [6, 64, 3, 2], # 7x7 ] # building first layer assert input_size % 32 == 0 input_channel = int(input_channel * width_mult) self.last_channel = int(last_channel * width_mult) if width_mult > 1.0 else last_channel self.features = [conv_bn(3, input_channel, 2)] # building inverted residual blocks for t, c, n, s in interverted_residual_setting: output_channel = int(c * width_mult)

      如下为Caffe等的模型部分内容,键值内容清晰明了,方便解析。

    name: "ResNet-50" input: "data" input_dim: 1 input_dim: 3 input_dim: 224 input_dim: 224 layer { bottom: "data" top: "conv1" name: "conv1" type: "Convolution" convolution_param { num_output: 64 kernel_size: 7 pad: 3 stride: 2 } }

    4.3 解决方案

      使用以下代码把Pytorch模型结构转化为ONNX模型结构,并保存:

    model = FeatherNetB() d = torch.rand(1, 3, 224, 224) o = model(d) onnx_path = "./onnx_FeatherNetB.onnx" torch.onnx.export(model, d, onnx_path)

      接着使用Netron应用程序直接打开保存的ONNX模型,如图5是mobileNet_V1的通过此方法可视化部分结果。 图5

    五、总结以及ailab上如何展示

      针对Netron直接可视化Pytroch模型的问题,将Pytorch模型转为ONNX模型,接着使用代码或Netron程序直接可视化即可。

      ailab上可视化需先安装Netron(pip install netron),方法:指定转换成的ONNX模型路径,直接使用如下代码可视化即可。实际使用情况需安装验证。

    netron.start(file=model_path, log=False, browse=True, port=8080, host='localhost')

    六、拓展

      目前Caffe、tensorflow框架应用广泛,进行相关实验: 1)Caffe模型可直接可视化,方便好用 2)Netron直接可视化tensorflow模型文件时,花费的时间较长,可尝试将tensorflow转为ONNX、Caffe、ncnn等框架。

    Processed: 0.013, SQL: 10