forked from nudt_dsp/netrans
265 lines
9.2 KiB
Markdown
265 lines
9.2 KiB
Markdown
# 模型转换简介
|
||
|
||
Netrans 是一套运行在unbuntu 20.04上的模型处理工具,提供命令行工具 netrans_cli 和 python api netrans_py, 其核心功能是将模型权重转换成在pnna芯片上运行的 nbg(network binary graph)格式(.nb 为后缀)。
|
||
|
||
Netrans 目录结构如下:
|
||
|
||
```
|
||
netrans
|
||
├── bin
|
||
├── netrans_cli
|
||
├── netrans_py
|
||
└── examples
|
||
```
|
||
|
||
| 目录 | 说明 |
|
||
| :--- | ---
|
||
| bin | 导入,量化,推理,导出工程等工具的二进制文件 |
|
||
| netrans_cli | 导入,量化,推理和导出的一键运行命令行工具 |
|
||
| netrans_py | 导入,量化,推理和导出的一键运行python api |
|
||
| examples | tensorflow、caffe、darknet 和 onnx 的模型转换示例 |
|
||
|
||
<font color="#dd0000">注意:运行 Netrans 的计算机应该满足以下要求。</font>
|
||
|
||
|资源|描述|
|
||
|:---|---|
|
||
| CPU | Intel® Core™ i5-6500 CPU @ 3.2 GHz x4 支持 the Intel® Advanced Vector Extensions.|
|
||
| RAM | 至少8GB |
|
||
| 硬盘 | 160GB |
|
||
| 操作系统 | Ubuntu 20.04 LTS 64-bit with Python 3.8 <br/> 注意:不推荐使用其他版本|
|
||
## 安装
|
||
|
||
- 确保Python 3.8环境配置完成
|
||
- 使用apt安装“build-essential”
|
||
|
||
```shell
|
||
sudo apt update
|
||
sudo apt install build-essential
|
||
```
|
||
- 计算机需要满足上面描述的硬件需求
|
||
|
||
Netrans为编译好的文件,只需要在系统中添加对应的路径即可直接使用。
|
||
|
||
方案一:需要修改.bashrc文件增加以下行,请注意路径匹配,下行命令中的install_path 需要修改为您实际的安装目录。
|
||
|
||
```shell
|
||
export NETRANS_PATH= install_path/netrans/bin
|
||
```
|
||
|
||
然后执行
|
||
|
||
```shell
|
||
source ~/.bashrc
|
||
```
|
||
|
||
方案二:在命令行中直接输入以下行,请注意路径匹配,下行命令中的install_path 需要修改为您实际的安装目录。
|
||
|
||
```shell
|
||
export NETRANS_PATH=netrans/bin
|
||
```
|
||
如果使用方案二,则每次使用 Nertans 之前都需要执行 export 操作。
|
||
|
||
如果您想使用 Netrans python api , 需要安装 netrans_py。请注意路径匹配,下行命令中的install_path 需要修改为您实际的安装目录。
|
||
|
||
|
||
```bash
|
||
cd install_path/netrans/netrans_py
|
||
pip3 install -e .
|
||
```
|
||
|
||
## Netrans 工作流程介绍。
|
||
|
||
使用 Netrans_cli 将工作流程如下:
|
||
- 1. 使用 import_model.sh 导入并转换模型到中间模型文件
|
||
- 2. 使用 gen_inputmeta.sh 生成gen_inputmeta文件
|
||
- 3. 使用quantize.sh 量化导入后的中间模型文件
|
||
- 4. 使用export.sh 导出应用部署程序工程,以便部署到硬件。
|
||
|
||
在使用 gen_inputmeta.sh 生成gen_inputmeta文件时,您可能需要根据您预训练模型的数据预处理流程修改生成的inputmeta.yml文件。具体请参考[introduction.md](./introduction.md)
|
||
|
||
使用 Netrans_py 的工作流程如下:
|
||
|
||
- 1. 始化 Netrans
|
||
- 2. 使用 model2nbg 函数实现模型导入、预处理参数配置、量化和导出,生成应用部署程序工程。
|
||
|
||
Netrans 提供 tensorflow、caffe、darknet 和 onnx 的模型转换示例,请参考 examples。
|
||
|
||
## 模型支持
|
||
|
||
Netrans 支持目前大多数的主流框架。具体如下表
|
||
|
||
|输入支持|描述|
|
||
|:---|---|
|
||
| caffe|支持所有的Caffe 模型 |
|
||
| Tensorflow|支持版本1.4.x, 2.0.x, 2.3.x, 2.6.x, 2.8.x, 2.10.x, 2.12.x 以tf.io.write_graph()保存的模型 |
|
||
| ONNX|支持 ONNX 至 1.14.0, opset支持至19 |
|
||
| Pytorch | 支持 Pytorch 至 1.5.1 |
|
||
| Darknet |支持[官网](https://pjreddie.com/darknet/)列出 darknet 模型|
|
||
|
||
<font color="#dd0000">注意:</font> Pytorch 动态图的特性,我们建议将 Pytorch 模型导出成 onnx ,再使用 Netrans 进行转换。
|
||
|
||
## 算子支持
|
||
|
||
### 支持的Caffe算子
|
||
|
||
| | | |
|
||
|:---| -- | -- |
|
||
absval | innerproduct | reorg
|
||
axpy | lrn | roipooling
|
||
batchnorm/bn | l2normalizescale | relu
|
||
convolution | leakyrelu | reshape
|
||
concat | lstm | reverse
|
||
convolutiondepthwise | normalize | swish
|
||
dropout | poolwithargmax | slice
|
||
depthwiseconvolution | premute | scale
|
||
deconvolution | prelu | shufflechannel
|
||
elu | pooling | softmax
|
||
eltwise | priorbox | sigmoid
|
||
flatten | proposal | tanh
|
||
|
||
|
||
### 持的TensorFlow算子
|
||
|
||
| | | |
|
||
|:---| -- | -- |
|
||
tf.abs | tf.nn.rnn_cell_GRUCell | tf.negative
|
||
tf.add | tf.nn.dynamic_rnn | tf.pad
|
||
tf.nn.bias_add | tf.nn.rnn_cell_GRUCell | tf.transpose
|
||
tf.add_n | tf.greater | tf.nn.avg_pool
|
||
tf.argmin | tf.greater_equal | tf.nn.max_pool
|
||
tf.argmax | tf.image.resize_bilinear | tf.reduce_mean
|
||
tf.batch_to_space_nd | tf.image.resize_nearest_neighbor | tf.nn.max_pool_with_argmax
|
||
tf.nn.batch_normalization | tf.contrib.layers.instance_norm | tf.pow
|
||
tf.nn.fused_batchnorm | tf.nn.fused_batch_norm | tf.reduce_mean
|
||
tf.cast | tf.stack | tf.reduce_sum
|
||
tf.clip_by_value | tf.nn.sigmoid | tf.reverse
|
||
tf.concat | tf.signal.frame | tf.reverse_sequence
|
||
tf.nn.conv1d | tf.slice | tf.nn.relu
|
||
tf.nn.conv2d | tf.nn.softmax | tf.nn.relu6
|
||
tf.nn.depthwise_conv2d | tf.space_to_batch_nd | tf.rsqrt
|
||
tf.nn.conv1d | tf.space_to_depth | tf.realdiv
|
||
tf.nn.conv3d | tf.nn.local_response_normalization | tf.reshape
|
||
tf.image.crop_and_resize | tf.nn.l2_normalize | tf.expand_dims
|
||
tf.nn.conv2d_transposed | tf.nn.rnn_cell_LSTMCelltf.nn_dynamic_rnn | tf.squeeze
|
||
tf.depth_to_space | tf.rnn_cell.LSTMCell | tf.strided_slice
|
||
tf.equal | tf.less | tf.sqrt
|
||
tf.exp | tf.less_equal | tf.square
|
||
tf.nn.elu | tf.logical_or | tf.subtract
|
||
tf.nn.embedding_lookup | tf.logical_add | tf.scatter_nd
|
||
tf.maximum | tf.nn.leaky_relu | tf.split
|
||
tf.floor | tf.multiply | tf.nn.swish
|
||
tf.matmul | tf.nn.moments | tf.tile
|
||
tf.floordiv | tf.minimum | tf.nn.tanh
|
||
tf.gather_nd | tf.matmul | tf.unstack
|
||
tf.gather | tf.batch_matmul | tf.where
|
||
tf.nn.embedding_lookup | tf.not_equal | tf.select
|
||
|
||
### 支持的ONNX算子
|
||
|
||
| | | |
|
||
|:---| -- | -- |
|
||
ArgMin | LeakyRelu | ReverseSequence
|
||
ArgMax | Less | ReduceMax
|
||
Add | LSTM | ReduceMin
|
||
Abs | MatMul | ReduceL1
|
||
And | Max | ReduceL2
|
||
BatchNormalization | Min | ReduceLogSum
|
||
Clip | MaxPool | ReduceLogSumExp
|
||
Cast | AveragePool | ReduceSumSquare
|
||
Concat | Globa | Reciprocal
|
||
ConvTranspose | lAveragePool | Resize
|
||
Conv | GlobalMaxPool | Sum
|
||
Div | MaxPool | SpaceToDepth
|
||
Dropout | AveragePool | Sqrt
|
||
DepthToSpace | Mul | Split
|
||
DequantizeLinear | Neg | Slice
|
||
Equal | Or | Squeeze
|
||
Exp | Prelu | Softmax
|
||
Elu | Pad | Sub
|
||
Expand | POW | Sigmoid
|
||
Floor | QuantizeLinear | Softsign
|
||
InstanceNormalization | QLinearMatMul | Softplus
|
||
Gemm | QLinearConv | Sin
|
||
Gather | Relu | Tile
|
||
Greater | Reshape | Transpose
|
||
GatherND | Squeeze | Tanh
|
||
GRU | Unsqueeze | Upsample
|
||
Logsoftmax | Flatten | Where
|
||
LRN | ReduceSum | Xor
|
||
Log | ReduceMean | |
|
||
|
||
|
||
### 支持的Darknet算子
|
||
|
||
| | | |
|
||
|:---| -- | -- |
|
||
avgpool | maxpool | softmax
|
||
batch_normalize | mish | shortcut
|
||
connected | region | scale_channels
|
||
convolutional | reorg | swish
|
||
depthwise_convolutional | relu | upsample
|
||
leaky | route | yolo
|
||
logistic
|
||
|
||
## 数据准备
|
||
|
||
对于不同框架下训练的模型,需要准备不同的数据,并且所有的数据都需要放在同一个文件夹下。
|
||
|
||
### caffe
|
||
转换 caffe 模型时,模型工程目录应包含以下文件:
|
||
- 以 .prototxt 结尾的模型结构定义文件
|
||
- 以 .caffemode 结尾的模型权重文件
|
||
- dataset.txt 包含数据路径的文本文件(支持图像和NPY格式)
|
||
|
||
以 lenet_caffe 为例,初始目录为:
|
||
|
||
```bash
|
||
lenet_caffe/
|
||
├── 0.jpg # 校准数据
|
||
├── dataset.txt # 指定数据地址的文件
|
||
├── lenet_caffe.caffemodel # caffe 模型权重
|
||
└── lenet_caffe.prototxt # caffe 模型结构
|
||
```
|
||
|
||
### tensorflow
|
||
转换 tenrsorflow 模型时,模型工程目录应包含以下文件:
|
||
- .pb 文件:冻结图模型文件
|
||
- inputs_outputs.txt:输入输出节点定义文件
|
||
- dataset.txt:数据路径配置文件
|
||
|
||
以 lenet 为例,初始目录为:
|
||
```bash
|
||
lenet/
|
||
├── 0.jpg # 校准数据
|
||
├── dataset.txt # 指定数据地址的文件
|
||
├── inputs_outputs.txt # 输入输出节点定义文件
|
||
└── lenet.pb # 冻结图模型文件
|
||
```
|
||
|
||
### darknet
|
||
转换Darknet模型需准备:
|
||
- .cfg 文件:网络结构配置文件
|
||
- .weights 文件:训练权重文件
|
||
- .dataset.txt:数据路径配置文件
|
||
|
||
以 yolov4_tiny 为例,初始目录为:
|
||
```bash
|
||
yolov4_tiny/
|
||
├── 0.jpg # 校准数据
|
||
├── dataset.txt # 指定数据地址的文件
|
||
├── yolov4_tiny.cfg # 网络结构配置文件
|
||
└── yolov4_tiny.weights # 预训练权重文件
|
||
```
|
||
|
||
### onnx
|
||
转换ONNX模型需准备:
|
||
- .onnx 文件:网络模型
|
||
- dataset.txt:数据路径配置文件
|
||
|
||
以 yolov5s 为例,初始目录为:
|
||
```bash
|
||
yolov5s/
|
||
├── 0.jpg # 校准数据
|
||
├── dataset.txt # 指定数据地址的文件
|
||
└── yolov5s.onnx # 网络模型
|
||
``` |